@@ -24,6 +24,19 @@

 const char h2o_httpclient_error_is_eos[] = "end of stream";
 const char h2o_httpclient_error_refused_stream[] = "refused stream";
+const char h2o_httpclient_error_unknown_alpn_protocol[] = "unknown alpn protocol";
+const char h2o_httpclient_error_io[] = "I/O error";
+const char h2o_httpclient_error_connection_timeout[] = "connection timeout";
+const char h2o_httpclient_error_first_byte_timeout[] = "first byte timeout";
+const char h2o_httpclient_error_io_timeout[] = "I/O timeout";
+const char h2o_httpclient_error_http1_line_folding[] = "line folding of header fields is not supported";
+const char h2o_httpclient_error_http1_unexpected_transfer_encoding[] = "unexpected type of transfer-encoding";
+const char h2o_httpclient_error_http1_invalid_content_length[] = "invalid content-length";
+const char h2o_httpclient_error_http1_parse_failed[] = "failed to parse the response";
+const char h2o_httpclient_error_http2_upstream_protocol[] = "upstream protocol error";
+const char h2o_httpclient_error_http2_goaway_received[] = "GOAWAY received";
+const char h2o_httpclient_error_http2_flow_control_window_overflow[] = "flow control window overflow";
+const char h2o_httpclient_error_internal[] = "internal error";

 void h2o_httpclient_connection_pool_init(h2o_httpclient_connection_pool_t *connpool, h2o_socketpool_t *sockpool)
 {

/*
 * Copyright (c) 2018 Ichito Nagata, Fastly, Inc.
 *
 * 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.
 */

#include "h2o/httpclient.h"

const char h2o_httpclient_error_is_eos[] = "end of stream";
const char h2o_httpclient_error_refused_stream[] = "refused stream";

void h2o_httpclient_connection_pool_init(h2o_httpclient_connection_pool_t *connpool, h2o_socketpool_t *sockpool)
{
    connpool->socketpool = sockpool;
    h2o_linklist_init_anchor(&connpool->http2.conns);
}

static void close_client(h2o_httpclient_t *client)
{
    if (client->_connect_req != NULL) {
        h2o_socketpool_cancel_connect(client->_connect_req);
        client->_connect_req = NULL;
    }

    if (h2o_timer_is_linked(&client->_timeout))
        h2o_timer_unlink(&client->_timeout);

    free(client);
}

static void on_connect_error(h2o_httpclient_t *client, const char *errstr)
{
    assert(errstr != NULL);
    client->_cb.on_connect(client, errstr, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    close_client(client);
}

static void on_connect_timeout(h2o_timer_t *entry)
{
    h2o_httpclient_t *client = H2O_STRUCT_FROM_MEMBER(h2o_httpclient_t, _timeout, entry);
    on_connect_error(client, "connection timeout");
}

static void do_cancel(h2o_httpclient_t *_client)
{
    h2o_httpclient_t *client = (void *)_client;
    close_client(client);
}

static h2o_httpclient_t *create_client(h2o_mem_pool_t *pool, void *data, h2o_httpclient_ctx_t *ctx, h2o_httpclient_connect_cb cb)
{
#define SZ_MAX(x, y) ((x) > (y) ? (x) : (y))
    size_t sz = SZ_MAX(h2o_httpclient__h1_size, h2o_httpclient__h2_size);
#undef SZ_MAX
    h2o_httpclient_t *client = h2o_mem_alloc(sz);
    memset(client, 0, sz);
    client->pool = pool;
    client->ctx = ctx;
    client->data = data;
    client->cancel = do_cancel;
    client->steal_socket = NULL;
    client->get_socket = NULL;
    client->update_window = NULL;
    client->write_req = NULL;
    client->_cb.on_connect = cb;
    client->_timeout.cb = on_connect_timeout;

    return client;
}

static void on_pool_connect(h2o_socket_t *sock, const char *errstr, void *data, h2o_url_t *origin)
{
    h2o_httpclient_t *client = data;

    h2o_timer_unlink(&client->_timeout);

    client->_connect_req = NULL;

    if (sock == NULL) {
        assert(errstr != NULL);
        on_connect_error(client, errstr);
        return;
    }

    h2o_iovec_t alpn_proto;
    if (sock->ssl == NULL || (alpn_proto = h2o_socket_ssl_get_selected_protocol(sock)).len == 0) {
        h2o_httpclient__h1_on_connect(client, sock, origin);
    } else {
        if (h2o_memis(alpn_proto.base, alpn_proto.len, H2O_STRLIT("h2"))) {
            /* detach this socket from the socketpool to count the number of h1 connections correctly */
            h2o_socketpool_detach(client->connpool->socketpool, sock);
            h2o_httpclient__h2_on_connect(client, sock, origin);
        } else if (memcmp(alpn_proto.base, "http/1.1", alpn_proto.len) == 0) {
            h2o_httpclient__h1_on_connect(client, sock, origin);
        } else {
            on_connect_error(client, "unknown alpn protocol");
        }
    }
}

static int should_use_h2(int8_t ratio, int8_t *counter)
{
    /* weighted fair queueing */
    if (*counter < 0)
        *counter = ratio == 0 ? 0 : 50 / ratio; /* set initial counter value */
    int use_h2 = (((int)ratio * *counter) % 100) + ratio >= 100;
    if (++*counter == 100)
        *counter = 0;
    return use_h2;
}

void h2o_httpclient_connect(h2o_httpclient_t **_client, h2o_mem_pool_t *pool, void *data, h2o_httpclient_ctx_t *ctx,
                            h2o_httpclient_connection_pool_t *connpool, h2o_url_t *origin, h2o_httpclient_connect_cb cb)
{
    static const h2o_iovec_t both_protos = {H2O_STRLIT("\x02"
                                                       "h2"
                                                       "\x08"
                                                       "http/1.1")};
    assert(connpool != NULL);
    h2o_iovec_t alpn_protos = h2o_iovec_init(NULL, 0);

    h2o_httpclient_t *client = create_client(pool, data, ctx, cb);
    client->connpool = connpool;
    if (_client != NULL)
        *_client = client;

    client->timings.start_at = h2o_gettimeofday(ctx->loop);

    h2o_httpclient__h2_conn_t *http2_conn = NULL;
    if (!h2o_linklist_is_empty(&connpool->http2.conns)) {
        http2_conn = H2O_STRUCT_FROM_MEMBER(h2o_httpclient__h2_conn_t, link, connpool->http2.conns.next);
        if (http2_conn->num_streams >= h2o_httpclient__h2_get_max_concurrent_streams(http2_conn))
            http2_conn = NULL;
    }

    if (ctx->http2.ratio < 0) {
        /* mix mode */

        if (http2_conn != NULL && connpool->socketpool->_shared.pooled_count != 0) {
            /* both of h1 and h2 connections exist, compare in-use ratio */
            double http1_ratio = (double)(connpool->socketpool->_shared.count - connpool->socketpool->_shared.pooled_count) /
                                 connpool->socketpool->_shared.count;
            double http2_ratio = http2_conn->num_streams / h2o_httpclient__h2_get_max_concurrent_streams(http2_conn);
            if (http2_ratio <= http1_ratio) {
                h2o_httpclient__h2_on_connect(client, http2_conn->sock, &http2_conn->origin_url);
            } else {
                goto UseSocketPool;
            }
        } else if (http2_conn != NULL) {
            /* h2 connection exists */
            h2o_httpclient__h2_on_connect(client, http2_conn->sock, &http2_conn->origin_url);
        } else if (connpool->socketpool->_shared.pooled_count != 0) {
            /* h1 connection exists */
            goto UseSocketPool;
        } else {
            /* no connections, connect using ALPN */
            alpn_protos = both_protos;
            goto UseSocketPool;
        }
    } else {
        /* fixed ratio mode */

        if (should_use_h2(ctx->http2.ratio, &ctx->http2.counter)) {
            if (http2_conn != NULL) {
                h2o_httpclient__h2_on_connect(client, http2_conn->sock, &http2_conn->origin_url);
            } else {
                alpn_protos = both_protos;
                goto UseSocketPool;
            }
        } else {
            goto UseSocketPool;
        }
    }

    return;

UseSocketPool:
    h2o_timer_link(client->ctx->loop, client->ctx->connect_timeout, &client->_timeout);
    h2o_socketpool_connect(&client->_connect_req, connpool->socketpool, origin, ctx->loop, ctx->getaddr_receiver, alpn_protos,
                           on_pool_connect, client);
}

I think that this error is version agnostic, and that therefore "http1" should be omitted. Also, I would appreciate it if you could check what we do for H2, and if the behavior is different between the protocol versions, align them.


@@ -1,6 +1,6 @@
 Summary:        Open Programmable Acceleration Engine (OPAE) SDK
 Name:           opae
-Version:        1.4.0
+Version:        1.4.1
 Release:        1%{?dist}
 License:        BSD
 ExclusiveArch:  x86_64

Summary:        Open Programmable Acceleration Engine (OPAE) SDK
Name:           opae
Version:        1.4.0
Release:        1%{?dist}
License:        BSD
ExclusiveArch:  x86_64

Group:          Development/Libraries
Vendor:         Intel Corporation
Requires:       uuid, json-c, python
URL:            https://github.com/OPAE/%{name}-sdk
Source0:        https://github.com/OPAE/opae-sdk/releases/download/%{version}-1/%{name}.tar.gz

BuildRequires:  gcc, gcc-c++
BuildRequires:  cmake
BuildRequires:  python3-devel
BuildRequires:  json-c-devel
BuildRequires:  libuuid-devel
BuildRequires:  rpm-build
BuildRequires:  hwloc-devel
BuildRequires:  python-sphinx
BuildRequires:  doxygen
BuildRequires:  systemd-rpm-macros
BuildRequires:  systemd

%description
Open Programmable Acceleration Engine (OPAE) is a software framework
for managing and accessing programmable accelerators (FPGAs).
Its main parts are:

* OPAE Software Development Kit (OPAE SDK) (this package)
* OPAE Linux driver for Intel(R) Xeon(R) CPU with
  Integrated FPGAs and Intel(R) PAC with Arria(R) 10 GX FPGA
* Basic Building Block (BBB) library for accelerating AFU

OPAE SDK is a collection of libraries and tools to facilitate the
development of software applications and accelerators using OPAE.
It provides a library implementing the OPAE C API for presenting a
streamlined and easy-to-use interface for software applications to
discover, access, and manage FPGA devices and accelerators using
the OPAE software stack.

%package devel
Summary:    OPAE headers, sample source, and documentation
Requires:   libuuid-devel, %{name}%{?_isa} = %{version}-%{release}

%description devel
OPAE headers, tools, sample source, and documentation

%prep
%setup -q -n %{name}

%build
rm -rf _build
mkdir _build
cd _build

%cmake .. -DCMAKE_INSTALL_PREFIX=/usr

%make_build  opae-c \
         bitstream \
         xfpga \
         safestr \
         modbmc \
         opae-cxx-core \
         hello_cxxcore \
         board_rc \
         board_vc \
         fpgaconf \
         fpgainfo \
         userclk \
         object_api \
         hello_fpga \
         hello_events \
         mmlink

%install
mkdir -p %{buildroot}%{_datadir}/opae
cp RELEASE_NOTES.md %{buildroot}%{_datadir}/opae/RELEASE_NOTES.md
cp LICENSE %{buildroot}%{_datadir}/opae/LICENSE
cp COPYING %{buildroot}%{_datadir}/opae/COPYING

mkdir -p %{buildroot}%{_usr}/src/opae/cmake/modules

for s in FindSphinx.cmake
do
  cp "cmake/${s}" %{buildroot}%{_usr}/src/opae/cmake/
done

mkdir -p %{buildroot}%{_usr}/src/opae/opae-libs/cmake/modules
for s in FindHwloc.cmake \
         OPAE.cmake \
         FindUUID.cmake \
         Findjson-c.cmake \
         OPAECompiler.cmake \
         OPAEGit.cmake \
         OPAEPackaging.cmake
do
  cp "opae-libs/cmake/modules/${s}" %{buildroot}%{_usr}/src/opae/opae-libs/cmake/modules
done

mkdir -p %{buildroot}%{_usr}/src/opae/samples
mkdir -p %{buildroot}%{_usr}/src/opae/samples/hello_fpga/
mkdir -p %{buildroot}%{_usr}/src/opae/samples/hello_events/
mkdir -p %{buildroot}%{_usr}/src/opae/samples/object_api/

cp samples/hello_fpga/hello_fpga.c %{buildroot}%{_usr}/src/opae/samples/hello_fpga/
cp samples/hello_events/hello_events.c %{buildroot}%{_usr}/src/opae/samples/hello_events/
cp samples/object_api/object_api.c %{buildroot}%{_usr}/src/opae/samples/object_api/

cd _build

DESTDIR=%{buildroot}  cmake -DCOMPONENT=safestrlib -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=opaeclib -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=opaecxxcorelib -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=samples -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=opaetoolslibs -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=toolfpgainfo -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=toolfpgaconf -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=tooluserclk -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=toolmmlink -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=samplebin -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=libopaeheaders -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=safestrheaders -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=toolpackager -P cmake_install.cmake
DESTDIR=%{buildroot}  cmake -DCOMPONENT=jsonschema -P cmake_install.cmake

%files
%dir %{_datadir}/opae
%doc %{_datadir}/opae/RELEASE_NOTES.md
%license %{_datadir}/opae/LICENSE
%license %{_datadir}/opae/COPYING
%{_libdir}/libopae-c.so.%{version}
%{_libdir}/libopae-c.so.1
%{_libdir}/libopae-c.so

%{_libdir}/libbitstream.so.%{version}
%{_libdir}/libbitstream.so.1
%{_libdir}/libbitstream.so

%{_libdir}/libopae-cxx-core.so.%{version}
%{_libdir}/libopae-cxx-core.so.1
%{_libdir}/libopae-cxx-core.so

%{_libdir}/opae/libxfpga.so*
%{_libdir}/opae/libmodbmc.so*
%{_libdir}/libsafestr.a*

%files devel
%dir %{_includedir}/opae
%{_includedir}/opae/*
%dir %{_includedir}/safe_string
%{_includedir}/safe_string/safe_string.h
%{_libdir}/libsafestr.a
%dir %{_usr}/src/opae
%{_usr}/src/opae/samples/hello_fpga/hello_fpga.c
%{_usr}/src/opae/samples/hello_events/hello_events.c
%{_usr}/src/opae/samples/object_api/object_api.c
%{_usr}/src/opae/cmake/*
%{_usr}/src/opae/opae-libs/cmake/modules/*

%{_libdir}/opae/libboard_rc.so*
%{_libdir}/opae/libboard_vc.so*

%{_bindir}/fpgaconf
%{_bindir}/fpgainfo
%{_bindir}/mmlink
%{_bindir}/userclk
%{_bindir}/hello_fpga
%{_bindir}/object_api
%{_bindir}/hello_events
%{_bindir}/hello_cxxcore
%{_bindir}/afu_json_mgr
%{_bindir}/packager

%{_usr}/share/opae/*

%changelog
* Tue Dec 17 2019 Korde Nakul <nakul.korde@intel.com> 1.4.0-1
- Added support to FPGA Linux kernel Device Feature List (DFL) driver patch set2.
- Increased test cases and test coverage
- Various bug fixes
- Various compiler warning fixes
- Various memory leak fixes
- Various Static code scan bug fixes
- Added new FPGA MMIO API to write 512 bits

Let's go back to 1.4.0 until the release is being prepared.


@@ -137,6 +137,18 @@ class ClangSA(analyzer_base.SourceAnalyzer):
                                          '-analyzer-disable-checker',
                                          '-Xclang', checker_name])

+            if config.ctu_dir:
+                analyzer_cmd.extend(['-Xclang', '-analyzer-config',
+                                     '-Xclang', 'xtu-dir=' + config.ctu_dir,
+                                     '-Xclang', '-analyzer-config',
+                                     '-Xclang', 'reanalyze-xtu-visited=true'])
+                if config.ctu_in_memory:
+                    analyzer_cmd.extend(['-Xclang', '-analyzer-config',
+                                         '-Xclang',
+                                         'xtu-reparse=' +
+                                         os.path.abspath(config.log_file[0])])
+            # TODO Make it work on multiple logfiles
+
             # Set language.
             analyzer_cmd.extend(['-x', self.buildaction.lang])

# -------------------------------------------------------------------------
#                     The CodeChecker Infrastructure
#   This file is distributed under the University of Illinois Open Source
#   License. See LICENSE.TXT for details.
# -------------------------------------------------------------------------

import os
import re
import shlex
import subprocess

from libcodechecker.analyze.analyzers import analyzer_base
from libcodechecker.logger import LoggerFactory
from libcodechecker.util import find_by_regex_in_envpath

LOG = LoggerFactory.get_new_logger('CLANGSA')

class ClangSA(analyzer_base.SourceAnalyzer):
    """
    Constructs clang static analyzer commands.
    """

    def __parse_checkers(self, clangsa_output):
        """
        Parse clang static analyzer checkers, store them to checkers.
        """

        # Checker name and description in one line.
        pattern = re.compile(
            r'^\s\s(?P<checker_name>\S*)\s*(?P<description>.*)')

        checker_name = None
        for line in clangsa_output.splitlines():
            if re.match(r'^CHECKERS:', line) or line == '':
                continue
            elif checker_name and not re.match(r'^\s\s\S', line):
                # Collect description for the checker name.
                self.checkers.append((checker_name, line.strip()))
                checker_name = None
            elif re.match(r'^\s\s\S+$', line.rstrip()):
                # Only checker name is in the line.
                checker_name = line.strip()
            else:
                # Checker name and description is in one line.
                match = pattern.match(line.rstrip())
                if match:
                    current = match.groupdict()
                    self.checkers.append((current['checker_name'],
                                          current['description']))

    def get_analyzer_checkers(self, config_handler, env):
        """
        Return the list of the supported checkers.
        """
        if not self.checkers:
            analyzer_binary = config_handler.analyzer_binary

            command = [analyzer_binary, "-cc1"]
            for plugin in config_handler.analyzer_plugins:
                command.extend(["-load", plugin])
            command.append("-analyzer-checker-help")

            try:
                command = shlex.split(' '.join(command))
                result = subprocess.check_output(command,
                                                 env=env)
                self.__parse_checkers(result)
            except (subprocess.CalledProcessError, OSError):
                return {}

        return self.checkers

    def construct_analyzer_cmd(self, res_handler):
        """
        Called by the analyzer method.
        Construct the analyzer command.
        """
        try:
            # Get an output file from the result handler.
            analyzer_output_file = res_handler.analyzer_result_file

            # Get the checkers list from the config_handler.
            # Checker order matters.
            config = self.config_handler

            analyzer_cmd = [config.analyzer_binary]

            analyzer_cmd.extend(self.buildaction.compiler_defines)
            analyzer_cmd.extend(self.buildaction.compiler_includes)

            if len(config.compiler_resource_dir) > 0:
                analyzer_cmd.extend(['-resource-dir',
                                     config.compiler_resource_dir,
                                     '-isystem',
                                     config.compiler_resource_dir])

            # Compiling is enough.
            analyzer_cmd.append('-c')

            analyzer_cmd.append('--analyze')

            # Turn off clang hardcoded checkers list.
            analyzer_cmd.append('--analyzer-no-default-checks')

            for plugin in config.analyzer_plugins:
                analyzer_cmd.extend(["-Xclang", "-plugin",
                                     "-Xclang", "checkercfg",
                                     "-Xclang", "-load",
                                     "-Xclang", plugin])

            analyzer_mode = 'plist-multi-file'
            analyzer_cmd.extend(['-Xclang',
                                 '-analyzer-opt-analyze-headers',
                                 '-Xclang',
                                 '-analyzer-output=' + analyzer_mode])

            if config.compiler_sysroot:
                analyzer_cmd.extend(['--sysroot', config.compiler_sysroot])

            for path in config.system_includes:
                analyzer_cmd.extend(['-isystem', path])

            for path in config.includes:
                analyzer_cmd.extend(['-I', path])

            analyzer_cmd.extend(['-o', analyzer_output_file])

            # Config handler stores which checkers are enabled or disabled.
            for checker_name, value in config.checks().items():
                enabled, _ = value
                if enabled:
                    analyzer_cmd.extend(['-Xclang',
                                         '-analyzer-checker=' + checker_name])
                else:
                    analyzer_cmd.extend(['-Xclang',
                                         '-analyzer-disable-checker',
                                         '-Xclang', checker_name])

            # Set language.
            analyzer_cmd.extend(['-x', self.buildaction.lang])

            analyzer_cmd.append(config.analyzer_extra_arguments)

            analyzer_cmd.extend(self.buildaction.analyzer_options)

            analyzer_cmd.append(self.source_file)

            return analyzer_cmd

        except Exception as ex:
            LOG.error(ex)
            return []

    @classmethod
    def resolve_missing_binary(cls, configured_binary, env):
        """
        In case of the configured binary for the analyzer is not found in the
        PATH, this method is used to find a callable binary.
        """

        LOG.debug(configured_binary + " not found in path for ClangSA!")

        if os.path.isabs(configured_binary):
            # Do not autoresolve if the path is an absolute path as there
            # is nothing we could auto-resolve that way.
            return False

        # clang, clang-5.0, clang++, clang++-5.1, ...
        binaries = find_by_regex_in_envpath(
            r'^clang(\+\+)?(-\d+(\.\d+){0,2})?$', env)

        if len(binaries) == 0:
            return False
        elif len(binaries) == 1:
            # Return the first found (earliest in PATH) binary for the only
            # found binary name group.
            return binaries.values()[0][0]
        else:
            # Select the "newest" available clang version if there are multiple
            keys = list(binaries.keys())
            keys.sort()
            files = binaries[keys[-1]]
            return files[-1]

(Note: The analyzer command is constructed for each and every build action separately. Maybe this fact could be used to handle this TODO.)


@@ -93,6 +93,11 @@ xfpga_fpgaOpen(fpga_token token, fpga_handle *handle, int flags)
 	// Init workspace table
 	_handle->wsid_root = NULL;

+	// Init metric enum
+	_handle->metric_enum_status = false;
+	_handle->dl_handle = NULL;
+	_handle->_bmc_metric_value = NULL;
+
 	// Open resources in exclusive mode unless FPGA_OPEN_SHARED is given
 	open_flags = O_RDWR | ((flags & FPGA_OPEN_SHARED) ? 0 : O_EXCL);
 	fddev = open(_token->devpath, open_flags);

// Copyright(c) 2017-2018, Intel Corporation
//
// Redistribution  and  use  in source  and  binary  forms,  with  or  without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of  source code  must retain the  above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name  of Intel Corporation  nor the names of its contributors
//   may be used to  endorse or promote  products derived  from this  software
//   without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H

#include "common_int.h"
#include <opae/access.h>
#include <opae/utils.h>
#include "types_int.h"

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include "safe_string/safe_string.h"

fpga_result __FPGA_API__
xfpga_fpgaOpen(fpga_token token, fpga_handle *handle, int flags)
{
	fpga_result result = FPGA_NOT_FOUND;
	struct _fpga_handle *_handle;
	struct _fpga_token *_token;
	int fddev = -1;
	pthread_mutexattr_t mattr;
	int open_flags = 0;

	if (NULL == token) {
		FPGA_MSG("token is NULL");
		return FPGA_INVALID_PARAM;
	}

	if (NULL == handle) {
		FPGA_MSG("handle is NULL");
		return FPGA_INVALID_PARAM;
	}

	if (flags & ~FPGA_OPEN_SHARED) {
		FPGA_MSG("unrecognized flags");
		return FPGA_INVALID_PARAM;
	}

	_token = (struct _fpga_token *)token;

	if (_token->magic != FPGA_TOKEN_MAGIC) {
		FPGA_MSG("Invalid token");
		return FPGA_INVALID_PARAM;
	}

	_handle = malloc(sizeof(struct _fpga_handle));
	if (NULL == _handle) {
		FPGA_MSG("Failed to allocate memory for handle");
		return FPGA_NO_MEMORY;
	}

	memset_s(_handle, sizeof(*_handle), 0);

	// mark data structure as valid
	_handle->magic = FPGA_HANDLE_MAGIC;

	_handle->token = token;

	_handle->fdfpgad = -1;

	// Init MMIO table
	_handle->mmio_root = NULL;

	// Init workspace table
	_handle->wsid_root = NULL;

	// Open resources in exclusive mode unless FPGA_OPEN_SHARED is given
	open_flags = O_RDWR | ((flags & FPGA_OPEN_SHARED) ? 0 : O_EXCL);
	fddev = open(_token->devpath, open_flags);
	if (-1 == fddev) {
		FPGA_MSG("open(%s) failed: %s", _token->devpath, strerror(errno));
		switch (errno) {
		case EACCES:
			result = FPGA_NO_ACCESS;
			break;
		case EBUSY:
			result = FPGA_BUSY;
			break;
		default:
			result = FPGA_NO_DRIVER;
			break;
		}
		goto out_free;
	}

	// Save the file descriptor for close.
	_handle->fddev = fddev;

	if (pthread_mutexattr_init(&mattr)) {
		FPGA_MSG("Failed to init handle mutex attributes");
		result = FPGA_EXCEPTION;
		goto out_free;
	}

	if (pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE) ||
	    pthread_mutex_init(&_handle->lock, &mattr)) {
		FPGA_MSG("Failed to init handle mutex");
		result = FPGA_EXCEPTION;
		goto out_attr_destroy;
	}

	pthread_mutexattr_destroy(&mattr);

	// set handle return value
	*handle = (void *)_handle;

	return FPGA_OK;

out_attr_destroy:
	pthread_mutexattr_destroy(&mattr);

out_free:
	free(_handle);

	if (-1 != fddev) {
		close(fddev);
	}

	return result;
}

The name dl_handle is too generic. Please rename to reflect its association with metrics.


@@ -15,22 +15,21 @@
 #include <string.h>
 #include "parse.h"

+static tagRegexTable antTagRegexTable [] = {
+	{"^[ \t]*<[ \t]*project[^>]+name=\"([^\"]+)\".*", "\\1",
+	 "p,project,projects", NULL},
+	{"^[ \t]*<[ \t]*target[^>]+name=\"([^\"]+)\".*", "\\1",
+	 "t,target,targets", NULL},
+	{"^[ \t]*<[ \t]*property[^>]+name=\"([^\"]+)\".*", "\\1",
+	 "P,property,property", NULL},
+	{"^[ \t]*<[ \t]*import[^>]+file=\"([^\"]+)\".*", "\\1",
+	 "i,import,imports", NULL}
+};
+
 /*
 *   FUNCTION DEFINITIONS
 */

-static void installAntRegex (const langType language)
-{
-	addTagRegex (language,
-		"^[ \t]*<[ \t]*project[^>]+name=\"([^\"]+)\".*", "\\1", "p,project,projects", NULL);
-	addTagRegex (language,
-		"^[ \t]*<[ \t]*target[^>]+name=\"([^\"]+)\".*", "\\1", "t,target,targets", NULL);
-	addTagRegex (language,
-		"^[ \t]*<[ \t]*property[^>]+name=\"([^\"]+)\".*", "\\1", "P,property,property", NULL);
-	addTagRegex (language,
-		"^[ \t]*<[ \t]*import[^>]+file=\"([^\"]+)\".*", "\\1", "i,import,imports", NULL);
-}
-
 extern parserDefinition* AntParser (void)
 {
 	static const char *const extensions [] = { "build.xml", NULL };

/*
*   Copyright (c) 2008, David Fishburn
*
*   This source code is released for free distribution under the terms of the
*   GNU General Public License version 2 or (at your option) any later version.
*
*   This module contains functions for generating tags for Ant language files.
*/

/*
*   INCLUDE FILES
*/
#include "general.h"  /* must always come first */

#include <string.h>
#include "parse.h"

/*
*   FUNCTION DEFINITIONS
*/

static void installAntRegex (const langType language)
{
	addTagRegex (language,
		"^[ \t]*<[ \t]*project[^>]+name=\"([^\"]+)\".*", "\\1", "p,project,projects", NULL);
	addTagRegex (language,
		"^[ \t]*<[ \t]*target[^>]+name=\"([^\"]+)\".*", "\\1", "t,target,targets", NULL);
	addTagRegex (language,
		"^[ \t]*<[ \t]*property[^>]+name=\"([^\"]+)\".*", "\\1", "P,property,property", NULL);
	addTagRegex (language,
		"^[ \t]*<[ \t]*import[^>]+file=\"([^\"]+)\".*", "\\1", "i,import,imports", NULL);
}

extern parserDefinition* AntParser (void)
{
	static const char *const extensions [] = { "build.xml", NULL };
	static const char *const patterns [] = { "build.xml", NULL };
	parserDefinition* const def = parserNew ("Ant");
	def->extensions = extensions;
	def->patterns = patterns;
	def->initialize = installAntRegex;
	def->method     = METHOD_NOT_CRAFTED|METHOD_REGEX;
	return def;
}

/* vi:set tabstop=4 shiftwidth=4: */

this and other tables should probably be all ~~static~~ const


@@ -10,32 +10,25 @@
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <string.h>
 #include <signal.h>
 #include <inttypes.h>
 #include <stdarg.h>
 #include <unistd.h>
+#include <string.h>
 #include <sys/types.h>
+#include <sys/stat.h>

-ssize_t write(int fd, const void *buf, size_t count) {
-
-	__typeof__(write) *original_write = dlsym(RTLD_NEXT, "write");
-
-	int real_count;
-	int prev_errno = errno;
-	errno = 0;
-	real_count = original_write(fd, buf, count);
-
-	if(real_count < 0 && errno == ENOSPC) {
-		original_write(STDERR_FILENO, "WRITE ERROR: device capacity reached.\n", 39);
-		return real_count;
-	}
-
-	if(!errno) {
-	   errno = prev_errno;
+char *strconcat(char *s1, char *s2)
+{
+    char *result = malloc(strlen(s1)+strlen(s2)+1);
+	if(!result) {
+		return "";
 	}
-
-	return real_count;
+    strcpy(result, s1);
+    strcat(result, s2);
+    return result;
 }

 int open(const char *path, int flags, ...)

#if defined(__linux__) && !defined(_GNU_SOURCE)
#define _GNU_SOURCE // Aaaaaah!!
#endif

#if !defined(RTLD_NEXT)
#define RTLD_NEXT 0
#endif

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <inttypes.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/types.h>

ssize_t write(int fd, const void *buf, size_t count) {

	__typeof__(write) *original_write = dlsym(RTLD_NEXT, "write");

	int real_count;
	int prev_errno = errno;
	errno = 0;
	real_count = original_write(fd, buf, count);

	if(real_count < 0 && errno == ENOSPC) {
		original_write(STDERR_FILENO, "WRITE ERROR: device capacity reached.\n", 39);
		return real_count;
	}

	if(!errno) {
	   errno = prev_errno;
	}

	return real_count;
}

int open(const char *path, int flags, ...)
{

	__typeof__(open) *original_open = dlsym(RTLD_NEXT, "open");

	va_list ap;
	int fd;
	int mode;
	int prev_errno = errno;

	va_start(ap, flags);
	mode = va_arg(ap, int);
	va_end(ap);

	fd = original_open(path, flags, mode);

	if(fd == -1 && errno == ENOSPC) {
		fprintf(stderr, "OPEN ERROR: inode capacity reached.\n");
		return fd;
	}

	if(!errno) {
		errno = prev_errno;
	}

	return fd;
}

Is this correct? It is better to fail than to return an incorrect result.


@@ -93,6 +93,13 @@ def parse_compile_commands_json(logfile, add_compiler_defaults=False):
     counter = 0
     for entry in data:
         sourcefile = entry['file']
+
+        if not os.path.isabs(sourcefile):
+            # Newest versions of intercept-build can create the 'file' in the
+            # JSON Compilation Database as a relative path.
+            sourcefile = os.path.join(os.path.abspath(entry['directory']),
+                                      sourcefile)
+
         lang = option_parser.get_language(sourcefile[sourcefile.rfind('.'):])

         if not lang:

# -------------------------------------------------------------------------
#                     The CodeChecker Infrastructure
#   This file is distributed under the University of Illinois Open Source
#   License. See LICENSE.TXT for details.
# -------------------------------------------------------------------------

import os
import sys
import traceback
import subprocess
import shlex

# TODO: This is a cross-subpackage import!
from libcodechecker.log import build_action
from libcodechecker.log import option_parser
from libcodechecker.logger import LoggerFactory

LOG = LoggerFactory.get_new_logger('LOG PARSER')

# -----------------------------------------------------------------------------
def get_compiler_includes(compiler):
    """
    Returns a list of default includes of the given compiler.
    """
    LOG.debug('getting include paths for  ' + compiler)
    start_mark = "#include <...> search starts here:"
    end_mark = "End of search list."

    cmd = compiler + " -E -x c++ - -v "  # what if not c++?
    include_paths = []
    try:
        proc = subprocess.Popen(shlex.split(cmd),
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)

        out, err = proc.communicate("")

        do_append = False
        for line in err.splitlines(True):
            line = line.strip()
            if line.startswith(end_mark):
                do_append = False
            if do_append:
                include_paths.append("-I"+line)
            if line.startswith(start_mark):
                do_append = True

    except OSError as oerr:
        LOG.error("Cannot find include paths:" + oerr.strerror+"\n")
    return include_paths

# -----------------------------------------------------------------------------
def get_compiler_defines(compiler):
    """
    Returns a list of default defines of the given compiler.
    """
    cmd = compiler + " -dM -E -"
    defines = []
    try:
        with open(os.devnull, 'r') as FNULL:
            proc = subprocess.Popen(shlex.split(cmd),
                                    stdin=FNULL,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            out, err = proc.communicate("")
            for line in out.splitlines(True):
                LOG.debug("define:"+line)
                define = line.strip().split(" ")[1:]
                d = "-D"+define[0] + '=' + '"' + ' '.join(define[1:]) + '"'
                defines.append(d)
    except OSError as oerr:
        LOG.error("Cannot find defines:" + oerr.strerror+"\n")
    return defines

# -----------------------------------------------------------------------------
def parse_compile_commands_json(logfile, add_compiler_defaults=False):
    import json
    LOG.debug('parse_compile_commands_json: ' + str(add_compiler_defaults))

    actions = []
    filtered_build_actions = {}

    logfile.seek(0)
    data = json.load(logfile)

    compiler_defines = {}
    compiler_includes = {}

    counter = 0
    for entry in data:
        sourcefile = entry['file']
        lang = option_parser.get_language(sourcefile[sourcefile.rfind('.'):])

        if not lang:
            continue

        action = build_action.BuildAction(counter)

        command = entry['command']
        results = option_parser.parse_options(command)

        action.original_command = command
        action.analyzer_options = results.compile_opts
        action.lang = results.lang
        action.target = results.arch

        # store the compiler built in include paths
        # and defines
        if add_compiler_defaults and results.compiler:
            if not (results.compiler in compiler_defines):
                compiler_defines[results.compiler] = \
                    get_compiler_defines(results.compiler)
                compiler_includes[results.compiler] = \
                    get_compiler_includes(results.compiler)
            action.compiler_defines = compiler_defines[results.compiler]
            action.compiler_includes = compiler_includes[results.compiler]

        if results.action == option_parser.ActionType.COMPILE or \
           results.action == option_parser.ActionType.LINK:
            action.skip = False

        # TODO: check arch.
        action.directory = entry['directory']
        action.sources = sourcefile
        # Filter out duplicate compilation commands.
        unique_key = action.cmp_key
        if filtered_build_actions.get(unique_key) is None:
            filtered_build_actions[unique_key] = action

        del action
        counter += 1

    for ba_hash, ba in filtered_build_actions.items():
        actions.append(ba)

    return actions

# -----------------------------------------------------------------------------
def parse_log(logfilepath, add_compiler_defaults=False):
    LOG.debug('Parsing log file: ' + logfilepath)
    actions = []

    with open(logfilepath) as logfile:
        try:
            actions = \
                parse_compile_commands_json(logfile, add_compiler_defaults)
        except (ValueError, KeyError, TypeError) as ex:
            if os.stat(logfilepath).st_size == 0:
                LOG.error('The compile database is empty.')
            else:
                LOG.error('The compile database is not valid.')
            LOG.debug(traceback.format_exc())
            LOG.debug(ex)
            sys.exit(1)

    LOG.debug('Parsing log file done.')
    return actions

When the argument list is `["one", "two three"]` then you concatenate it as you do it here, you won't be able to get the original list back with split. You need to annotate the list items better. (Or if you won't do the split by yourself, the called shell will do it. So you need shell escaping. How portable is that?) The main driver to change this in `intercept-build` was to get rid of these concatenation and splitting errors. The current compilation database parser in Clang understands the `arguments` filed... So the question, why don't you pass the command around as a list instead of a string?


@@ -12,6 +12,11 @@ import hashlib

 class BuildAction(object):
+    LINK = 0
+    COMPILE = 1
+    PREPROCESS = 2
+    INFO = 3
+
     def __init__(self, build_action_id=0):
         self._id = build_action_id
         # Filtered list of options.

# -------------------------------------------------------------------------
#                     The CodeChecker Infrastructure
#   This file is distributed under the University of Illinois Open Source
#   License. See LICENSE.TXT for details.
# -------------------------------------------------------------------------
""""""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import hashlib

class BuildAction(object):
    def __init__(self, build_action_id=0):
        self._id = build_action_id
        # Filtered list of options.
        self.analyzer_options = []
        self.compiler_includes = []
        self.analyzer_type = -1
        self._original_command = ''
        self.directory = ''
        self.output = ''
        self.lang = None
        self.target = ''
        self.source_count = 0
        self._sources = []

    def __str__(self):
        # For debugging.
        return ('Id: {0} ,\nOriginal command: {1},\n'
                'Analyzer type: {2},\n Analyzer options: {3},\n'
                'Directory: {4},\nOutput: {5},\nLang: {6},\nTarget: {7},\n'
                'Source count {8},\nSources: {9}'). \
            format(self._id, self._original_command,
                   self.analyzer_type, self.analyzer_options,
                   self.directory, self.output, self.lang, self.target,
                   self.source_count, self._sources)

    @property
    def id(self):
        return self._id

    @property
    def original_command(self):
        return self._original_command

    @property
    def original_command_hash(self):
        hash_object = hashlib.sha1(self._original_command)
        hex_dig = hash_object.hexdigest()
        return hex_dig

    @original_command.setter
    def original_command(self, value):
        self._original_command = value

    @property
    def sources(self):
        for source in self._sources:
            yield source

    @sources.setter
    def sources(self, value):
        self._sources.append(value)
        self.source_count += 1

    def __eq__(self, other):
        return other._original_command == self._original_command

    @property
    def cmp_key(self):
        """
        If the compilation database contains the same compilation action
        multiple times it should be checked only once.
        Use this key to compare compilation commands for the analysis.
        """
        hash_content = []
        hash_content.extend(self.analyzer_options)
        hash_content.append(str(self.analyzer_type))
        hash_content.append(self.target)
        hash_content.extend(self.sources)
        return hashlib.sha1(''.join(hash_content)).hexdigest()

Can't we have build actions that do multiple things? I.e. both compile and link? Is it sufficient to have these constants? Shouldn't they rather be powers of two so we can have a set of purpose for each build action?


@@ -23,17 +23,28 @@
 // win32
 #include <time.h>

+#if defined(__MINGW32__)
+  #include <sys/time.h>
+#endif
+
 #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
 #else
 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
 #endif

+#if !defined(__MINGW32__)
 struct timezone {
   int tz_minuteswest; /* minutes W of Greenwich */
   int tz_dsttime;     /* type of dst correction */
 };
+#endif

+#if defined(__MINGW32__)
+int thrift_gettimeofday(struct timeval* tv, struct timezone* tz) {
+  return gettimeofday(tv,tz);
+}
+#else
 int thrift_gettimeofday(struct timeval* tv, struct timezone* tz) {
   FILETIME ft;
   unsigned __int64 tmpres(0);

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */

#include <thrift/windows/GetTimeOfDay.h>
#include <thrift/thrift-config.h>

// win32
#include <time.h>

#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif

struct timezone {
  int tz_minuteswest; /* minutes W of Greenwich */
  int tz_dsttime;     /* type of dst correction */
};

int thrift_gettimeofday(struct timeval* tv, struct timezone* tz) {
  FILETIME ft;
  unsigned __int64 tmpres(0);
  static int tzflag;

  if (NULL != tv) {
    GetSystemTimeAsFileTime(&ft);

    tmpres |= ft.dwHighDateTime;
    tmpres <<= 32;
    tmpres |= ft.dwLowDateTime;

    /*converting file time to unix epoch*/
    tmpres -= DELTA_EPOCH_IN_MICROSECS;
    tmpres /= 10; /*convert into microseconds*/
    tv->tv_sec = (long)(tmpres / 1000000UL);
    tv->tv_usec = (long)(tmpres % 1000000UL);
  }

  if (NULL != tz) {
    if (!tzflag) {
      _tzset();
      tzflag++;
    }

    long time_zone(0);
    errno_t err(_get_timezone(&time_zone));
    if (err == NO_ERROR) {
      tz->tz_minuteswest = time_zone / 60;
    } else {
      return -1;
    }

    int day_light(0);
    err = (_get_daylight(&day_light));
    if (err == NO_ERROR) {
      tz->tz_dsttime = day_light;
      return 0;
    } else {
      return -1;
    }
  }

  return 0;
}

int thrift_sleep(unsigned int seconds) {
  ::Sleep(seconds * 1000);
  return 0;
}
int thrift_usleep(unsigned int microseconds) {
  unsigned int milliseconds = (microseconds + 999) / 1000;
  ::Sleep(milliseconds);
  return 0;
}

char* thrift_ctime_r(const time_t* _clock, char* _buf) {
  strcpy(_buf, ctime(_clock));
  return _buf;
}

Would you merge this `#if !` to `#else` below ? It seems integral part.


@@ -57,11 +57,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
 	struct roots_wl_shell_surface *roots_surface =
 		wl_container_of(listener, roots_surface, destroy);
 	wl_list_remove(&roots_surface->destroy.link);
-	wl_list_remove(&roots_surface->ping_timeout.link);
 	wl_list_remove(&roots_surface->request_move.link);
 	wl_list_remove(&roots_surface->request_resize.link);
-	wl_list_remove(&roots_surface->request_set_fullscreen.link);
-	wl_list_remove(&roots_surface->request_set_maximized.link);
 	view_destroy(roots_surface->view);
 	free(roots_surface);
 }

#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
#include <wayland-server.h>
#include <wlr/types/wlr_box.h>
#include <wlr/types/wlr_surface.h>
#include <wlr/types/wlr_wl_shell.h>
#include <wlr/util/log.h>
#include "rootston/desktop.h"
#include "rootston/server.h"
#include "rootston/input.h"

static void resize(struct roots_view *view, uint32_t width, uint32_t height) {
	assert(view->type == ROOTS_WL_SHELL_VIEW);
	struct wlr_wl_shell_surface *surf = view->wl_shell_surface;
	wlr_wl_shell_surface_configure(surf, WL_SHELL_SURFACE_RESIZE_NONE, width,
		height);
}

static void close(struct roots_view *view) {
	assert(view->type == ROOTS_WL_SHELL_VIEW);
	struct wlr_wl_shell_surface *surf = view->wl_shell_surface;
	wl_client_destroy(surf->client);
}

static void handle_request_move(struct wl_listener *listener, void *data) {
	struct roots_wl_shell_surface *roots_surface =
		wl_container_of(listener, roots_surface, request_move);
	struct roots_view *view = roots_surface->view;
	struct roots_input *input = view->desktop->server->input;
	struct wlr_wl_shell_surface_move_event *e = data;
	const struct roots_input_event *event = get_input_event(input, e->serial);
	if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) {
		return;
	}
	view_begin_move(input, event->cursor, view);
}

static void handle_request_resize(struct wl_listener *listener, void *data) {
	struct roots_wl_shell_surface *roots_surface =
		wl_container_of(listener, roots_surface, request_resize);
	struct roots_view *view = roots_surface->view;
	struct roots_input *input = view->desktop->server->input;
	struct wlr_wl_shell_surface_resize_event *e = data;
	const struct roots_input_event *event = get_input_event(input, e->serial);
	if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) {
		return;
	}
	view_begin_resize(input, event->cursor, view, e->edges);
}

static void handle_surface_commit(struct wl_listener *listener, void *data) {
	// TODO do we need to do anything here?
}

static void handle_destroy(struct wl_listener *listener, void *data) {
	struct roots_wl_shell_surface *roots_surface =
		wl_container_of(listener, roots_surface, destroy);
	wl_list_remove(&roots_surface->destroy.link);
	wl_list_remove(&roots_surface->ping_timeout.link);
	wl_list_remove(&roots_surface->request_move.link);
	wl_list_remove(&roots_surface->request_resize.link);
	wl_list_remove(&roots_surface->request_set_fullscreen.link);
	wl_list_remove(&roots_surface->request_set_maximized.link);
	view_destroy(roots_surface->view);
	free(roots_surface);
}

static int shell_surface_compare_equals(const void *item, const void *cmp_to) {
	const struct roots_view *view = item;
	if (view->type == ROOTS_WL_SHELL_VIEW && view->wl_shell_surface == cmp_to) {
		return 0;
	}
	return -1;
}

void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
	struct roots_desktop *desktop =
		wl_container_of(listener, desktop, wl_shell_surface);

	struct wlr_wl_shell_surface *surface = data;
	wlr_log(L_DEBUG, "new shell surface: title=%s, class=%s",
		surface->title, surface->class);
	wlr_wl_shell_surface_ping(surface);

	struct roots_wl_shell_surface *roots_surface =
		calloc(1, sizeof(struct roots_wl_shell_surface));
	if (!roots_surface) {
		return;
	}
	wl_list_init(&roots_surface->destroy.link);
	roots_surface->destroy.notify = handle_destroy;
	wl_signal_add(&surface->events.destroy, &roots_surface->destroy);
	wl_list_init(&roots_surface->ping_timeout.link);
	wl_list_init(&roots_surface->request_move.link);
	roots_surface->request_move.notify = handle_request_move;
	wl_signal_add(&surface->events.request_move, &roots_surface->request_move);
	wl_list_init(&roots_surface->request_resize.link);
	roots_surface->request_resize.notify = handle_request_resize;
	wl_signal_add(&surface->events.request_resize,
		&roots_surface->request_resize);
	wl_list_init(&roots_surface->request_set_fullscreen.link);
	wl_list_init(&roots_surface->request_set_maximized.link);
	wl_list_init(&roots_surface->surface_commit.link);
	roots_surface->surface_commit.notify = handle_surface_commit;
	wl_signal_add(&surface->surface->events.commit,
		&roots_surface->surface_commit);

	struct roots_view *view = calloc(1, sizeof(struct roots_view));
	view->type = ROOTS_WL_SHELL_VIEW;

	view->wl_shell_surface = surface;
	view->roots_wl_shell_surface = roots_surface;
	view->wlr_surface = surface->surface;
	view->resize = resize;
	view->close = close;
	view->desktop = desktop;
	roots_surface->view = view;
	list_add(desktop->views, view);
	view_initialize(view);

	if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TRANSIENT) {
		// we need to map it relative to the parent
		int i =
			list_seq_find(desktop->views,
				shell_surface_compare_equals, surface->parent);
		if (i != -1) {
			struct roots_view *parent = desktop->views->items[i];
			view_set_position(view,
				parent->x + surface->transient_state->x,
				parent->y + surface->transient_state->y);
		}
	}
}

Why did these go? You need to remove the listener link to stop listening to the event.


@@ -59,3 +59,37 @@ int h2o_http3_decode_priority_update_frame(h2o_http3_priority_update_frame_t *fr

     return 0;
 }
+
+size_t h2o_http3_goaway_frame_capacity(quicly_stream_id_t stream_or_push_id)
+{
+    return 1   /* type */
+           + 1 /* length field. length should be less than 64, so 1 byte should be enough to represent it */
+           + quicly_encodev_capacity(stream_or_push_id);
+}
+
+uint8_t *h2o_http3_encode_goaway_frame(uint8_t *dst, quicly_stream_id_t stream_or_push_id)
+{
+    *dst++ = H2O_HTTP3_FRAME_TYPE_GOAWAY;                /* type */
+    *dst++ = quicly_encodev_capacity(stream_or_push_id); /* payload length */
+    dst = quicly_encodev(dst, stream_or_push_id);
+
+    return dst;
+}
+
+int h2o_http3_decode_goaway_frame(h2o_http3_goaway_frame_t *frame, const uint8_t *payload, size_t len, const char **err_desc)
+{
+    const uint8_t *src = payload, *end = src + len;
+
+    /* quicly_decodev below will reject len == 0 case */
+    if (len > PTLS_ENCODE_QUICINT_CAPACITY)
+        goto Fail;
+
+    if ((frame->stream_or_push_id = quicly_decodev(&src, end)) == UINT64_MAX)
+        goto Fail;
+
+    return 0;
+
+Fail:
+    *err_desc = "Invalid GOAWAY frame";
+    return H2O_HTTP3_ERROR_FRAME;
+}

/*
 * Copyright (c) 2019 Fastly, Kazuho Oku
 *
 * 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.
 */
#include "h2o/absprio.h"
#include "h2o/http3_common.h"

uint8_t *h2o_http3_encode_priority_update_frame(uint8_t *dst, const h2o_http3_priority_update_frame_t *frame)
{
    *dst++ = H2O_HTTP3_FRAME_TYPE_PRIORITY_UPDATE;
    *dst++ = frame->element_is_push ? 0x80 : 0;
    dst = quicly_encodev(dst, frame->element);
    *dst++ = 'u';
    *dst++ = '=';
    *dst++ = '0' + frame->priority.urgency;
    if (!frame->priority.incremental) {
        static const h2o_iovec_t s = {H2O_STRLIT(",i=1")};
        memcpy(dst, s.base, s.len);
        dst += s.len;
    }
    return dst;
}

int h2o_http3_decode_priority_update_frame(h2o_http3_priority_update_frame_t *frame, const uint8_t *payload, size_t len,
                                           const char **err_desc)
{
    const uint8_t *src = payload, *end = src + len;

    if (src == end)
        return H2O_HTTP3_ERROR_FRAME;
    frame->element_is_push = (*src++ & 0x80) != 0;
    if ((frame->element = quicly_decodev(&src, end)) == UINT64_MAX) {
        *err_desc = "invalid PRIORITY frame";
        return H2O_HTTP3_ERROR_FRAME;
    }
    if (!frame->element_is_push) {
        if (!(quicly_stream_is_client_initiated(frame->element) && !quicly_stream_is_unidirectional(frame->element)))
            return H2O_HTTP3_ERROR_FRAME;
    }
    frame->priority = h2o_absprio_default;
    h2o_absprio_parse_priority((const char *)src, end - src, &frame->priority);

    return 0;
}

I think this error check is insufficient. Consider the case where the given payload was `0100` (len = 2 bytes). This should be considered invalid, as the second byte is a junk. I think the correct thing to do in this function is to assert `src == end` after returning successfully from `quicly_decodev`.


@@ -159,17 +159,17 @@ static struct flb_config_map config_map[] = {
     {
      FLB_CONFIG_MAP_STR, "format", NULL,
      0, FLB_FALSE, 0,
-     NULL
+     "Specifies the data format to be printed. Supported formats are msgpack json, json_lines and json_stream."
     },
     {
      FLB_CONFIG_MAP_STR, "json_date_format", NULL,
      0, FLB_FALSE, 0,
-     NULL
+    "Specifies the name of the date field in output."
     },
     {
      FLB_CONFIG_MAP_STR, "json_date_key", "date",
      0, FLB_TRUE, offsetof(struct flb_stdout, json_date_key),
-     NULL
+    "Specifies the format of the date. Supported formats are double, iso8601 and epoch."
     },

     /* EOF */

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*  Fluent Bit
 *  ==========
 *  Copyright (C) 2019-2020 The Fluent Bit Authors
 *  Copyright (C) 2015-2018 Treasure Data Inc.
 *
 *  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.
 */

#include <fluent-bit/flb_output_plugin.h>
#include <fluent-bit/flb_utils.h>
#include <fluent-bit/flb_slist.h>
#include <fluent-bit/flb_time.h>
#include <fluent-bit/flb_pack.h>
#include <fluent-bit/flb_config_map.h>
#include <msgpack.h>

#include "stdout.h"

static int cb_stdout_init(struct flb_output_instance *ins,
                          struct flb_config *config, void *data)
{
    int ret;
    const char *tmp;
    struct flb_stdout *ctx = NULL;
    (void) ins;
    (void) config;
    (void) data;

    ctx = flb_calloc(1, sizeof(struct flb_stdout));
    if (!ctx) {
        flb_errno();
        return -1;
    }
    ctx->ins = ins;

    ret = flb_output_config_map_set(ins, (void *) ctx);
    if (ret == -1) {
        flb_free(ctx);
        return -1;
    }

    ctx->out_format = FLB_PACK_JSON_FORMAT_NONE;
    tmp = flb_output_get_property("format", ins);
    if (tmp) {
        ret = flb_pack_to_json_format_type(tmp);
        if (ret == -1) {
            flb_plg_error(ctx->ins, "unrecognized 'format' option. "
                          "Using 'msgpack'");
        }
        else {
            ctx->out_format = ret;
        }
    }

    /* Date format for JSON output */
    ctx->json_date_format = FLB_PACK_JSON_DATE_DOUBLE;
    tmp = flb_output_get_property("json_date_format", ins);
    if (tmp) {
        ret = flb_pack_to_json_date_type(tmp);
        if (ret == -1) {
            flb_plg_error(ctx->ins, "invalid json_date_format '%s'. "
                          "Using 'double' type", tmp);
        }
        else {
            ctx->json_date_format = ret;
        }
    }

    /* Export context */
    flb_output_set_context(ins, ctx);

    return 0;
}

static void cb_stdout_flush(const void *data, size_t bytes,
                            const char *tag, int tag_len,
                            struct flb_input_instance *i_ins,
                            void *out_context,
                            struct flb_config *config)
{
    msgpack_unpacked result;
    size_t off = 0, cnt = 0;
    struct flb_stdout *ctx = out_context;
    flb_sds_t json;
    char *buf = NULL;
    (void) i_ins;
    (void) config;
    struct flb_time tmp;
    msgpack_object *p;

    if (ctx->out_format != FLB_PACK_JSON_FORMAT_NONE) {
        json = flb_pack_msgpack_to_json_format(data, bytes,
                                               ctx->out_format,
                                               ctx->json_date_format,
                                               ctx->json_date_key);
        write(STDOUT_FILENO, json, flb_sds_len(json));
        flb_sds_destroy(json);

        /*
         * If we are 'not' in json_lines mode, we need to add an extra
         * breakline.
         */
        if (ctx->out_format != FLB_PACK_JSON_FORMAT_LINES) {
            printf("\n");
        }
        fflush(stdout);
    }
    else {
        /* A tag might not contain a NULL byte */
        buf = flb_malloc(tag_len + 1);
        if (!buf) {
            flb_errno();
            FLB_OUTPUT_RETURN(FLB_RETRY);
        }
        memcpy(buf, tag, tag_len);
        buf[tag_len] = '\0';
        msgpack_unpacked_init(&result);
        while (msgpack_unpack_next(&result, data, bytes, &off) == MSGPACK_UNPACK_SUCCESS) {
            printf("[%zd] %s: [", cnt++, buf);
            flb_time_pop_from_msgpack(&tmp, &result, &p);
            printf("%"PRIu32".%09lu, ", (uint32_t)tmp.tm.tv_sec, tmp.tm.tv_nsec);
            msgpack_object_print(stdout, *p);
            printf("]\n");
        }
        msgpack_unpacked_destroy(&result);
        flb_free(buf);
    }
    fflush(stdout);

    FLB_OUTPUT_RETURN(FLB_OK);
}

static int cb_stdout_exit(void *data, struct flb_config *config)
{
    struct flb_stdout *ctx = data;

    if (!ctx) {
        return 0;
    }

    flb_free(ctx);
    return 0;
}

/* Configuration properties map */
static struct flb_config_map config_map[] = {
    {
     FLB_CONFIG_MAP_STR, "format", NULL,
     0, FLB_FALSE, 0,
     NULL
    },
    {
     FLB_CONFIG_MAP_STR, "json_date_format", NULL,
     0, FLB_FALSE, 0,
     NULL
    },
    {
     FLB_CONFIG_MAP_STR, "json_date_key", "date",
     0, FLB_TRUE, offsetof(struct flb_stdout, json_date_key),
     NULL
    },

    /* EOF */
    {0}
};

/* Plugin registration */
struct flb_output_plugin out_stdout_plugin = {
    .name         = "stdout",
    .description  = "Prints events to STDOUT",
    .cb_init      = cb_stdout_init,
    .cb_flush     = cb_stdout_flush,
    .cb_exit      = cb_stdout_exit,
    .flags        = 0,
    .config_map   = config_map
};

extra space in between "double" and "iso8601"


@@ -77,9 +77,6 @@ struct flb_td *td_config_init(struct flb_output_instance *ins)
             return NULL;
         }
     }
