@@ -37,14 +37,16 @@ namespace Nethermind.JsonRpc.Modules.Trace
         private readonly ITracer _tracer;
         private readonly IBlockFinder _blockFinder;
         private readonly TransactionDecoder _txDecoder = new TransactionDecoder();
-        private readonly CancellationToken _cancellationToken;
+        private readonly IJsonRpcConfig _jsonRpcConfig;
+        private readonly TimeSpan _cancellationTokenTimeout;

-        public TraceModule(IReceiptFinder receiptFinder, ITracer tracer, IBlockFinder blockFinder, CancellationToken cancellationToken = default(CancellationToken))
+        public TraceModule(IReceiptFinder receiptFinder, ITracer tracer, IBlockFinder blockFinder, IJsonRpcConfig jsonRpcConfig)
         {
-            _cancellationToken = cancellationToken;
             _receiptFinder = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder));
             _tracer = tracer ?? throw new ArgumentNullException(nameof(tracer));
             _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder));
+            _jsonRpcConfig = jsonRpcConfig ?? throw new ArgumentNullException(nameof(jsonRpcConfig));
+            _cancellationTokenTimeout = TimeSpan.FromMilliseconds(_jsonRpcConfig.TracerTimeout);
         }

         private static ParityTraceTypes GetParityTypes(string[] types)

//  Copyright (c) 2018 Demerzel Solutions Limited
//  This file is part of the Nethermind library.
//
//  The Nethermind library is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  The Nethermind library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Find;
using Nethermind.Blockchain.Receipts;
using Nethermind.Blockchain.Tracing;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Evm.Tracing.ParityStyle;
using Nethermind.JsonRpc.Data;
using Nethermind.Serialization.Rlp;

namespace Nethermind.JsonRpc.Modules.Trace
{
    public class TraceModule : ITraceModule
    {
        private readonly IReceiptFinder _receiptFinder;
        private readonly ITracer _tracer;
        private readonly IBlockFinder _blockFinder;
        private readonly TransactionDecoder _txDecoder = new TransactionDecoder();
        private readonly CancellationToken _cancellationToken;

        public TraceModule(IReceiptFinder receiptFinder, ITracer tracer, IBlockFinder blockFinder, CancellationToken cancellationToken = default(CancellationToken))
        {
            _cancellationToken = cancellationToken;
            _receiptFinder = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder));
            _tracer = tracer ?? throw new ArgumentNullException(nameof(tracer));
            _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder));
        }

        private static ParityTraceTypes GetParityTypes(string[] types)
        {
            return types.Select(s => (ParityTraceTypes) Enum.Parse(typeof(ParityTraceTypes), s, true)).Aggregate((t1, t2) => t1 | t2);
        }

        public ResultWrapper<ParityTxTraceFromReplay> trace_call(TransactionForRpc message, string[] traceTypes, BlockParameter blockParameter)
        {
            Transaction tx = message.ToTransaction();
            return TraceTx(tx, traceTypes, blockParameter);
        }

        public ResultWrapper<ParityTxTraceFromReplay[]> trace_callMany((TransactionForRpc message, string[] traceTypes, BlockParameter numberOrTag)[] a)
        {
            throw new NotImplementedException();
        }

        public ResultWrapper<ParityTxTraceFromReplay> trace_rawTransaction(byte[] data, string[] traceTypes)
        {
            Transaction tx = _txDecoder.Decode(new RlpStream(data));
            return TraceTx(tx, traceTypes, BlockParameter.Latest);
        }

        private ResultWrapper<ParityTxTraceFromReplay> TraceTx(Transaction tx, string[] traceTypes, BlockParameter blockParameter)
        {
            SearchResult<BlockHeader> headerSearch = _blockFinder.SearchForHeader(blockParameter);
            if (headerSearch.IsError)
            {
                return ResultWrapper<ParityTxTraceFromReplay>.Fail(headerSearch);
            }

            BlockHeader header = headerSearch.Object;

            if (header.IsGenesis)
            {
                header = new BlockHeader(
                    header.Hash,
                    Keccak.OfAnEmptySequenceRlp,
                    Address.Zero,
                    header.Difficulty,
                    header.Number + 1,
                    header.GasLimit,
                    header.Timestamp + 1,
                    header.ExtraData);

                header.TotalDifficulty = 2 * header.Difficulty;
            }

            Block block = new Block(header, new[] {tx}, Enumerable.Empty<BlockHeader>());

            IReadOnlyCollection<ParityLikeTxTrace> result = TraceBlock(block, GetParityTypes(traceTypes));
            return ResultWrapper<ParityTxTraceFromReplay>.Success(new ParityTxTraceFromReplay(result.SingleOrDefault()));
        }

        public ResultWrapper<ParityTxTraceFromReplay> trace_replayTransaction(Keccak txHash, string[] traceTypes)
        {
            SearchResult<Keccak> blockHashSearch = _receiptFinder.SearchForReceiptBlockHash(txHash);
            if (blockHashSearch.IsError)
            {
                return ResultWrapper<ParityTxTraceFromReplay>.Fail(blockHashSearch);
            }

            SearchResult<Block> blockSearch = _blockFinder.SearchForBlock(new BlockParameter(blockHashSearch.Object));
            if (blockSearch.IsError)
            {
                return ResultWrapper<ParityTxTraceFromReplay>.Fail(blockSearch);
            }

            Block block = blockSearch.Object;

            ParityLikeTxTrace txTrace = TraceTx(block, txHash, GetParityTypes(traceTypes));
            return ResultWrapper<ParityTxTraceFromReplay>.Success(new ParityTxTraceFromReplay(txTrace));
        }

        public ResultWrapper<ParityTxTraceFromReplay[]> trace_replayBlockTransactions(BlockParameter blockParameter, string[] traceTypes)
        {
            SearchResult<Block> blockSearch = _blockFinder.SearchForBlock(blockParameter);
            if (blockSearch.IsError)
            {
                return ResultWrapper<ParityTxTraceFromReplay[]>.Fail(blockSearch);
            }

            Block block = blockSearch.Object;

            IReadOnlyCollection<ParityLikeTxTrace> txTraces = TraceBlock(block, GetParityTypes(traceTypes));

            // ReSharper disable once CoVariantArrayConversion
            return ResultWrapper<ParityTxTraceFromReplay[]>.Success(txTraces.Select(t => new ParityTxTraceFromReplay(t, true)).ToArray());
        }

        public ResultWrapper<ParityTxTraceFromStore[]> trace_filter(BlockParameter fromBlock, BlockParameter toBlock, Address toAddress, int after, int count)
        {
            throw new NotImplementedException();
        }

        public ResultWrapper<ParityTxTraceFromStore[]> trace_block(BlockParameter blockParameter)
        {
            SearchResult<Block> blockSearch = _blockFinder.SearchForBlock(blockParameter);
            if (blockSearch.IsError)
            {
                return ResultWrapper<ParityTxTraceFromStore[]>.Fail(blockSearch);
            }

            Block block = blockSearch.Object;

            IReadOnlyCollection<ParityLikeTxTrace> txTraces = TraceBlock(block, ParityTraceTypes.Trace | ParityTraceTypes.Rewards);
            return ResultWrapper<ParityTxTraceFromStore[]>.Success(txTraces.SelectMany(ParityTxTraceFromStore.FromTxTrace).ToArray());
        }

        public ResultWrapper<ParityTxTraceFromStore[]> trace_get(Keccak txHash, int[] positions)
        {
            throw new NotImplementedException();
        }

        public ResultWrapper<ParityTxTraceFromStore[]> trace_transaction(Keccak txHash)
        {
            SearchResult<Keccak> blockHashSearch = _receiptFinder.SearchForReceiptBlockHash(txHash);
            if (blockHashSearch.IsError)
            {
                return ResultWrapper<ParityTxTraceFromStore[]>.Fail(blockHashSearch);
            }

            SearchResult<Block> blockSearch = _blockFinder.SearchForBlock(new BlockParameter(blockHashSearch.Object));
            if (blockSearch.IsError)
            {
                return ResultWrapper<ParityTxTraceFromStore[]>.Fail(blockSearch);
            }

            Block block = blockSearch.Object;

            ParityLikeTxTrace txTrace = TraceTx(block, txHash, ParityTraceTypes.Trace | ParityTraceTypes.Rewards);
            return ResultWrapper<ParityTxTraceFromStore[]>.Success(ParityTxTraceFromStore.FromTxTrace(txTrace));
        }

        private IReadOnlyCollection<ParityLikeTxTrace> TraceBlock(Block block, ParityTraceTypes traceTypes)
        {
            ParityLikeBlockTracer listener = new ParityLikeBlockTracer(traceTypes, _cancellationToken);
            _tracer.Trace(block, listener);

            return listener.BuildResult();
        }

        private ParityLikeTxTrace TraceTx(Block block, Keccak txHash, ParityTraceTypes traceTypes)
        {
            ParityLikeBlockTracer listener = new ParityLikeBlockTracer(txHash, traceTypes, _cancellationToken);
            _tracer.Trace(block, listener);

            return listener.BuildResult().SingleOrDefault();
        }
    }
}

That was a really bad CR from me before if I did not spot it.


@@ -144,6 +144,7 @@ namespace Datadog.Trace.Vendors.Newtonsoft.Json.Serialization
             return property;
         }

