Exemplo n.º 1
0
        public static Task CallSubstrate(this BackgroundService service, ILogger logger, PublicKey contractKey, string nodeEndpoint, Address from, byte[] privateKey, Func <IApplication, IExtrinsicCall> callGenerator)
        {
            var completionSource = new TaskCompletionSource();

            Task.Run(async() =>
            {
                SafeApplication application = SafeApplication.CreateApplication(
                    ex =>
                {
                    logger.LogError(ex, "{ServiceName} substrate api failed", service.GetType().FullName);
                    Interlocked.Exchange <TaskCompletionSource?>(ref completionSource, null)?.SetException(ex);
                }, logger, contractKey);
                try
                {
                    application.Application.Connect(nodeEndpoint);
                    var call = callGenerator(application.Application !);
                    application.HealthCheck(TimeSpan.FromMinutes(10), () =>
                    {
                        Interlocked.Exchange <TaskCompletionSource?>(ref completionSource, null)?.SetException(new TimeoutException());
                        application.Dispose();
                    });
                    var result =
                        await application.Application.SignWaitRetryOnLowPriority(from,
                                                                                 privateKey, call);
                    application.CancelHealthCheck();
                    result.Switch(_ =>
                    {
                        Interlocked.Exchange <TaskCompletionSource?>(ref completionSource, null)?.SetResult();
                    }, fail =>
                    {
                        var error = fail.ErrorMessage(application.Application);
                        logger.LogError("Failed to call substrate, {ErrorText}", error);
                        Interlocked.Exchange <TaskCompletionSource?>(ref completionSource, null)?.SetException(new ApplicationException(error));
                    });
                }
                catch (Exception ex)
                {
                    Interlocked.Exchange <TaskCompletionSource?>(ref completionSource, null)?.SetException(ex);
                }
                finally
                {
                    application.Dispose();
                }
            });
            return(completionSource.Task);
        }