-    else {
-        ctx->region = FLB_TD_REGION_US;
-    }

     flb_plg_info(ctx->ins, "Treasure Data / database='%s' table='%s'",
                  ctx->db_name, ctx->db_table);

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*  Fluent Bit
 *  ==========
 *  Copyright (C) 2019-2020 The Fluent Bit Authors
 *  Copyright (C) 2015-2018 Treasure Data Inc.
 *
 *  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.
 */

#include <fluent-bit/flb_output_plugin.h>
#include "td_config.h"
#include <stdlib.h>

struct flb_td *td_config_init(struct flb_output_instance *ins)
{
    const char *tmp;
    const char *api;
    const char *db_name;
    const char *db_table;
    struct flb_td *ctx;

    /* Validate TD section keys */
    api = flb_output_get_property("API", ins);
    db_name = flb_output_get_property("Database", ins);
    db_table = flb_output_get_property("Table", ins);

    if (!api) {
        flb_plg_error(ins, "error reading API key value");
        return NULL;
    }

    if (!db_name) {
        flb_plg_error(ins, "error reading Database name");
        return NULL;
    }

    if (!db_table) {
        flb_plg_error(ins, "error reading Table name");
        return NULL;
    }

    /* Allocate context */
    ctx = flb_calloc(1, sizeof(struct flb_td));
    if (!ctx) {
        flb_errno();
        return NULL;
    }
    ctx->ins      = ins;
    ctx->fd       = -1;
    ctx->api      = api;
    ctx->db_name  = db_name;
    ctx->db_table = db_table;