+#if !NETCOREAPP
         private bool TryGetValue(string key, out JsonProperty item)
         {
             if (Dictionary == null)

//------------------------------------------------------------------------------
// <auto-generated />
// This file was automatically generated by the UpdateVendors tool.
//------------------------------------------------------------------------------
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using Datadog.Trace.Vendors.Newtonsoft.Json.Utilities;
using System.Globalization;

namespace Datadog.Trace.Vendors.Newtonsoft.Json.Serialization
{
    /// <summary>
    /// A collection of <see cref="JsonProperty"/> objects.
    /// </summary>
    internal class JsonPropertyCollection : KeyedCollection<string, JsonProperty>
    {
        private readonly Type _type;
        private readonly List<JsonProperty> _list;

        /// <summary>
        /// Initializes a new instance of the <see cref="JsonPropertyCollection"/> class.
        /// </summary>
        /// <param name="type">The type.</param>
        public JsonPropertyCollection(Type type)
            : base(StringComparer.Ordinal)
        {
            ValidationUtils.ArgumentNotNull(type, "type");
            _type = type;

            // foreach over List<T> to avoid boxing the Enumerator
            _list = (List<JsonProperty>)Items;
        }

        /// <summary>
        /// When implemented in a derived class, extracts the key from the specified element.
        /// </summary>
        /// <param name="item">The element from which to extract the key.</param>
        /// <returns>The key for the specified element.</returns>
        protected override string GetKeyForItem(JsonProperty item)
        {
            return item.PropertyName;
        }

        /// <summary>
        /// Adds a <see cref="JsonProperty"/> object.
        /// </summary>
        /// <param name="property">The property to add to the collection.</param>
        public void AddProperty(JsonProperty property)
        {
            if (Contains(property.PropertyName))
            {
                // don't overwrite existing property with ignored property
                if (property.Ignored)
                {
                    return;
                }

                JsonProperty existingProperty = this[property.PropertyName];
                bool duplicateProperty = true;

                if (existingProperty.Ignored)
                {
                    // remove ignored property so it can be replaced in collection
                    Remove(existingProperty);
                    duplicateProperty = false;
                }
                else
                {
                    if (property.DeclaringType != null && existingProperty.DeclaringType != null)
                    {
                        if (property.DeclaringType.IsSubclassOf(existingProperty.DeclaringType)
                            || (existingProperty.DeclaringType.IsInterface() && property.DeclaringType.ImplementInterface(existingProperty.DeclaringType)))
                        {
                            // current property is on a derived class and hides the existing
                            Remove(existingProperty);
                            duplicateProperty = false;
                        }
                        if (existingProperty.DeclaringType.IsSubclassOf(property.DeclaringType)
                            || (property.DeclaringType.IsInterface() && existingProperty.DeclaringType.ImplementInterface(property.DeclaringType)))
                        {
                            // current property is hidden by the existing so don't add it
                            return;
                        }

                        if (_type.ImplementInterface(existingProperty.DeclaringType) && _type.ImplementInterface(property.DeclaringType))
                        {
                            // current property was already defined on another interface
                            return;
                        }
                    }
                }

                if (duplicateProperty)
                {
                    throw new JsonSerializationException("A member with the name '{0}' already exists on '{1}'. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, _type));
                }
            }

            Add(property);
        }

        /// <summary>
        /// Gets the closest matching <see cref="JsonProperty"/> object.
        /// First attempts to get an exact case match of <paramref name="propertyName"/> and then
        /// a case insensitive match.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns>A matching property if found.</returns>
        public JsonProperty GetClosestMatchProperty(string propertyName)
        {
            JsonProperty property = GetProperty(propertyName, StringComparison.Ordinal);
            if (property == null)
            {
                property = GetProperty(propertyName, StringComparison.OrdinalIgnoreCase);
            }

            return property;
        }

        private bool TryGetValue(string key, out JsonProperty item)
        {
            if (Dictionary == null)
            {
                item = default;
                return false;
            }

            return Dictionary.TryGetValue(key, out item);
        }

        /// <summary>
        /// Gets a property by property name.
        /// </summary>
        /// <param name="propertyName">The name of the property to get.</param>
        /// <param name="comparisonType">Type property name string comparison.</param>
        /// <returns>A matching property if found.</returns>
        public JsonProperty GetProperty(string propertyName, StringComparison comparisonType)
        {
            // KeyedCollection has an ordinal comparer
            if (comparisonType == StringComparison.Ordinal)
            {
                if (TryGetValue(propertyName, out JsonProperty property))
                {
                    return property;
                }

                return null;
            }

            for (int i = 0; i < _list.Count; i++)
            {
                JsonProperty property = _list[i];
                if (string.Equals(propertyName, property.PropertyName, comparisonType))
                {
                    return property;
                }
            }

            return null;
        }
    }
}


@@ -9,5 +9,15 @@ namespace MvvmCross.Forms.Views.Attributes
         public MvxNavigationPagePresentationAttribute()
         {
         }
+
+        public virtual bool WrapInNavigationPage { get; set; } = false;
+
+        /// <summary>
+        /// Clears the backstack of the current NavigationPage when set to true
+        /// </summary>
+        /// <value><c>true</c> if no history; otherwise, <c>false</c>.</value>
+        public virtual bool NoHistory { get; set; } = false;
+
+        public bool Animated { get; set; } = true;
     }
 }

using System;
using MvvmCross.Core.Views;

namespace MvvmCross.Forms.Views.Attributes
{
    [AttributeUsage(AttributeTargets.Class)]
    public class MvxNavigationPagePresentationAttribute : MvxBasePresentationAttribute
    {
        public MvxNavigationPagePresentationAttribute()
        {
        }
    }
}

Is it possible to wrap a NavigationPage in a NavigationPage?


@@ -32,6 +32,10 @@ namespace MvvmCross.Core.ViewModels
         public static void CallBundleMethod(this IMvxViewModel viewModel, MethodInfo methodInfo, IMvxBundle bundle)
         {
             var parameters = methodInfo.GetParameters().ToArray();
+
+            if (bundle == null && parameters.Count() > 0)
+                return;
+
             if (parameters.Count() == 1
                 && parameters[0].ParameterType == typeof(IMvxBundle))
             {

// MvxViewModelExtensions.cs

// MvvmCross is licensed using Microsoft Public License (Ms-PL)
// Contributions and inspirations noted in readme.md and license.txt
//
// Project Lead - Stuart Lodge, @slodge, me@slodge.com

namespace MvvmCross.Core.ViewModels
{
    using System.Linq;
    using System.Reflection;

    using MvvmCross.Platform;

    public static class MvxViewModelExtensions
    {
        public static void CallBundleMethods(this IMvxViewModel viewModel, string methodName, IMvxBundle bundle)
        {
            var methods = viewModel
                .GetType()
                .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy)
                .Where(m => m.Name == methodName)
                .Where(m => !m.IsAbstract)
                .ToList();

            foreach (var methodInfo in methods)
            {
                viewModel.CallBundleMethod(methodInfo, bundle);
            }
        }

        public static void CallBundleMethod(this IMvxViewModel viewModel, MethodInfo methodInfo, IMvxBundle bundle)
        {
            var parameters = methodInfo.GetParameters().ToArray();
            if (parameters.Count() == 1
                && parameters[0].ParameterType == typeof(IMvxBundle))
            {
                // this method is the 'normal' interface method
                methodInfo.Invoke(viewModel, new object[] { bundle });
                return;
            }

            if (parameters.Count() == 1
                && !MvxSingletonCache.Instance.Parser.TypeSupported(parameters[0].ParameterType))
            {
                // call method using typed object
                var value = bundle.Read(parameters[0].ParameterType);
                methodInfo.Invoke(viewModel, new[] { value });
                return;
            }

            // call method using named method arguments
            var invokeWith = bundle.CreateArgumentList(parameters, viewModel.GetType().Name)
                                   .ToArray();
            methodInfo.Invoke(viewModel, invokeWith);
        }

        public static IMvxBundle SaveStateBundle(this IMvxViewModel viewModel)
        {
            var toReturn = new MvxBundle();
            var methods = viewModel.GetType()
                                   .GetMethods()
                                   .Where(m => m.Name == "SaveState")
                                   .Where(m => m.ReturnType != typeof(void))
                                   .Where(m => !m.GetParameters().Any());

            foreach (var methodInfo in methods)
            {
                // use methods like `public T SaveState()`
                var stateObject = methodInfo.Invoke(viewModel, new object[0]);
                if (stateObject != null)
                {
                    toReturn.Write(stateObject);
                }
            }

            // call the general `public void SaveState(bundle)` method too
            viewModel.SaveState(toReturn);

            return toReturn;
        }
    }
}

This check looks odd to me. I can't quite grok it. Why is it needed now? What's changed?


@@ -94,8 +94,7 @@ namespace OpenTelemetry.Trace
             }
             else if (this.Exporter != null)
             {
-                // TODO: Make this BatchingActivityProcessor once its available.
-                exportingProcessor = new SimpleActivityProcessor(this.Exporter);
+                exportingProcessor = new BatchingActivityProcessor(this.Exporter);
                 this.Processors.Add(exportingProcessor);
             }

// <copyright file="ActivityProcessorPipelineBuilder.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using System;
using System.Collections.Generic;
using OpenTelemetry.Trace.Internal;

namespace OpenTelemetry.Trace
{
    /// <summary>
    /// Configures exporting pipeline with chains of processors and exporter.
    /// </summary>
    public class ActivityProcessorPipelineBuilder
    {
        private Func<ActivityExporter, ActivityProcessor> lastProcessorFactory;
        private List<Func<ActivityProcessor, ActivityProcessor>> processorChain;

        internal ActivityProcessorPipelineBuilder()
        {
        }

        internal ActivityExporter Exporter { get; private set; }

