private async Task GetNodeSelfSignedCert()

in src/ccf/ccf-provider/CcfNetworkProvider.cs [1632:1732]


    private async Task<string> GetNodeSelfSignedCert(
        NodeEndpoint nodeEndpoint,
        Func<Task>? onRetry = null)
    {
        var endpoint = nodeEndpoint.ClientRpcAddress;
        var nodeName = nodeEndpoint.NodeName;

        using var client = HttpClientManager.NewInsecureClient(endpoint, this.logger);

        // Use a shorter timeout than the default (100s) so that we retry faster to connect to the
        // endpoint that is warming up.
        client.Timeout = TimeSpan.FromSeconds(30);

        // At times it takes a while for the endpoint to start responding so giving a large timeout.
        TimeSpan readyTimeout = TimeSpan.FromSeconds(300);
        var stopwatch = Stopwatch.StartNew();
        while (true)
        {
            try
            {
                using var response = await client.GetAsync("/node/self_signed_certificate");
                if (response.IsSuccessStatusCode)
                {
                    var nodeCert = (await response.Content.ReadFromJsonAsync<JsonObject>())!;
                    var value = nodeCert["self_signed_certificate"]!.ToString();
                    return value;
                }

                this.logger.LogInformation(
                    $"{nodeName}: Waiting for {endpoint}/node/self_signed_certificate to report " +
                    $"success. Current statusCode: {response.StatusCode}.");
            }
            catch (TaskCanceledException te)
            {
                this.logger.LogError(
                    $"{nodeName}: Hit HttpClient timeout waiting for " +
                    $"{endpoint}/node/self_signed_certificate to " +
                    $"report success. Current error: {te.Message}.");
            }
            catch (HttpRequestException re)
            {
                this.logger.LogInformation(
                    $"{nodeName}: Waiting for {endpoint}/node/self_signed_certificate to report " +
                    $"success. Current statusCode: {re.StatusCode}, error: {re.Message}.");

                await LogNodeState();
            }

            if (stopwatch.Elapsed > readyTimeout)
            {
                throw new TimeoutException(
                    $"{nodeName}: Hit timeout waiting for {endpoint}/node/self_signed_certificate");
            }

            if (onRetry != null)
            {
                await onRetry.Invoke();
            }

            await Task.Delay(TimeSpan.FromSeconds(1));
        }

        async Task LogNodeState()
        {
            try
            {
                // Check the node endorsed endpoint in case that is up and reporting state.
                // This helps debug issues.
                using var debugClient = HttpClientManager.NewInsecureClient(
                    nodeEndpoint.NodeEndorsedRpcAddress,
                    this.logger);
                debugClient.Timeout = TimeSpan.FromSeconds(30);

                var nodeStateResponse = await debugClient.GetAsync("/node/state");
                if (nodeStateResponse.IsSuccessStatusCode)
                {
                    var nodeState =
                        (await nodeStateResponse.Content.ReadFromJsonAsync<JsonObject>())!;
                    this.logger.LogInformation(
                        $"{nodeName}: /node/state endpoint on node endorsed endpoint is " +
                        $"reporting: " +
                        $"{JsonSerializer.Serialize(nodeState)}.");
                }
                else
                {
                    this.logger.LogError(
                        $"{nodeName}: Could not query /node/state on node endorsed endpoint to " +
                        $"glean further information. Current statusCode: " +
                        $"{nodeStateResponse.StatusCode}.");
                }
            }
            catch (Exception e)
            {
                // Ignore any failures of this method as this was invoked to gather better
                // debugging info.
                this.logger.LogError(
                    $"{nodeName}: Could not query /node/state on node endorsed endpoint to " +
                    $"glean further information. Error: {e}.");
            }
        }
    }