    /* Lookup desired region */
    tmp = flb_output_get_property("region", ins);
    if (tmp) {
        if (strcasecmp(tmp, "us") == 0) {
            ctx->region = FLB_TD_REGION_US;
        }
        else if (strcasecmp(tmp, "jp") == 0) {
            ctx->region = FLB_TD_REGION_JP;
        }
        else {
            flb_plg_error(ctx->ins, "invalid region in configuration");
            flb_free(ctx);
            return NULL;
        }
    }
    else {
        ctx->region = FLB_TD_REGION_US;
    }

    flb_plg_info(ctx->ins, "Treasure Data / database='%s' table='%s'",
                 ctx->db_name, ctx->db_table);

    return ctx;
}

If `tmp` is guaranteed not to be `NULL`, whole if statement has to be removed.


@@ -21,5 +21,13 @@

 static CALI_BPF_INLINE int calico_unittest_entry (struct __sk_buff *skb)
 {
-	return vxlan_v4_encap(skb, HOST_IP, 0x02020202);
+	struct cali_tc_ctx ctx = {
+		.state = state_get(),
+		.skb = skb,
+		.fwd = {
+			.res = TC_ACT_UNSPEC,
+			.reason = CALI_REASON_UNKNOWN,
+		},
+	};
+	return vxlan_v4_encap(&ctx, HOST_IP, 0x02020202);
 }