        internal List<ActivityProcessor> Processors { get; private set; }

        /// <summary>
        /// Adds chained processor to the pipeline. Processors are executed in the order they were added.
        /// </summary>
        /// <param name="processorFactory">Function that creates processor from the next one.</param>
        /// <returns>Returns <see cref="ActivityProcessorPipelineBuilder"/>.</returns>
        public ActivityProcessorPipelineBuilder AddProcessor(Func<ActivityProcessor, ActivityProcessor> processorFactory)
        {
            if (processorFactory == null)
            {
                throw new ArgumentNullException(nameof(processorFactory));
            }

            if (this.processorChain == null)
            {
                this.processorChain = new List<Func<ActivityProcessor, ActivityProcessor>>();
            }

            this.processorChain.Add(processorFactory);

            return this;
        }

        /// <summary>
        /// Configures last processor that invokes exporter. When not set, <see cref="SimpleActivityProcessor"/> is used.
        /// </summary>
        /// <param name="processorFactory">Factory that creates exporting processor from the exporter.</param>
        /// <returns>Returns <see cref="ActivityProcessorPipelineBuilder"/>.</returns>
        public ActivityProcessorPipelineBuilder SetExportingProcessor(Func<ActivityExporter, ActivityProcessor> processorFactory)
        {
            this.lastProcessorFactory = processorFactory ?? throw new ArgumentNullException(nameof(processorFactory));
            return this;
        }

        /// <summary>
        /// Configures exporter.
        /// </summary>
        /// <param name="exporter">Exporter instance.</param>
        /// <returns>Returns <see cref="ActivityProcessorPipelineBuilder"/>.</returns>
        public ActivityProcessorPipelineBuilder SetExporter(ActivityExporter exporter)
        {
            this.Exporter = exporter ?? throw new ArgumentNullException(nameof(exporter));
            return this;
        }

        internal ActivityProcessor Build()
        {
            this.Processors = new List<ActivityProcessor>();

            ActivityProcessor exportingProcessor = null;

            // build or create default exporting processor
            if (this.lastProcessorFactory != null)
            {
                exportingProcessor = this.lastProcessorFactory.Invoke(this.Exporter);
                this.Processors.Add(exportingProcessor);
            }
            else if (this.Exporter != null)
            {
                // TODO: Make this BatchingActivityProcessor once its available.
                exportingProcessor = new SimpleActivityProcessor(this.Exporter);
                this.Processors.Add(exportingProcessor);
            }

            if (this.processorChain == null)
            {
                // if there is no chain, return exporting processor.
                if (exportingProcessor == null)
                {
                    exportingProcessor = new NoopActivityProcessor();
                    this.Processors.Add(exportingProcessor);
                }

                return exportingProcessor;
            }

            var next = exportingProcessor;

            // build chain from the end to the beginning
            for (int i = this.processorChain.Count - 1; i >= 0; i--)
            {
                next = this.processorChain[i].Invoke(next);
                this.Processors.Add(next);
            }

            // return the last processor in the chain - it will be called first
            return this.Processors[this.Processors.Count - 1];
        }
    }
}

Don't know what should be the default. Lets keep BatchingProcessor for now. And revisit the area after beta.


@@ -19,9 +19,9 @@ namespace Datadog.Trace.Util.Http
         internal static Dictionary<string, object> PrepareArgsForWaf(this HttpRequest request, RouteData routeDatas = null)
         {
             var url = GetUrl(request);
-
             var headersDic = new Dictionary<string, string>();
-            foreach (var k in request.Headers.Keys)
+            var headerKeys = request.Headers.Keys.Where(k => k != "Cookie");
+            foreach (var k in headerKeys)
             {
                 headersDic.Add(k, request.Headers[k]);
             }

// <copyright file="HttpRequestExtensions.Core.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

#if !NETFRAMEWORK
using System.Collections.Generic;
using System.Linq;
using Datadog.Trace.AppSec;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;

namespace Datadog.Trace.Util.Http
{
    internal static partial class HttpRequestExtensions
    {
        private const string NoHostSpecified = "UNKNOWN_HOST";

        internal static Dictionary<string, object> PrepareArgsForWaf(this HttpRequest request, RouteData routeDatas = null)
        {
            var url = GetUrl(request);

            var headersDic = new Dictionary<string, string>();
            foreach (var k in request.Headers.Keys)
            {
                headersDic.Add(k, request.Headers[k]);
            }

            var cookiesDic = new Dictionary<string, string>();
            foreach (var k in request.Cookies.Keys)
            {
                cookiesDic.Add(k, request.Cookies[k]);
            }

            var dict = new Dictionary<string, object>()
            {
                { AddressesConstants.RequestMethod, request.Method },
                { AddressesConstants.RequestUriRaw, url },
                { AddressesConstants.RequestQuery, request.QueryString.ToString() },
                { AddressesConstants.RequestHeaderNoCookies, headersDic },
                { AddressesConstants.RequestCookies, cookiesDic },
            };

            if (routeDatas != null && routeDatas.Values.Any())
            {
                var routeDataDict = ConvertRouteValueDictionary(routeDatas.Values);
                dict.Add(AddressesConstants.RequestPathParams, routeDataDict);
            }

            return dict;
        }

        internal static string GetUrl(this HttpRequest request)
        {
            if (request.Host.HasValue)
            {
                return $"{request.Scheme}://{request.Host.Value}{request.PathBase.Value}{request.Path.Value}";
            }

            // HTTP 1.0 requests are not required to provide a Host to be valid
            // Since this is just for display, we can provide a string that is
            // not an actual Uri with only the fields that are specified.
            // request.GetDisplayUrl(), used above, will throw an exception
            // if request.Host is null.
            return $"{request.Scheme}://{HttpRequestExtensions.NoHostSpecified}{request.PathBase.Value}{request.Path.Value}";
        }
    }
}
#endif

Don't know if you want to use LINQ here, and instead move to be an `if` inside the loop (as you do in the other implementation for FX?). Also, probably want to make the comparison case insensitive?


@@ -56,8 +56,8 @@ namespace Microsoft.VisualStudio.TestPlatform.Client
             var runconfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(discoveryCriteria.RunSettings);
             var testHostManager = this.TestEngine.GetDefaultTestHostManager(runconfiguration.TargetPlatform, runconfiguration.TargetFrameworkVersion);

-            var discoveryManager = this.TestEngine.GetDiscoveryManager();
-            discoveryManager.Initialize(testHostManager);
+            var discoveryManager = this.TestEngine.GetDiscoveryManager(testHostManager);
+            discoveryManager.Initialize();

             return new DiscoveryRequest(discoveryCriteria, discoveryManager);
         }

// Copyright (c) Microsoft. All rights reserved.

namespace Microsoft.VisualStudio.TestPlatform.Client
{
    using System;
    using System.Collections.Generic;

    using Microsoft.VisualStudio.TestPlatform.Client.Discovery;
    using Microsoft.VisualStudio.TestPlatform.Client.Execution;
    using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine;
    using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
    using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine;
    using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;

    /// <summary>
    /// Implementation for TestPlatform
    /// </summary>
    public class TestPlatform : ITestPlatform
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TestPlatform"/> class.
        /// </summary>
        public TestPlatform() : this(new TestEngine())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TestPlatform"/> class.
        /// </summary>
        /// <param name="testEngine">
        /// The test engine.
        /// </param>
        protected TestPlatform(ITestEngine testEngine)
        {
            this.TestEngine = testEngine;
        }

        /// <summary>
        /// Gets or sets Test Engine instance
        /// </summary>
        private ITestEngine TestEngine { get; set; }

        /// <summary>
        /// The create discovery request.
        /// </summary>
        /// <param name="discoveryCriteria"> The discovery criteria. </param>
        /// <returns> The <see cref="IDiscoveryRequest"/>. </returns>
        /// <exception cref="ArgumentNullException"> Throws if parameter is null. </exception>
        public IDiscoveryRequest CreateDiscoveryRequest(DiscoveryCriteria discoveryCriteria)
        {
            if (discoveryCriteria == null)
            {
                throw new ArgumentNullException("discoveryCriteria");
            }

            var runconfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(discoveryCriteria.RunSettings);
            var testHostManager = this.TestEngine.GetDefaultTestHostManager(runconfiguration.TargetPlatform, runconfiguration.TargetFrameworkVersion);

            var discoveryManager = this.TestEngine.GetDiscoveryManager();
            discoveryManager.Initialize(testHostManager);

            return new DiscoveryRequest(discoveryCriteria, discoveryManager);
        }

        /// <summary>
        /// The create test run request.
        /// </summary>
        /// <param name="testRunCriteria"> The test run criteria.  </param>
        /// <returns> The <see cref="ITestRunRequest"/>. </returns>
        /// <exception cref="ArgumentNullException"> Throws if parameter is null. </exception>
        public ITestRunRequest CreateTestRunRequest(TestRunCriteria testRunCriteria)
        {
            if (testRunCriteria == null)
            {
                throw new ArgumentNullException("testRunCriteria");
            }

            var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(testRunCriteria.TestRunSettings);
            var testHostManager = this.TestEngine.GetDefaultTestHostManager(runConfiguration.TargetPlatform, runConfiguration.TargetFrameworkVersion);

            if (testRunCriteria.TestHostLauncher != null)
            {
                testHostManager.SetCustomLauncher(testRunCriteria.TestHostLauncher);
            }

            var executionManager = this.TestEngine.GetExecutionManager(testRunCriteria);
            executionManager.Initialize(testHostManager);

            return new TestRunRequest(testRunCriteria, executionManager);
        }

