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}.");
}
}
}