// Project Calico BPF dataplane programs.
// Copyright (c) 2020 Tigera, Inc. All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#include "ut.h"
#include "bpf.h"
#include "nat.h"

static CALI_BPF_INLINE int calico_unittest_entry (struct __sk_buff *skb)
{
	return vxlan_v4_encap(skb, HOST_IP, 0x02020202);
}

Check `.state` here, if it's really needed for the next call?


@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Linq.Expressions;

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using MvvmCross.Platform.Logging;

namespace MvvmCross.Core.Platform.LogProviders
{
    internal sealed class ConsoleLogProvider : MvxBaseLogProvider
    {
        private static readonly Type ConsoleType;
        private static readonly Type ConsoleColorType;
        private static readonly Action<string> ConsoleWriteLine;
        private static readonly Func<int> GetConsoleForeground;
        private static readonly Action<int> SetConsoleForeground;
        private static readonly IDictionary<MvxLogLevel, int> Colors;

        static ConsoleLogProvider()
        {
            ConsoleType = Type.GetType("System.Console");
            ConsoleColorType = ConsoleColorValues.Type;

            if (!IsLoggerAvailable())
            {
                throw new InvalidOperationException("System.Console or System.ConsoleColor type not found");
            }

            MessageFormatter = DefaultMessageFormatter;
            Colors = new Dictionary<MvxLogLevel, int>
            {
                {MvxLogLevel.Fatal, ConsoleColorValues.Red},
                {MvxLogLevel.Error, ConsoleColorValues.Yellow},
                {MvxLogLevel.Warn, ConsoleColorValues.Magenta},
                {MvxLogLevel.Info, ConsoleColorValues.White},
                {MvxLogLevel.Debug, ConsoleColorValues.Gray},
                {MvxLogLevel.Trace, ConsoleColorValues.DarkGray},
            };
            ConsoleWriteLine = GetConsoleWrite();
            GetConsoleForeground = GetGetConsoleForeground();
            SetConsoleForeground = GetSetConsoleForeground();
        }