        /// <summary>
        /// The dispose.
        /// </summary>
        public void Dispose()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// The initialize.
        /// </summary>
        /// <param name="pathToAdditionalExtensions"> The path to additional extensions. </param>
        /// <param name="loadOnlyWellKnownExtensions"> The load only well known extensions. </param>
        /// <param name="forceX86Discoverer"> The force x86 discoverer. </param>
        public void Initialize(IEnumerable<string> pathToAdditionalExtensions, bool loadOnlyWellKnownExtensions, bool forceX86Discoverer)
        {
            // TODO: ForceX86Discoverer options
            this.TestEngine.GetExtensionManager()
                 .UseAdditionalExtensions(pathToAdditionalExtensions, loadOnlyWellKnownExtensions);
        }

        /// <summary>
        /// The update extensions.
        /// </summary>
        /// <param name="pathToAdditionalExtensions"> The path to additional extensions. </param>
        /// <param name="loadOnlyWellKnownExtensions"> The load only well known extensions. </param>
        public void UpdateExtensions(IEnumerable<string> pathToAdditionalExtensions, bool loadOnlyWellKnownExtensions)
        {
            this.TestEngine.GetExtensionManager()
                   .UseAdditionalExtensions(pathToAdditionalExtensions, loadOnlyWellKnownExtensions);
        }
    }
}

We want to use the DiscoveryManager instance across several TestHostManager . So inject it via Initialize and call Close.


@@ -16,11 +16,12 @@

 using System.Collections.Generic;
 using Nethermind.Core;
+using Nethermind.Core.Crypto;

 namespace Nethermind.Consensus
 {
     public interface IPendingTxSelector
     {
-        IEnumerable<Transaction> SelectTransactions(long gasLimit);
+        IEnumerable<Transaction> SelectTransactions(Keccak stateRoot, long gasLimit);
     }
 }

//  Copyright (c) 2018 Demerzel Solutions Limited
//  This file is part of the Nethermind library.
//
//  The Nethermind library is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  The Nethermind library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.

using System.Collections.Generic;
using Nethermind.Core;

namespace Nethermind.Consensus
{
    public interface IPendingTxSelector
    {
        IEnumerable<Transaction> SelectTransactions(long gasLimit);
    }
}

stateRoot or maybe ParentHeader would make more sense from API point of view?


@@ -19,13 +19,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
     /// </summary>
     public class ListenOptions : IEndPointInformation, IConnectionBuilder
     {
+        internal const string Http2ExperimentSwitch = "Switch.Microsoft.AspNetCore.Server.Kestrel.Experimental.Http2";
+
         private FileHandleType _handleType;
+        private HttpProtocols _protocols = HttpProtocols.Http1;
+        internal bool _isHttp2Supported;
         private readonly List<Func<ConnectionDelegate, ConnectionDelegate>> _components = new List<Func<ConnectionDelegate, ConnectionDelegate>>();

         internal ListenOptions(IPEndPoint endPoint)
         {
             Type = ListenType.IPEndPoint;
             IPEndPoint = endPoint;
+            AppContext.TryGetSwitch(Http2ExperimentSwitch, out _isHttp2Supported);
         }

         internal ListenOptions(string socketPath)

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Protocols;
using Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;

namespace Microsoft.AspNetCore.Server.Kestrel.Core
{
    /// <summary>
    /// Describes either an <see cref="IPEndPoint"/>, Unix domain socket path, or a file descriptor for an already open
    /// socket that Kestrel should bind to or open.
    /// </summary>
    public class ListenOptions : IEndPointInformation, IConnectionBuilder
    {
        private FileHandleType _handleType;
        private readonly List<Func<ConnectionDelegate, ConnectionDelegate>> _components = new List<Func<ConnectionDelegate, ConnectionDelegate>>();

        internal ListenOptions(IPEndPoint endPoint)
        {
            Type = ListenType.IPEndPoint;
            IPEndPoint = endPoint;
        }

        internal ListenOptions(string socketPath)
        {
            Type = ListenType.SocketPath;
            SocketPath = socketPath;
        }

        internal ListenOptions(ulong fileHandle)
            : this(fileHandle, FileHandleType.Auto)
        {
        }

        internal ListenOptions(ulong fileHandle, FileHandleType handleType)
        {
            Type = ListenType.FileHandle;
            FileHandle = fileHandle;
            switch (handleType)
            {
                case FileHandleType.Auto:
                case FileHandleType.Tcp:
                case FileHandleType.Pipe:
                    _handleType = handleType;
                    break;
                default:
                    throw new NotSupportedException();
            }
        }

        /// <summary>
        /// The type of interface being described: either an <see cref="IPEndPoint"/>, Unix domain socket path, or a file descriptor.
        /// </summary>
        public ListenType Type { get; }

        public FileHandleType HandleType
        {
            get => _handleType;
            set
            {
                if (value == _handleType)
                {
                    return;
                }
                if (Type != ListenType.FileHandle || _handleType != FileHandleType.Auto)
                {
                    throw new InvalidOperationException();
                }

                switch (value)
                {
                    case FileHandleType.Tcp:
                    case FileHandleType.Pipe:
                        _handleType = value;
                        break;
                    default:
                        throw new ArgumentException(nameof(HandleType));
                }
            }
        }

        // IPEndPoint is mutable so port 0 can be updated to the bound port.
        /// <summary>
        /// The <see cref="IPEndPoint"/> to bind to.
        /// Only set if the <see cref="ListenOptions"/> <see cref="Type"/> is <see cref="ListenType.IPEndPoint"/>.
        /// </summary>
        public IPEndPoint IPEndPoint { get; set; }

        /// <summary>
        /// The absolute path to a Unix domain socket to bind to.
        /// Only set if the <see cref="ListenOptions"/> <see cref="Type"/> is <see cref="ListenType.SocketPath"/>.
        /// </summary>
        public string SocketPath { get; }

        /// <summary>
        /// A file descriptor for the socket to open.
        /// Only set if the <see cref="ListenOptions"/> <see cref="Type"/> is <see cref="ListenType.FileHandle"/>.
        /// </summary>
        public ulong FileHandle { get; }

        /// <summary>
        /// Enables an <see cref="IConnectionAdapter"/> to resolve and use services registered by the application during startup.
        /// Only set if accessed from the callback of a <see cref="KestrelServerOptions"/> Listen* method.
        /// </summary>
        public KestrelServerOptions KestrelServerOptions { get; internal set; }

        /// <summary>
        /// Set to false to enable Nagle's algorithm for all connections.
        /// </summary>
        /// <remarks>
        /// Defaults to true.
        /// </remarks>
        public bool NoDelay { get; set; } = true;

        /// <summary>
        /// The protocols enabled on this endpoint.
        /// </summary>
        /// <remarks>Defaults to HTTP/1.x only.</remarks>
        public HttpProtocols Protocols { get; set; } = HttpProtocols.Http1;

        /// <summary>
        /// Gets the <see cref="List{IConnectionAdapter}"/> that allows each connection <see cref="System.IO.Stream"/>
        /// to be intercepted and transformed.
        /// Configured by the <c>UseHttps()</c> and <see cref="Hosting.ListenOptionsConnectionLoggingExtensions.UseConnectionLogging(ListenOptions)"/>
        /// extension methods.
        /// </summary>
        /// <remarks>
        /// Defaults to empty.
        /// </remarks>
        public List<IConnectionAdapter> ConnectionAdapters { get; } = new List<IConnectionAdapter>();

        public IServiceProvider ApplicationServices => KestrelServerOptions?.ApplicationServices;

        /// <summary>
        /// Gets the name of this endpoint to display on command-line when the web server starts.
        /// </summary>
        internal virtual string GetDisplayName()
        {
            var scheme = ConnectionAdapters.Any(f => f.IsHttps)
                ? "https"
                : "http";

            switch (Type)
            {
                case ListenType.IPEndPoint:
                    return $"{scheme}://{IPEndPoint}";
                case ListenType.SocketPath:
                    return $"{scheme}://unix:{SocketPath}";
                case ListenType.FileHandle:
                    return $"{scheme}://<file handle>";
                default:
                    throw new InvalidOperationException();
            }
        }

        public override string ToString() => GetDisplayName();

        public IConnectionBuilder Use(Func<ConnectionDelegate, ConnectionDelegate> middleware)
        {
            _components.Add(middleware);
            return this;
        }

        public ConnectionDelegate Build()
        {
            ConnectionDelegate app = context =>
            {
                return Task.CompletedTask;
            };

            for (int i = _components.Count - 1; i >= 0; i--)
            {
                var component = _components[i];
                app = component(app);
            }

            return app;
        }

        internal virtual async Task BindAsync(AddressBindContext context)
        {
            await AddressBinder.BindEndpointAsync(this, context).ConfigureAwait(false);
            context.Addresses.Add(GetDisplayName());
        }
    }
}


@@ -5,8 +5,8 @@ namespace Microsoft.CodeAnalysis.Sarif
     public static class VersionConstants
     {
         public const string Prerelease = "-beta";
-        public const string AssemblyVersion = "1.5.21";
-        public const string FileVersion = "1.5.21" + ".0";
+        public const string AssemblyVersion = "1.5.22";
+        public const string FileVersion = "1.5.22" + ".0";
         public const string Version = AssemblyVersion + Prerelease;
     }
  }

// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT
// license. See LICENSE file in the project root for full license information.
namespace Microsoft.CodeAnalysis.Sarif
{
    public static class VersionConstants
    {
        public const string Prerelease = "-beta";
        public const string AssemblyVersion = "1.5.21";
        public const string FileVersion = "1.5.21" + ".0";
        public const string Version = AssemblyVersion + Prerelease;
    }
 }