        internal static bool IsLoggerAvailable()
            => ConsoleType != null && ConsoleColorType != null;

        protected override Logger GetLogger(string name)
            => new ColouredConsoleLogger(name, ConsoleWriteLine, GetConsoleForeground, SetConsoleForeground).Log;

        internal delegate string MessageFormatterDelegate(
            string loggerName,
            MvxLogLevel level,
            object message,
            Exception e);

        internal static MessageFormatterDelegate MessageFormatter { get; set; }

        private static string DefaultMessageFormatter(string loggerName, MvxLogLevel level, object message, Exception e)
        {
            var stringBuilder = new StringBuilder();
            stringBuilder.Append(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture));
            stringBuilder.Append(" ");

            // Append a readable representation of the log level
            stringBuilder.Append(("[" + level.ToString().ToUpper() + "]").PadRight(8));
            stringBuilder.Append("(" + loggerName + ") ");

            // Append the message
            stringBuilder.Append(message);

            // Append stack trace if there is an exception
            if (e != null)
            {
                stringBuilder.Append(Environment.NewLine).Append(e.GetType());
                stringBuilder.Append(Environment.NewLine).Append(e.Message);
                stringBuilder.Append(Environment.NewLine).Append(e.StackTrace);
            }

            return stringBuilder.ToString();
        }

        private static Action<string> GetConsoleWrite()
        {
            var messageParameter = Expression.Parameter(typeof(string), "message");

            MethodInfo writeMethod = ConsoleType.GetMethodPortable("WriteLine", typeof(string));
            var writeExpression = Expression.Call(writeMethod, messageParameter);

            return Expression.Lambda<Action<string>>(
                writeExpression, messageParameter).Compile();
        }

        private static Func<int> GetGetConsoleForeground()
        {
            MethodInfo getForeground = ConsoleType.GetPropertyPortable("ForegroundColor").GetGetMethod();
            var getForegroundExpression = Expression.Convert(Expression.Call(getForeground), typeof(int));

            return Expression.Lambda<Func<int>>(getForegroundExpression).Compile();
        }

        private static Action<int> GetSetConsoleForeground()
        {
            var colorParameter = Expression.Parameter(typeof(int), "color");

            MethodInfo setForeground = ConsoleType.GetPropertyPortable("ForegroundColor").GetSetMethod();
            var setForegroundExpression = Expression.Call(setForeground,
                Expression.Convert(colorParameter, ConsoleColorType));

            return Expression.Lambda<Action<int>>(
                setForegroundExpression, colorParameter).Compile();
        }

        public class ColouredConsoleLogger
        {
            private readonly string _name;
            private readonly Action<string> _write;
            private readonly Func<int> _getForeground;
            private readonly Action<int> _setForeground;

            public ColouredConsoleLogger(string name, Action<string> write,
                Func<int> getForeground, Action<int> setForeground)
            {
                _name = name;
                _write = write;
                _getForeground = getForeground;
                _setForeground = setForeground;
            }

            public bool Log(MvxLogLevel logLevel, Func<string> messageFunc, Exception exception,
                params object[] formatParameters)
            {
                if (messageFunc == null)
                {
                    return true;
                }

                messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters);

                Write(logLevel, messageFunc(), exception);
                return true;
            }

            protected void Write(MvxLogLevel logLevel, string message, Exception e = null)
            {
                var formattedMessage = MessageFormatter(_name, logLevel, message, e);
                int color;

                if (Colors.TryGetValue(logLevel, out color))
                {
                    var originalColor = _getForeground();
                    try
                    {
                        _setForeground(color);
                        _write(formattedMessage);
                    }
                    finally
                    {
                        _setForeground(originalColor);
                    }
                }
                else
                {
                    _write(formattedMessage);
                }
            }
        }

        private static class ConsoleColorValues
        {
            internal static readonly Type Type;
            internal static readonly int Red;
            internal static readonly int Yellow;
            internal static readonly int Magenta;
            internal static readonly int White;
            internal static readonly int Gray;
            internal static readonly int DarkGray;

            static ConsoleColorValues()
            {
                Type = Type.GetType("System.ConsoleColor");
                if (Type == null) return;
                Red = (int)Enum.Parse(Type, "Red", false);
                Yellow = (int)Enum.Parse(Type, "Yellow", false);
                Magenta = (int)Enum.Parse(Type, "Magenta", false);
                White = (int)Enum.Parse(Type, "White", false);
                Gray = (int)Enum.Parse(Type, "Gray", false);
                DarkGray = (int)Enum.Parse(Type, "DarkGray", false);
            }
        }
    }
}

Can we avoid no-change changes being committed - they make it harder to distinguish actual changes from code editor changes


@@ -53,6 +53,17 @@ namespace Examples.AspNet
                         zipkinOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["ZipkinEndpoint"]);
                     });
                     break;
+                case "otlp":
+                    // Adding the OtlpExporter creates a GrpcChannel.
+                    // This switch must be set before creating a GrpcChannel/HttpClient when calling an insecure gRPC service.
+                    // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client
+                    AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
+
+                    builder.AddOtlpExporter(otlpOptions =>
+                        {
+                            otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]);
+                        });
+                    break;
                 default:
                     builder.AddConsoleExporter(options => options.Targets = ConsoleExporterOutputTargets.Debug);
                     break;

// <copyright file="Global.asax.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.Configuration;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using OpenTelemetry;
using OpenTelemetry.Exporter;
using OpenTelemetry.Trace;

namespace Examples.AspNet
{
#pragma warning disable SA1649 // File name should match first type name
    public class WebApiApplication : HttpApplication
#pragma warning restore SA1649 // File name should match first type name
    {
        private IDisposable tracerProvider;

        protected void Application_Start()
        {
            var builder = Sdk.CreateTracerProviderBuilder()
                 .AddAspNetInstrumentation()
                 .AddHttpClientInstrumentation();

            switch (ConfigurationManager.AppSettings["UseExporter"].ToLowerInvariant())
            {
                case "jaeger":
                    builder.AddJaegerExporter(jaegerOptions =>
                     {
                         jaegerOptions.AgentHost = ConfigurationManager.AppSettings["JaegerHost"];
                         jaegerOptions.AgentPort = int.Parse(ConfigurationManager.AppSettings["JaegerPort"]);
                     });
                    break;
                case "zipkin":
                    builder.AddZipkinExporter(zipkinOptions =>
                    {
                        zipkinOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["ZipkinEndpoint"]);
                    });
                    break;
                default:
                    builder.AddConsoleExporter(options => options.Targets = ConsoleExporterOutputTargets.Debug);
                    break;
            }

            this.tracerProvider = builder.Build();

            GlobalConfiguration.Configure(WebApiConfig.Register);

            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }

        protected void Application_End()
        {
            this.tracerProvider?.Dispose();
        }
    }
}


@@ -15,7 +15,21 @@
 //  along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.
 //

+using System;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Nethermind.Blockchain;
+using Nethermind.Core;
+using Nethermind.Core.Crypto;
+using Nethermind.Core.Extensions;
+using Nethermind.Core.Test.Builders;
+using Nethermind.Int256;
+using Nethermind.Logging;
+using Nethermind.Mev.Data;
+using Nethermind.Mev.Execution;
+using Nethermind.Mev.Source;
 using NUnit.Framework;
+using NSubstitute;

 namespace Nethermind.Mev.Test
 {

//  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 NUnit.Framework;

namespace Nethermind.Mev.Test
{
    [TestFixture]
    public class MetricsTests
    {
        [Test]
        public void Can_update_metrics()
        {

        }

        [Test]
        public void Are_described()
        {
            Monitoring.Test.MetricsTests.ValidateMetricsDescriptions();
        }
    }
}

(minor) I think _correctly can be dropped from name


@@ -50,11 +50,11 @@ namespace OpenTelemetry
             return Resource.Empty;
         }

-        public static Func<Batch<Metric>> GetMetricCollect(this BaseProvider baseProvider)
+        public static Action GetCollectObservableInstruments(this BaseProvider baseProvider)
         {
             if (baseProvider is MeterProviderSdk meterProviderSdk)
             {
-                return meterProviderSdk.Collect;
+                return meterProviderSdk.CollectObservableInstruments;
             }

             return null;

// <copyright file="ProviderExtensions.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 OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

namespace OpenTelemetry
{
    /// <summary>
    /// Contains provider extension methods.
    /// </summary>
    public static class ProviderExtensions
    {
        /// <summary>
        /// Gets the <see cref="Resource"/> associated with the <see cref="BaseProvider"/>.
        /// </summary>
        /// <param name="baseProvider"><see cref="BaseProvider"/>.</param>
        /// <returns><see cref="Resource"/>if found otherwise <see cref="Resource.Empty"/>.</returns>
        public static Resource GetResource(this BaseProvider baseProvider)
        {
            if (baseProvider is TracerProviderSdk tracerProviderSdk)
            {
                return tracerProviderSdk.Resource;
            }
            else if (baseProvider is OpenTelemetryLoggerProvider otelLoggerProvider)
            {
                return otelLoggerProvider.Resource;
            }
            else if (baseProvider is MeterProviderSdk meterProviderSdk)
            {
                return meterProviderSdk.Resource;
            }

            return Resource.Empty;
        }

        public static Func<Batch<Metric>> GetMetricCollect(this BaseProvider baseProvider)
        {
            if (baseProvider is MeterProviderSdk meterProviderSdk)
            {
                return meterProviderSdk.Collect;
            }

            return null;
        }

        /// <summary>
        /// Gets the <see cref="Resource"/> associated with the <see cref="BaseProvider"/>.
        /// </summary>
        /// <param name="baseProvider"><see cref="BaseProvider"/>.</param>
        /// <returns><see cref="Resource"/>if found otherwise <see cref="Resource.Empty"/>.</returns>
        public static Resource GetDefaultResource(this BaseProvider baseProvider)
        {
            return ResourceBuilder.CreateDefault().Build();
        }
    }
}

This is changing the public API surface but this was only being called by `MetricReader.OnCollect`.


@@ -35,7 +35,7 @@ namespace Nethermind.TxPool
         void AddPeer(ITxPoolPeer peer);
         void RemovePeer(PublicKey nodeId);
         AddTxResult AddTransaction(Transaction tx, TxHandlingOptions handlingOptions);
-        void RemoveTransaction(Keccak hash, long blockNumber);
+        void RemoveTransaction(Keccak hash, long blockNumber, bool removeSmallerNonces);
         bool TryGetPendingTransaction(Keccak hash, out Transaction transaction);
         UInt256 ReserveOwnTransactionNonce(Address address);
         event EventHandler<TxEventArgs> NewDiscovered;

//  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 Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Int256;

namespace Nethermind.TxPool
{
    public interface ITxPool
    {
        Transaction[] GetPendingTransactions();
        Transaction[] GetOwnPendingTransactions();

        /// <summary>
        /// Grouped by sender address, sorted by nonce and later tx pool sorting
        /// </summary>
        /// <returns></returns>
        IDictionary<Address, Transaction[]> GetPendingTransactionsBySender();
        void AddPeer(ITxPoolPeer peer);
        void RemovePeer(PublicKey nodeId);
        AddTxResult AddTransaction(Transaction tx, TxHandlingOptions handlingOptions);
        void RemoveTransaction(Keccak hash, long blockNumber);
        bool TryGetPendingTransaction(Keccak hash, out Transaction transaction);
        UInt256 ReserveOwnTransactionNonce(Address address);
        event EventHandler<TxEventArgs> NewDiscovered;
        event EventHandler<TxEventArgs> NewPending;
        event EventHandler<TxEventArgs> RemovedPending;
    }
}

void RemoveTransactions(Address sander, long removeBelowThisNonce) and separate these two calls


@@ -83,7 +83,7 @@ namespace Nethermind.Core.Collections
         public static int BinarySearch<TItem>(this IList<TItem> list, TItem value,  IComparer<TItem> comparer) => list.BinarySearch(value, comparer.Compare);

         public static bool TryGetSearchedItem<TComparable>(this IList<TComparable> list, in TComparable activation, out TComparable item) where TComparable : IComparable<TComparable> =>
-            list.TryGetSearchedItem(activation, (b, c) => b.CompareTo(c), out item);
+            list.TryGetSearchedItem(activation, (b, c) => b.CompareTo(c), out item!);

         public static bool TryGetForBlock(this IList<long> list, in long blockNumber, out long item) =>
             list.TryGetSearchedItem(blockNumber, (b, c) => b.CompareTo(c), out item);

//  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.Generic;

namespace Nethermind.Core.Collections
{
    public static class ListExtensions
    {
        public static T? GetItemRoundRobin<T>(this IList<T> array, long index) => array.Count == 0 ? default : array[(int) (index % array.Count)];

        /// <summary>
        /// Performs a binary search on the specified collection.
        /// </summary>
        /// <typeparam name="TItem">The type of the item.</typeparam>
        /// <typeparam name="TSearch">The type of the searched item.</typeparam>
        /// <param name="list">The list to be searched.</param>
        /// <param name="value">The value to search for.</param>
        /// <param name="comparer">The comparer that is used to compare the value
        /// with the list items.</param>
        /// <returns></returns>
        public static int BinarySearch<TItem, TSearch>(this IList<TItem> list, TSearch value, Func<TSearch, TItem, int> comparer)
        {
            if (list is null) throw new ArgumentNullException(nameof(list));
            if (comparer is null) throw new ArgumentNullException(nameof(comparer));

            int lower = 0;
            int upper = list.Count - 1;

            while (lower <= upper)
            {
                int middle = lower + (upper - lower) / 2;
                int comparisonResult = comparer(value, list[middle]);
                if (comparisonResult < 0)
                {
                    upper = middle - 1;
                }
                else if (comparisonResult > 0)
                {
                    lower = middle + 1;
                }
                else
                {
                    return middle;
                }
            }

            return ~lower;
        }

        /// <summary>
        /// Performs a binary search on the specified collection.
        /// </summary>
        /// <typeparam name="TItem">The type of the item.</typeparam>
        /// <param name="list">The list to be searched.</param>
        /// <param name="value">The value to search for.</param>
        /// <returns></returns>
        public static int BinarySearch<TItem>(this IList<TItem> list, TItem value) => BinarySearch(list, value, Comparer<TItem>.Default);

        /// <summary>
        /// Performs a binary search on the specified collection.
        /// </summary>
        /// <typeparam name="TItem">The type of the item.</typeparam>
        /// <param name="list">The list to be searched.</param>
        /// <param name="value">The value to search for.</param>
        /// <param name="comparer">The comparer that is used to compare the value
        /// with the list items.</param>
        /// <returns></returns>
        public static int BinarySearch<TItem>(this IList<TItem> list, TItem value,  IComparer<TItem> comparer) => list.BinarySearch(value, comparer.Compare);

        public static bool TryGetSearchedItem<TComparable>(this IList<TComparable> list, in TComparable activation, out TComparable item) where TComparable : IComparable<TComparable> =>
            list.TryGetSearchedItem(activation, (b, c) => b.CompareTo(c), out item);

        public static bool TryGetForBlock(this IList<long> list, in long blockNumber, out long item) =>
            list.TryGetSearchedItem(blockNumber, (b, c) => b.CompareTo(c), out item);

        public static bool TryGetSearchedItem<T, TComparable>(this IList<T> list, in TComparable searchedItem, Func<TComparable, T, int> comparer, out T? item)
        {
            int index = list.BinarySearch(searchedItem, comparer);
            return TryGetSearchedItem(list, index, out item);
        }

        private static bool TryGetSearchedItem<T>(this IList<T> list, int index, out T? item)
        {
            if (index >= 0)
            {
                item = list[index];
                return true;
            }
            else
            {
                int largerIndex = ~index;
                if (largerIndex != 0)
                {
                    item = list[largerIndex - 1];
                    return true;
                }
                else
                {
                    item = default;
                    return false;
                }
            }
        }
    }
}

the other way around, item can be nulll, so out TComparable? item


@@ -42,5 +42,12 @@ namespace OpenTelemetry.Trace.Export
         /// <param name="cancellationToken">Cancellation token.</param>
         /// <returns>Returns <see cref="Task"/>.</returns>
         public abstract Task ShutdownAsync(CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Flushes all activity objects that have been queued for processing.
+        /// </summary>
+        /// <param name="cancellationToken">Cancellation token.</param>
+        /// <returns>Returns <see cref="Task"/>.</returns>
+        public abstract Task ForceFlushAsync(CancellationToken cancellationToken);
     }
 }

// <copyright file="ActivityProcessor.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.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace OpenTelemetry.Trace.Export
{
    /// <summary>
    /// Activity processor base class.
    /// </summary>
    public abstract class ActivityProcessor
    {
        /// <summary>
        /// Activity start hook.
        /// </summary>
        /// <param name="activity">Instance of activity to process.</param>
        public abstract void OnStart(Activity activity);

        /// <summary>
        /// Activity end hook.
        /// </summary>
        /// <param name="activity">Instance of activity to process.</param>
        public abstract void OnEnd(Activity activity);

        /// <summary>
        /// Shuts down Activity processor asynchronously.
        /// </summary>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>Returns <see cref="Task"/>.</returns>
        public abstract Task ShutdownAsync(CancellationToken cancellationToken);
    }
}

minor: `Export all ended spans to the configured Exporter that have not yet been exported.` - This is the spec description. Lets use something on that line. "queue" is not necessarily present for all processor.


@@ -35,7 +35,7 @@ namespace Examples.AspNet
             this.openTelemetry = Sdk.CreateTracerProviderBuilder()
                  .AddHttpClientInstrumentation()
                  .AddAspNetInstrumentation()
-                 .UseJaegerExporter(c =>
+                 .AddJaegerExporter(c =>
                 {
                     c.AgentHost = "localhost";
                     c.AgentPort = 6831;

// <copyright file="Global.asax.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.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using OpenTelemetry;
using OpenTelemetry.Trace;

namespace Examples.AspNet
{
#pragma warning disable SA1649 // File name should match first type name
    public class WebApiApplication : HttpApplication
#pragma warning restore SA1649 // File name should match first type name
    {
        private IDisposable openTelemetry;

        protected void Application_Start()
        {
            this.openTelemetry = Sdk.CreateTracerProviderBuilder()
                 .AddHttpClientInstrumentation()
                 .AddAspNetInstrumentation()
                 .UseJaegerExporter(c =>
                {
                    c.AgentHost = "localhost";
                    c.AgentPort = 6831;
                })
                 .Build();

            GlobalConfiguration.Configure(WebApiConfig.Register);

            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }

        protected void Application_End()
        {
            this.openTelemetry?.Dispose();
        }
    }
}

One minor suggestion, it seems we've been very inconsistent in the variable name, for example we use `c` here, and in other places we use `o`, `opt`, `options`, `b` - I would vote for changing them all to `options`. BTW, `this.openTelmetry` is another thing we probably want to change - it should be called `tracerProvider`. Not blocking this PR though.


@@ -48,7 +48,7 @@ namespace Nethermind.Api
         IFilterStore? FilterStore { get; set; }
         IFilterManager? FilterManager { get; set; }
         IHeaderValidator? HeaderValidator { get; set; }
-        ITrieStore? ReadOnlyTrieStore { get; set; }
+        ReadOnlyTrieStore? ReadOnlyTrieStore { get; set; }
         IRewardCalculatorSource? RewardCalculatorSource { get; set; }
         ISealer? Sealer { get; set; }
         ISealValidator? SealValidator { get; set; }

//  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/>.
//

#nullable enable
using Nethermind.Blockchain;
using Nethermind.Blockchain.Filters;
using Nethermind.Blockchain.Processing;
using Nethermind.Blockchain.Rewards;
using Nethermind.Blockchain.Validators;
using Nethermind.Config;
using Nethermind.Consensus;
using Nethermind.Core;
using Nethermind.Evm;
using Nethermind.Facade;
using Nethermind.State;
using Nethermind.Trie.Pruning;
using Nethermind.TxPool;

namespace Nethermind.Api
{
    public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory
    {
        (IApiWithStores GetFromApi, IApiWithBlockchain SetInApi) ForInit => (this, this);
        (IApiWithStores GetFromApi, IApiWithBlockchain SetInApi) ForBlockchain => (this, this);
        (IApiWithBlockchain GetFromApi, IApiWithBlockchain SetInApi) ForProducer => (this, this);

        IBlockchainProcessor? BlockchainProcessor { get; set; }
        CompositeBlockPreprocessorStep BlockPreprocessor { get; }
        IBlockProcessingQueue? BlockProcessingQueue { get; set; }
        IBlockProcessor? MainBlockProcessor { get; set; }
        IBlockProducer? BlockProducer { get; set; }
        IBlockValidator? BlockValidator { get; set; }
        IEnode? Enode { get; set; }
        IFilterStore? FilterStore { get; set; }
        IFilterManager? FilterManager { get; set; }
        IHeaderValidator? HeaderValidator { get; set; }
        ITrieStore? ReadOnlyTrieStore { get; set; }
        IRewardCalculatorSource? RewardCalculatorSource { get; set; }
        ISealer? Sealer { get; set; }
        ISealValidator? SealValidator { get; set; }

        /// <summary>
        /// Can be used only for processing blocks, on all other contexts use <see cref="StateReader"/> or <see cref="ChainHeadStateProvider"/>.
        /// </summary>
        /// <remarks>
        /// DO NOT USE OUTSIDE OF PROCESSING BLOCK CONTEXT!
        /// </remarks>
        IStateProvider? StateProvider { get; set; }
        IKeyValueStoreWithBatching? MainStateDbWithCache { get; set; }
        IReadOnlyStateProvider? ChainHeadStateProvider { get; set; }
        IStateReader? StateReader { get; set; }
        IStorageProvider? StorageProvider { get; set; }
        ITransactionProcessor? TransactionProcessor { get; set; }
        ITrieStore? TrieStore { get; set; }
        ITxSender? TxSender { get; set; }
        ITxPool? TxPool { get; set; }
        ITxPoolInfoProvider? TxPoolInfoProvider { get; set; }
        IWitnessCollector? WitnessCollector { get; set; }
        IHealthHintService? HealthHintService { get; set; }
    }
}