How'd this get updated? Why don't I see a chance somewhere to SetCurrentVersion.cmd?


@@ -1,27 +1,19 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
 using Datadog.Trace.Logging;
 using OpenTracing;

 namespace Datadog.Trace.OpenTracing
 {
-    internal class OpenTracingSpanContext : SpanContext, ISpanContext
+    internal class OpenTracingSpanContext : ISpanContext
     {
         private static ILog _log = LogProvider.For<OpenTracingSpanContext>();

-        internal OpenTracingSpanContext(IDatadogTracer tracer, SpanContext parent, string serviceName)
-            : base(tracer, parent, serviceName)
+        public OpenTracingSpanContext(SpanContext context)
         {
+            Context = context;
         }

-        internal OpenTracingSpanContext(ulong traceId, ulong spanId)
-            : base(traceId, spanId)
-        {
-        }
-
-        internal OpenTracingSpanContext(SpanContext spanContext)
-            : base(spanContext)
-        {
-        }
+        internal SpanContext Context { get; }

         public override bool Equals(object obj)
         {

using System.Collections.Generic;
using Datadog.Trace.Logging;
using OpenTracing;

namespace Datadog.Trace.OpenTracing
{
    internal class OpenTracingSpanContext : SpanContext, ISpanContext
    {
        private static ILog _log = LogProvider.For<OpenTracingSpanContext>();

        internal OpenTracingSpanContext(IDatadogTracer tracer, SpanContext parent, string serviceName)
            : base(tracer, parent, serviceName)
        {
        }

        internal OpenTracingSpanContext(ulong traceId, ulong spanId)
            : base(traceId, spanId)
        {
        }

        internal OpenTracingSpanContext(SpanContext spanContext)
            : base(spanContext)
        {
        }

        public override bool Equals(object obj)
        {
            var spanContext = obj as OpenTracingSpanContext;
            if (spanContext == null)
            {
                return false;
            }

            return this.ParentId == spanContext.ParentId && this.SpanId == spanContext.SpanId && this.ServiceName == spanContext.ServiceName;
        }

        public override int GetHashCode()
        {
            return this.ParentId.GetHashCode() ^ this.SpanId.GetHashCode() ^ this.ServiceName.GetHashCode();
        }

        public IEnumerable<KeyValuePair<string, string>> GetBaggageItems()
        {
            _log.Debug("SpanContext.GetBaggageItems is not implemented by Datadog.Trace");
            yield break;
        }
    }
}

I think I had a reason to do it by inheritance but I can't think of it anymore. I'll think about it and update you if it comes back.


//  Copyright (c) 2018 Demerzel Solutions Limited
//  This file is part of the Nethermind library.
//
//  The Nethermind library is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  The Nethermind library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.

using System;
using BenchmarkDotNet.Attributes;
using Nethermind.Core.Crypto;
using Nethermind.Stats;
using Nethermind.Stats.Model;

namespace Nethermind.Network.Benchmarks
{
    public class NodeStatsCtorBenchmarks
    {
        private Node _node;

        [GlobalSetup]
        public void Setup()
        {
            _node = new Node(new PublicKey("0x000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"), "127.0.0.1", 1234);
        }

        [Benchmark]
        public void Improved()
        {
            throw new NotImplementedException();
        }

        [Benchmark]
        public void Light()
        {
            NodeStatsLight stats = new NodeStatsLight(_node);
        }

        [Benchmark]
        public long LightRep()
        {
            NodeStatsLight stats = new NodeStatsLight(_node);
            return stats.CurrentNodeReputation;
        }
    }
}

a lot of default 'false' for isStatic cluttering the PR


@@ -13,5 +13,5 @@ namespace Datadog.Trace.Configuration
         {
             return Environment.GetEnvironmentVariable(key);
         }
-    }
+   }
 }

using System;

namespace Datadog.Trace.Configuration
{
    /// <summary>
    /// Represents a configuration source that
    /// retrieves values from environment variables.
    /// </summary>
    public class EnvironmentConfigurationSource : StringConfigurationSource
    {
        /// <inheritdoc />
        public override string GetString(string key)
        {
            return Environment.GetEnvironmentVariable(key);
        }
    }
}

nit: Looks like the whitespace got thrown off, can you fix this?


@@ -1,14 +1,16 @@
-// IMvxAppStart.cs
+// IMvxAppStart.cs

 // MvvmCross is licensed using Microsoft Public License (Ms-PL)
 // Contributions and inspirations noted in readme.md and license.txt
 //
 // Project Lead - Stuart Lodge, @slodge, me@slodge.com

+using System.Threading.Tasks;
+
 namespace MvvmCross.Core.ViewModels
 {
     public interface IMvxAppStart
     {
-        void Start(object hint = null);
+        Task Start(object hint = null);
     }
 }

// IMvxAppStart.cs

// MvvmCross is licensed using Microsoft Public License (Ms-PL)
// Contributions and inspirations noted in readme.md and license.txt
//
// Project Lead - Stuart Lodge, @slodge, me@slodge.com

namespace MvvmCross.Core.ViewModels
{
    public interface IMvxAppStart
    {
        void Start(object hint = null);
    }
}


@@ -1,12 +1,19 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

+using System;
 using Microsoft.AspNetCore.Server.Kestrel.Filter;

 namespace Microsoft.AspNetCore.Server.Kestrel
 {
     public interface IKestrelServerInformation
     {
+        TimeSpan ExecutionTimeout { get; set; }
+
+        TimeSpan HeadersCompleteTimeout { get; set; }
+
+        TimeSpan KeepAliveTimeout { get; set; }
+
         int ThreadCount { get; set; }

         bool NoDelay { get; set; }

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.AspNetCore.Server.Kestrel.Filter;

namespace Microsoft.AspNetCore.Server.Kestrel
{
    public interface IKestrelServerInformation
    {
        int ThreadCount { get; set; }

        bool NoDelay { get; set; }

        /// <summary>
        /// Gets or sets a flag that instructs <seealso cref="KestrelServer"/> whether it is safe to
        /// reuse the Request and Response <seealso cref="System.IO.Stream"/> objects
        /// for another request after the Response's OnCompleted callback has fired.
        /// When this is set to true it is not safe to retain references to these streams after this event has fired.
        /// It is false by default.
        /// </summary>
        /// <remarks>
        /// When this is set to true it is not safe to retain references to these streams after this event has fired.
        /// It is false by default.
        /// </remarks>
        bool ReuseStreams { get; set; }

        IConnectionFilter ConnectionFilter { get; set; }
    }
}

KeepAlive and HeadersComplete are reasonable, but I don't think we need or want ExecutionTimeout at the server level. A) The same functionality can be provided in app/middleware code. B) The timeout is un-enforceable. You can't force an app to abandon a request, you can only close the socket and trip the token. The RequestAborted CancellationToken is at best a hint. There are no thread aborts like v4. C) There are known scenarios this breaks with long running requests. It's one more setting on the server to hunt down and fiddle with when that happens.


@@ -11,6 +11,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Https
     public static class HttpsApplicationBuilderExtensions
     {
         public static IApplicationBuilder UseKestrelHttps(this IApplicationBuilder app, X509Certificate2 cert)
+        {
+            return app.UseKestrelHttps(new HttpsConnectionFilterOptions { ServerCertificate = cert});
+        }
+
+        public static IApplicationBuilder UseKestrelHttps(this IApplicationBuilder app, HttpsConnectionFilterOptions options)
         {
             var serverInfo = app.ServerFeatures.Get<IKestrelServerInformation>();

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Server.Kestrel.Filter;

namespace Microsoft.AspNet.Server.Kestrel.Https
{
    public static class HttpsApplicationBuilderExtensions
    {
        public static IApplicationBuilder UseKestrelHttps(this IApplicationBuilder app, X509Certificate2 cert)
        {
            var serverInfo = app.ServerFeatures.Get<IKestrelServerInformation>();

            if (serverInfo == null)
            {
                return app;
            }

            var prevFilter = serverInfo.ConnectionFilter ?? new NoOpConnectionFilter();

            serverInfo.ConnectionFilter = new HttpsConnectionFilter(cert, prevFilter);

            return app;
        }
    }
}

Should I remove this in favor of the HttpsConnectionFilterOptions overload?


@@ -19,7 +19,7 @@ namespace Nethermind.Blockchain.Synchronization.SyncLimits
     public static class GethSyncLimits
     {
         public const int MaxHeaderFetch = 192; // Amount of block headers to be fetched per retrieval request
-        public const int MaxBodyFetch = 32; // Amount of block bodies to be fetched per retrieval request
+        public const int MaxBodyFetch = 128; // Amount of block bodies to be fetched per retrieval request
         public const int MaxReceiptFetch = 128; // Amount of transaction receipts to allow fetching per request
         public const int MaxCodeFetch = 64; // Amount of contract codes to allow fetching per request
         public const int MaxProofsFetch = 64; // Amount of merkle proofs to be fetched per retrieval request

//  Copyright (c) 2018 Demerzel Solutions Limited
//  This file is part of the Nethermind library.
//
//  The Nethermind library is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  The Nethermind library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.

namespace Nethermind.Blockchain.Synchronization.SyncLimits
{
    public static class GethSyncLimits
    {
        public const int MaxHeaderFetch = 192; // Amount of block headers to be fetched per retrieval request
        public const int MaxBodyFetch = 32; // Amount of block bodies to be fetched per retrieval request
        public const int MaxReceiptFetch = 128; // Amount of transaction receipts to allow fetching per request
        public const int MaxCodeFetch = 64; // Amount of contract codes to allow fetching per request
        public const int MaxProofsFetch = 64; // Amount of merkle proofs to be fetched per retrieval request
        public const int MaxHelperTrieProofsFetch = 64; // Amount of helper tries to be fetched per retrieval request
        public const int MaxTxSend = 64; // Amount of transactions to be send per request
        public const int MaxTxStatus = 256; // Amount of transactions to queried per request
    }
}

check with Geth and this should be fine (incorrectly took the LES setting before)


@@ -7,6 +7,9 @@ namespace Datadog.Trace
     /// </summary>
     public static class CorrelationIdentifier
     {
+        internal static readonly string ServiceKey = "dd.service";
+        internal static readonly string VersionKey = "dd.version";
+        internal static readonly string EnvKey = "dd.env";
         internal static readonly string TraceIdKey = "dd.trace_id";
         internal static readonly string SpanIdKey = "dd.span_id";

using System;

namespace Datadog.Trace
{
    /// <summary>
    /// An API to access the active trace and span ids.
    /// </summary>
    public static class CorrelationIdentifier
    {
        internal static readonly string TraceIdKey = "dd.trace_id";
        internal static readonly string SpanIdKey = "dd.span_id";

        /// <summary>
        /// Gets the trace id
        /// </summary>
        public static ulong TraceId
        {
            get
            {
                return Tracer.Instance.ActiveScope?.Span?.TraceId ?? 0;
            }
        }

        /// <summary>
        /// Gets the span id
        /// </summary>
        public static ulong SpanId
        {
            get
            {
                return Tracer.Instance.ActiveScope?.Span?.SpanId ?? 0;
            }
        }
    }
}

Could rename to `ServiceVersionKey` for consistency with the suggestion to rename the TracerSetting.


@@ -133,7 +133,7 @@ namespace OpenTelemetry.Trace

         private void AddInternal(string key, object value)
         {
-            Guard.Null(key, nameof(key));
+            Debug.Assert(key != null, $"{nameof(key)} must not be null");

             this.Attributes[key] = value;
         }

// <copyright file="SpanAttributes.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using System.Collections.Generic;
using System.Diagnostics;
using OpenTelemetry.Internal;

namespace OpenTelemetry.Trace
{
    /// <summary>
    /// A class that represents the span attributes. Read more here https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/common.md#attributes.
    /// </summary>
    /// <remarks>SpanAttributes is a wrapper around <see cref="ActivityTagsCollection"/> class.</remarks>
    public class SpanAttributes
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SpanAttributes"/> class.
        /// </summary>
        public SpanAttributes()
        {
            this.Attributes = new ActivityTagsCollection();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SpanAttributes"/> class.
        /// </summary>
        /// <param name="attributes">Initial attributes to store in the collection.</param>
        public SpanAttributes(IEnumerable<KeyValuePair<string, object>> attributes)
            : this()
        {
            Guard.Null(attributes, nameof(attributes));

            foreach (KeyValuePair<string, object> kvp in attributes)
            {
                this.AddInternal(kvp.Key, kvp.Value);
            }
        }

        internal ActivityTagsCollection Attributes { get; }

        /// <summary>
        /// Add entry to the attributes.
        /// </summary>
        /// <param name="key">Entry key.</param>
        /// <param name="value">Entry value.</param>
        public void Add(string key, long value)
        {
            this.AddInternal(key, value);
        }

        /// <summary>
        /// Add entry to the attributes.
        /// </summary>
        /// <param name="key">Entry key.</param>
        /// <param name="value">Entry value.</param>
        public void Add(string key, string value)
        {
            this.AddInternal(key, value);
        }

        /// <summary>
        /// Add entry to the attributes.
        /// </summary>
        /// <param name="key">Entry key.</param>
        /// <param name="value">Entry value.</param>
        public void Add(string key, bool value)
        {
            this.AddInternal(key, value);
        }

        /// <summary>
        /// Add entry to the attributes.
        /// </summary>
        /// <param name="key">Entry key.</param>
        /// <param name="value">Entry value.</param>
        public void Add(string key, double value)
        {
            this.AddInternal(key, value);
        }

        /// <summary>
        /// Add entry to the attributes.
        /// </summary>
        /// <param name="key">Entry key.</param>
        /// <param name="values">Entry value.</param>
        public void Add(string key, long[] values)
        {
            this.AddInternal(key, values);
        }

        /// <summary>
        /// Add entry to the attributes.
        /// </summary>
        /// <param name="key">Entry key.</param>
        /// <param name="values">Entry value.</param>
        public void Add(string key, string[] values)
        {
            this.AddInternal(key, values);
        }

        /// <summary>
        /// Add entry to the attributes.
        /// </summary>
        /// <param name="key">Entry key.</param>
        /// <param name="values">Entry value.</param>
        public void Add(string key, bool[] values)
        {
            this.AddInternal(key, values);
        }

        /// <summary>
        /// Add entry to the attributes.
        /// </summary>
        /// <param name="key">Entry key.</param>
        /// <param name="values">Entry value.</param>
        public void Add(string key, double[] values)
        {
            this.AddInternal(key, values);
        }

        private void AddInternal(string key, object value)
        {
            Guard.Null(key, nameof(key));

            this.Attributes[key] = value;
        }
    }
}

I think we have the same problem here - if folks called the `public void Add` with a `null` key, we need to use `Guard`.


@@ -57,14 +57,29 @@ namespace Nethermind.Network.StaticNodes

             string data = await File.ReadAllTextAsync(_staticNodesPath);
             string[] nodes = GetNodes(data);
-            if (_logger.IsInfo) _logger.Info($"Loaded {nodes.Length} static nodes from file: {Path.GetFullPath(_staticNodesPath)}");
+            if (_logger.IsInfo)
+                _logger.Info($"Loaded {nodes.Length} static nodes from file: {Path.GetFullPath(_staticNodesPath)}");
             if (nodes.Length != 0)
             {
                 if (_logger.IsDebug) _logger.Debug($"Static nodes: {Environment.NewLine}{data}");
             }
-
-            _nodes = new ConcurrentDictionary<PublicKey, NetworkNode>(nodes.Select(n => new NetworkNode(n))
-                .ToDictionary(n => n.NodeId, n => n));
+
+            IEnumerable<NetworkNode> networkNodes = new List<NetworkNode>();
+
+            foreach (var n in nodes)
+            {
+                try
+                {
+                    NetworkNode networkNode = new(n);
+                    networkNodes = networkNodes.Append(networkNode);
+                }
+                catch (Exception exception)
+                {
+                    if (_logger.IsError) _logger.Error("Unable to process node. ", exception);
+                }
+            }
+
+            _nodes = new ConcurrentDictionary<PublicKey, NetworkNode>(networkNodes.ToDictionary(n => n.NodeId, n => n));
         }

         private static string[] GetNodes(string data)

//  Copyright (c) 2021 Demerzel Solutions Limited
//  This file is part of the Nethermind library.
//
//  The Nethermind library is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  The Nethermind library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Nethermind.Config;
using Nethermind.Core.Crypto;
using Nethermind.Logging;
using Nethermind.Stats.Model;
using Newtonsoft.Json;

namespace Nethermind.Network.StaticNodes
{
    public class StaticNodesManager : IStaticNodesManager
    {
        private ConcurrentDictionary<PublicKey, NetworkNode> _nodes =
            new ConcurrentDictionary<PublicKey, NetworkNode>();

        private readonly string _staticNodesPath;
        private readonly ILogger _logger;

        public StaticNodesManager(string staticNodesPath, ILogManager logManager)
        {
            _staticNodesPath = staticNodesPath.GetApplicationResourcePath();
            _logger = logManager.GetClassLogger();
        }

        public IEnumerable<NetworkNode> Nodes => _nodes.Values;
        public event EventHandler<NetworkNodeEventArgs> NodeAdded;
        public event EventHandler<NetworkNodeEventArgs> NodeRemoved;

        public async Task InitAsync()
        {
            if (!File.Exists(_staticNodesPath))
            {
                if (_logger.IsDebug) _logger.Debug($"Static nodes file was not found for path: {_staticNodesPath}");

                return;
            }

            string data = await File.ReadAllTextAsync(_staticNodesPath);
            string[] nodes = GetNodes(data);
            if (_logger.IsInfo) _logger.Info($"Loaded {nodes.Length} static nodes from file: {Path.GetFullPath(_staticNodesPath)}");
            if (nodes.Length != 0)
            {
                if (_logger.IsDebug) _logger.Debug($"Static nodes: {Environment.NewLine}{data}");
            }

            _nodes = new ConcurrentDictionary<PublicKey, NetworkNode>(nodes.Select(n => new NetworkNode(n))
                .ToDictionary(n => n.NodeId, n => n));
        }

        private static string[] GetNodes(string data)
        {
            string[] nodes;
            try
            {
                nodes = JsonConvert.DeserializeObject<string[]>(data) ?? Array.Empty<string>();
            }
            catch (JsonException)
            {
                nodes = data.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
            }

            return nodes.Distinct().ToArray();
        }

        public async Task<bool> AddAsync(string enode, bool updateFile = true)
        {
            NetworkNode node = new NetworkNode(enode);
            if (!_nodes.TryAdd(node.NodeId, node))
            {
                if (_logger.IsInfo) _logger.Info($"Static node was already added: {enode}");
                return false;
            }

            if (_logger.IsInfo) _logger.Info($"Static node added: {enode}");
            NodeAdded?.Invoke(this, new NetworkNodeEventArgs(node));
            if (updateFile)
            {
                await SaveFileAsync();
            }

            return true;
        }

        public async Task<bool> RemoveAsync(string enode, bool updateFile = true)
        {
            NetworkNode node = new NetworkNode(enode);
            if (!_nodes.TryRemove(node.NodeId, out _))
            {
                if (_logger.IsInfo) _logger.Info($"Static node was not found: {enode}");
                return false;
            }

            if (_logger.IsInfo) _logger.Info($"Static node was removed: {enode}");
            NodeRemoved?.Invoke(this, new NetworkNodeEventArgs(node));
            if (updateFile)
            {
                await SaveFileAsync();
            }

            return true;
        }

        public bool IsStatic(string enode)
        {
            NetworkNode node = new NetworkNode(enode);
            return _nodes.TryGetValue(node.NodeId, out NetworkNode staticNode) && string.Equals(staticNode.Host, node.Host, StringComparison.InvariantCultureIgnoreCase);
        }

        private Task SaveFileAsync()
            => File.WriteAllTextAsync(_staticNodesPath,
                JsonConvert.SerializeObject(_nodes.Select(n => n.Value.ToString()), Formatting.Indented));
    }
}

Any exception here, not only ArgumentException, SocketException, NetworkException?


@@ -85,6 +85,17 @@ namespace pwiz.Skyline.Model.Databinding.Entities
         [Format(NullValue = TextUtil.EXCEL_NA)]
         public int? PointsAcrossPeak { get { return ChromInfo.PointsAcrossPeak; } }

+        [Format(Formats.RETENTION_TIME, NullValue = TextUtil.EXCEL_NA)]
+        public double? AverageCycleTime
+        {
+            get
+            {
+                return StartTime.HasValue && EndTime.HasValue && PointsAcrossPeak.HasValue
+                    ? (EndTime.Value - StartTime.Value) * 60 / PointsAcrossPeak.Value
+                    : (double?) null;
+            }
+        }
+
         public bool Coeluting { get { return !ChromInfo.IsForcedIntegration; } }

         [Format(Formats.RETENTION_TIME, NullValue = TextUtil.EXCEL_NA)]

/*
 * Original author: Nicholas Shulman <nicksh .at. u.washington.edu>,
 *                  MacCoss Lab, Department of Genome Sciences, UW
 *
 * Copyright 2012 University of Washington - Seattle, WA
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using System.ComponentModel;
using pwiz.Common.DataBinding.Attributes;
using pwiz.Skyline.Model.DocSettings;
using pwiz.Skyline.Model.ElementLocators;
using pwiz.Skyline.Model.Hibernate;
using pwiz.Skyline.Model.Results;
using pwiz.Skyline.Util.Extensions;

namespace pwiz.Skyline.Model.Databinding.Entities
{
    [InvariantDisplayName(nameof(TransitionResult))]
    [AnnotationTarget(AnnotationDef.AnnotationTarget.transition_result)]
    public class TransitionResult : Result
    {
        private readonly CachedValue<TransitionChromInfo> _chromInfo;
        private readonly CachedValue<Chromatogram> _chromatogram;
        public TransitionResult(Transition transition, ResultFile resultFile) : base(transition, resultFile)
        {
            _chromInfo = CachedValue.Create(DataSchema, () => GetResultFile().FindChromInfo(transition.DocNode.Results));
            _chromatogram = CachedValue.Create(DataSchema,
                () => new Chromatogram(new ChromatogramGroup(PrecursorResult), Transition));
        }

        [Browsable(false)]
        public TransitionChromInfo ChromInfo { get { return _chromInfo.Value; } }

        public void ChangeChromInfo(EditDescription editDescription, Func<TransitionChromInfo, TransitionChromInfo> newChromInfo)
        {
            Transition.ChangeDocNode(editDescription, docNode=>docNode.ChangeResults(GetResultFile().ChangeChromInfo(docNode.Results, newChromInfo)));
        }
        [HideWhen(AncestorOfType = typeof(Transition))]
        public Transition Transition { get { return (Transition)SkylineDocNode; } }
        [Format(Formats.RETENTION_TIME, NullValue = TextUtil.EXCEL_NA)]
        public double? RetentionTime { get { return ChromInfo.IsEmpty ? (double?) null : ChromInfo.RetentionTime; } }
        [Format(Formats.RETENTION_TIME, NullValue = TextUtil.EXCEL_NA)]
        public double? Fwhm { get { return ChromInfo.IsEmpty ? (double?) null : ChromInfo.Fwhm; } }
        public bool FwhmDegenerate { get { return ChromInfo.IsFwhmDegenerate; } }
        [Format(Formats.RETENTION_TIME, NullValue = TextUtil.EXCEL_NA)]
        public double? StartTime { get { return ChromInfo.IsEmpty ? (double?)null : ChromInfo.StartRetentionTime; } }
        [Format(Formats.RETENTION_TIME, NullValue = TextUtil.EXCEL_NA)]
        public double? EndTime { get { return ChromInfo.IsEmpty ? (double?) null : ChromInfo.EndRetentionTime; } }
        [Format(Formats.PEAK_AREA, NullValue = TextUtil.EXCEL_NA)]
        public double? Area { get { return ChromInfo.IsEmpty ? (double?) null : ChromInfo.Area; } }
        [Format(Formats.PEAK_AREA, NullValue = TextUtil.EXCEL_NA)]
        public double? Background { get { return ChromInfo.IsEmpty ? (double?)null : ChromInfo.BackgroundArea; } }
        [Format(Formats.STANDARD_RATIO, NullValue = TextUtil.EXCEL_NA)]
        public double? AreaRatio { get { return ChromInfo.Ratio; } }
        [Format(Formats.PEAK_AREA_NORMALIZED, NullValue = TextUtil.EXCEL_NA)]
        public double? AreaNormalized
        {
            get { return Area / GetResultFile().GetTotalArea(Transition.Precursor.IsotopeLabelType); }
        }
        [Format(Formats.PEAK_AREA, NullValue = TextUtil.EXCEL_NA)]
        public double? Height { get { return ChromInfo.IsEmpty ? (double?) null : ChromInfo.Height; } }
        [Format(Formats.MASS_ERROR, NullValue = TextUtil.EXCEL_NA)]
        public double? MassErrorPPM { get { return ChromInfo.MassError; } }
        public bool? Truncated { get { return ChromInfo.IsTruncated; } }
        [Format(NullValue = TextUtil.EXCEL_NA)]
        public int? PeakRank { get { return ChromInfo.IsEmpty ? (int?)null : ChromInfo.Rank; } }
        [Format(NullValue = TextUtil.EXCEL_NA)]
        public int? PeakRankByLevel { get { return ChromInfo.IsEmpty ? (int?)null : ChromInfo.RankByLevel; } }
        public UserSet UserSetPeak { get { return ChromInfo.UserSet; } }
        [Format(NullValue = TextUtil.EXCEL_NA)]
        public int OptStep { get { return ChromInfo.OptimizationStep; } }
        [Format(NullValue = TextUtil.EXCEL_NA)]
        public int? PointsAcrossPeak { get { return ChromInfo.PointsAcrossPeak; } }

        public bool Coeluting { get { return !ChromInfo.IsForcedIntegration; } }

        [Format(Formats.RETENTION_TIME, NullValue = TextUtil.EXCEL_NA)]
        public double? IonMobilityFragment
        {
            get
            {
                return IonMobilityFilter.IsNullOrEmpty(ChromInfo.IonMobility) ? null
                    : ChromInfo.IonMobility.IonMobilityAndCCS.GetHighEnergyIonMobility();
            }
        }

        public Chromatogram Chromatogram
        {
            get { return _chromatogram.Value; }
        }

        [InvariantDisplayName("TransitionReplicateNote")]
        [Importable]
        public string Note
        {
            get { return ChromInfo.Annotations.Note; }
            set
            {
                ChangeChromInfo(EditColumnDescription(nameof(Note), value),
                    chromInfo=>chromInfo.ChangeAnnotations(chromInfo.Annotations.ChangeNote(value)));
            }
        }

        public override void SetAnnotation(AnnotationDef annotationDef, object value)
        {
            ChangeChromInfo(EditDescription.SetAnnotation(annotationDef, value),
                chromInfo=>chromInfo.ChangeAnnotations(chromInfo.Annotations.ChangeAnnotation(annotationDef, value)));
        }

        public override object GetAnnotation(AnnotationDef annotationDef)
        {
            return DataSchema.AnnotationCalculator.GetAnnotation(annotationDef, this, ChromInfo.Annotations);
        }

        [HideWhen(AncestorOfType = typeof(SkylineDocument))]
        public PrecursorResult PrecursorResult
        {
            get
            {
                return new PrecursorResult(Transition.Precursor, GetResultFile());
            }
        }
        public override string ToString()
        {
            return string.Format(@"{0:0}", ChromInfo.Area);
        }

        [InvariantDisplayName("TransitionResultLocator")]
        public string Locator
        {
            get { return GetLocator(); }
        }

        public override ElementRef GetElementRef()
        {
            return TransitionResultRef.PROTOTYPE.ChangeChromInfo(GetResultFile().Replicate.ChromatogramSet, ChromInfo)
                .ChangeParent(Transition.GetElementRef());
        }

        public override bool IsEmpty()
        {
            return ChromInfo.IsEmpty;
        }
    }
}

You can simplify this by doing: return (EndTime - StartTime) * 60 / PointsAcrossPeak;


@@ -34,14 +34,10 @@ namespace OpenTelemetry.Exporter.Jaeger
         private readonly IJaegerUdpBatcher jaegerAgentUdpBatcher;
         private bool disposedValue = false; // To detect redundant dispose calls

-        public JaegerTraceExporter(JaegerExporterOptions options)
+        public JaegerTraceExporter(JaegerExporterOptions options, IJaegerUdpBatcher jaegerAgentUdpBatcher)
         {
             this.ValidateOptions(options);
             this.InitializeOptions(options);
-        }
-
-        public JaegerTraceExporter(IJaegerUdpBatcher jaegerAgentUdpBatcher)
-        {
             this.jaegerAgentUdpBatcher = jaegerAgentUdpBatcher;
         }

// <copyright file="JaegerTraceExporter.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

namespace OpenTelemetry.Exporter.Jaeger
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using OpenTelemetry.Exporter.Jaeger.Implementation;
    using OpenTelemetry.Trace;
    using OpenTelemetry.Trace.Export;

    public class JaegerTraceExporter : SpanExporter, IDisposable
    {
        public const string DefaultAgentUdpHost = "localhost";
        public const int DefaultAgentUdpCompactPort = 6831;
        public const int DefaultMaxPacketSize = 65000;

        private readonly IJaegerUdpBatcher jaegerAgentUdpBatcher;
        private bool disposedValue = false; // To detect redundant dispose calls

        public JaegerTraceExporter(JaegerExporterOptions options)
        {
            this.ValidateOptions(options);
            this.InitializeOptions(options);
        }

        public JaegerTraceExporter(IJaegerUdpBatcher jaegerAgentUdpBatcher)
        {
            this.jaegerAgentUdpBatcher = jaegerAgentUdpBatcher;
        }

        public override async Task<ExportResult> ExportAsync(IEnumerable<Span> otelSpanList, CancellationToken cancellationToken)
        {
            var jaegerspans = otelSpanList.Select(sdl => sdl.ToJaegerSpan());

            foreach (var s in jaegerspans)
            {
                // avoid cancelling here: this is no return point: if we reached this point
                // and cancellation is requested, it's better if we try to finish sending spans rather than drop it
                await this.jaegerAgentUdpBatcher.AppendAsync(s, CancellationToken.None);
            }

            // TODO jaeger status to ExportResult
            return ExportResult.Success;
        }

        public override Task ShutdownAsync(CancellationToken cancellationToken)
        {
            return this.jaegerAgentUdpBatcher.FlushAsync(cancellationToken);
        }

        public void Dispose()
        {
            // Do not change this code. Put cleanup code in Dispose(bool disposing).
            this.Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposedValue)
            {
                if (disposing)
                {
                    this.jaegerAgentUdpBatcher.Dispose();
                }

                this.disposedValue = true;
            }
        }

        private void ValidateOptions(JaegerExporterOptions options)
        {
            if (string.IsNullOrWhiteSpace(options.ServiceName))
            {
                throw new ArgumentException("ServiceName", "Service Name is required.");
            }
        }

        private void InitializeOptions(JaegerExporterOptions options)
        {
            if (string.IsNullOrWhiteSpace(options.AgentHost))
            {
                options.AgentHost = DefaultAgentUdpHost;
            }

            if (!options.AgentPort.HasValue)
            {
                options.AgentPort = DefaultAgentUdpCompactPort;
            }

            if (!options.MaxPacketSize.HasValue)
            {
                options.MaxPacketSize = DefaultMaxPacketSize;
            }
        }
    }
}

Alternatively we can keep the existing constructor and default to use `JaegerUdpBatcher`


@@ -120,10 +120,17 @@ namespace Microsoft.DotNet.Build.CloudTestTasks
                     Log.LogMessage(MessageImportance.Normal, "Received response to check whether Container blobs exist");
                 }
             }
-            await ThreadingTask.WhenAll(Items.Select(item => UploadAsync(ct, item, blobsPresent)));
-
-           Log.LogMessage(MessageImportance.High, "Upload to Azure is complete, a total of {0} items were uploaded.", Items.Length);
+            try
+            {
+                await ThreadingTask.WhenAll(Items.Select(item => UploadAsync(ct, item, blobsPresent)));
+            }
+            catch (Exception)
+            {
+                Log.LogError("Failed to upload to Azure");
+                return false;
+            }

+            Log.LogMessage(MessageImportance.High, "Upload to Azure is complete, a total of {0} items were uploaded.", Items.Length);
             return true;
         }

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Linq;
using System.Net.Http;

using Microsoft.Build.Framework;

using Task = Microsoft.Build.Utilities.Task;
using ThreadingTask = System.Threading.Tasks.Task;

namespace Microsoft.DotNet.Build.CloudTestTasks
{

    public class UploadToAzure : Task, ICancelableTask
    {
        private static readonly CancellationTokenSource TokenSource = new CancellationTokenSource();
        private static readonly CancellationToken CancellationToken = TokenSource.Token;

        /// <summary>
        ///     The Azure account key used when creating the connection string.
        /// </summary>
        [Required]
        public string AccountKey { get; set; }

        /// <summary>
        ///     The Azure account name used when creating the connection string.
        /// </summary>
        [Required]
        public string AccountName { get; set; }

        /// <summary>
        ///     The name of the container to access.  The specified name must be in the correct format, see the
        ///     following page for more info.  https://msdn.microsoft.com/en-us/library/azure/dd135715.aspx
        /// </summary>
        [Required]
        public string ContainerName { get; set; }

        /// <summary>
        ///     An item group of files to upload.  Each item must have metadata RelativeBlobPath
        ///     that specifies the path relative to ContainerName where the item will be uploaded.
        /// </summary>
        [Required]
        public ITaskItem[] Items { get; set; }

        /// <summary>
        ///     Indicates if the destination blob should be overwritten if it already exists.  The default if false.
        /// </summary>
        public bool Overwrite { get; set; } = false;

        public void Cancel()
        {
            TokenSource.Cancel();
        }

        public override bool Execute()
        {
            return ExecuteAsync(CancellationToken).GetAwaiter().GetResult();
        }

        public async Task<bool> ExecuteAsync(CancellationToken ct)
        {
            Log.LogMessage(
                MessageImportance.High,
                "Begin uploading blobs to Azure account {0} in container {1}.",
                AccountName,
                ContainerName);

            if (Items.Length == 0)
            {
                throw new ArgumentException("No items were provided for upload.");
            }

            // first check what blobs are present
            string checkListUrl = string.Format(
                "https://{0}.blob.core.windows.net/{1}?restype=container&comp=list",
                AccountName,
                ContainerName);

            DateTime dt = DateTime.UtcNow;
            HashSet<string> blobsPresent = new HashSet<string>();

            using (HttpClient client = new HttpClient())
            {
                using (HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, checkListUrl))
                {
                    req.Headers.Add(AzureHelper.DateHeaderString, dt.ToString("R", CultureInfo.InvariantCulture));
                    req.Headers.Add(AzureHelper.VersionHeaderString, AzureHelper.StorageApiVersion);
                    req.Headers.Add(AzureHelper.AuthorizationHeaderString, AzureHelper.AuthorizationHeader(
                        AccountName,
                        AccountKey,
                        "GET",
                        dt,
                        req));

                    Log.LogMessage(MessageImportance.Normal, "Sending request to check whether Container blobs exist");
                    XmlDocument doc;
                    using (HttpResponseMessage response = await client.SendAsync(req, ct))
                    {
                        doc = new XmlDocument();
                        doc.LoadXml(await response.Content.ReadAsStringAsync());
                    }

                    XmlNodeList nodes = doc.DocumentElement.GetElementsByTagName("Blob");

                    foreach (XmlNode node in nodes)
                    {
                        blobsPresent.Add(node["Name"].InnerText);
                    }

                    Log.LogMessage(MessageImportance.Normal, "Received response to check whether Container blobs exist");
                }
            }
            await ThreadingTask.WhenAll(Items.Select(item => UploadAsync(ct, item, blobsPresent)));

           Log.LogMessage(MessageImportance.High, "Upload to Azure is complete, a total of {0} items were uploaded.", Items.Length);

            return true;
        }

        private async ThreadingTask UploadAsync(CancellationToken ct, ITaskItem item, HashSet<string> blobsPresent)
        {
            bool result = true;
            if (ct.IsCancellationRequested)
            {
                Log.LogError("Task UploadToAzure cancelled");
                ct.ThrowIfCancellationRequested();
            }

            string relativeBlobPath = item.GetMetadata("RelativeBlobPath");
            if (string.IsNullOrEmpty(relativeBlobPath))
            {
                Log.LogError(string.Format("Metadata 'RelativeBlobPath' is missing for item '{0}'.", item.ItemSpec));
                result = false;
            }

            if (!File.Exists(item.ItemSpec))
            {
                Log.LogError(string.Format("The file '{0}' does not exist.", item.ItemSpec));
                result = false;
            }

            if (!Overwrite && blobsPresent.Contains(relativeBlobPath))
            {
                Log.LogError(string.Format("The blob '{0}' already exists.", relativeBlobPath));
                result = false;
            }

            if (result)
            {
                Log.LogMessage("Uploading {0} to {1}.", item.ItemSpec, ContainerName);
                UploadClient uploadClient = new UploadClient(Log);
                await
                    uploadClient.UploadBlockBlobAsync(
                        ct,
                        AccountName,
                        AccountKey,
                        ContainerName,
                        item.ItemSpec,
                        relativeBlobPath);
            }
        }
    }
}

You can use LogErrorFromException instead :smile: