Re-namespace `::kv` to `ccf::kv` (#6312)

This commit is contained in:
Eddy Ashton 2024-06-28 15:42:49 +01:00 коммит произвёл GitHub
Родитель da4e643e75
Коммит 45328bf200
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
181 изменённых файлов: 2130 добавлений и 1983 удалений

Просмотреть файл

@ -3,4 +3,4 @@
( V ) / . \ | +---=---'
/--x-m- /--n-n---xXx--/--yY------>>>----<<<>>]]{{}}---||-/\---..
2024__
!..!
!..!!

Просмотреть файл

@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- `::http` is now `ccf::http`
- `::nonstd` is now `ccf::nonstd`
- `::crypto` is now `ccf::crypto`
- `::kv` is now `ccf::kv`
- `::logger` is now `ccf::logger`
- The `programmability` sample app now demonstrates how applications can define their own extensions, creating bindings between C++ and JS state, and allowing JS endpoints to call functions implemented in C++.
- Introduce `DynamicJSEndpointRegistry::record_action_for_audit_v1` and `DynamicJSEndpointRegistry::check_action_not_replayed_v1` to allow an application making use of the programmability feature to easily implement auditability, and protect users allowed to update the application against replay attacks (#6285).

Просмотреть файл

@ -35,21 +35,21 @@ The following table describes the structure of a serialised transaction as it is
+ +------------------------------------------+-------------------------------------------------------------------------+
| | uint64_t | Length of serialised public domain |
+----------+------------------------------------------+-------------------------------------------------------------------------+
| | :cpp:type:`kv::EntryType` | Snapshot, or a WriteSet variant |
| | :cpp:type:`ccf::kv::EntryType` | Snapshot, or a WriteSet variant |
+ +------------------------------------------+-------------------------------------------------------------------------+
| | :cpp:type:`kv::Version` | Transaction version |
| | :cpp:type:`ccf::kv::Version` | Transaction version |
+ +------------------------------------------+-------------------------------------------------------------------------+
| | :cpp:type:`ccf::crypto::Sha256Hash` | User-defined claims digest, when entry type is WriteSetWith.*Claims |
| | :cpp:type:`ccf::crypto::Sha256Hash` | User-defined claims digest, when entry type is WriteSetWith.*Claims |
+ +------------------------------------------+-------------------------------------------------------------------------+
| | :cpp:type:`ccf::crypto::Sha256Hash` | Commit evidence digest, when entry type is WriteSetWithCommitEvidence.* |
| | :cpp:type:`ccf::crypto::Sha256Hash` | Commit evidence digest, when entry type is WriteSetWithCommitEvidence.* |
+ +------------------------------------------+-------------------------------------------------------------------------+
| | :cpp:type:`kv::Version` | Unused, reserved for compatibility |
| | :cpp:type:`ccf::kv::Version` | Unused, reserved for compatibility |
+ +------------------------------------------+-------------------------------------------------------------------------+
| | **Repeating [0..n]** | With ``n`` the number of maps in the transaction |
+ +-----+------------------------------------+-------------------------------------------------------------------------+
| | | std::string | Name of the serialised :cpp:type:`kv::Map` |
| | | std::string | Name of the serialised :cpp:type:`ccf::kv::Map` |
| +-----+------------------------------------+-------------------------------------------------------------------------+
| | | :cpp:type:`kv::Version` | Read version |
| | | :cpp:type:`ccf::kv::Version` | Read version |
| +-----+------------------------------------+-------------------------------------------------------------------------+
| | | uint64_t | Read count |
| | +------------------------------------+-------------------------------------------------------------------------+

Просмотреть файл

@ -19,7 +19,7 @@ The Logging example application simply has:
.. note::
:cpp:type:`kv::Map` tables are the only interface between CCF and the replicated application, and the sole mechanism for it to have distributed state.
:cpp:type:`ccf::kv::Map` tables are the only interface between CCF and the replicated application, and the sole mechanism for it to have distributed state.
The Logging application keeps its state in a pair of tables, one containing private encrypted logs and the other containing public unencrypted logs. Their type is defined as:
@ -54,7 +54,7 @@ The implementation of :cpp:func:`ccfapp::make_user_endpoints()` should return a
:lines: 1
:dedent:
The logging app defines :cpp:class:`ccfapp::LoggerHandlers`, which creates and installs handler functions or lambdas for several different HTTP endpoints. Each of these functions takes as input the details of the current request (such as the URI which was called, the query string, the request body), interacts with the KV tables using the given :cpp:class:`kv::Tx` object, and returns a result:
The logging app defines :cpp:class:`ccfapp::LoggerHandlers`, which creates and installs handler functions or lambdas for several different HTTP endpoints. Each of these functions takes as input the details of the current request (such as the URI which was called, the query string, the request body), interacts with the KV tables using the given :cpp:class:`ccf::kv::Tx` object, and returns a result:
.. literalinclude:: ../../samples/apps/logging/logging.cpp
:language: cpp

Просмотреть файл

@ -3,84 +3,84 @@ Key-Value Store API
This page presents the API that a CCF application must use to access and mutate the replicated key-value store.
A CCF application should store its data in one or more :cpp:type:`kv::Map`. The name, type, and serialisation of these maps is under the application's control. Each invocation of an :cpp:class:`ccf::EndpointRegistry::Endpoint` is given a :cpp:class:`kv::Tx` transaction object, through which it can read and write to its :cpp:type:`kv::Map`.
A CCF application should store its data in one or more :cpp:type:`ccf::kv::Map`. The name, type, and serialisation of these maps is under the application's control. Each invocation of an :cpp:class:`ccf::EndpointRegistry::Endpoint` is given a :cpp:class:`ccf::kv::Tx` transaction object, through which it can read and write to its :cpp:type:`ccf::kv::Map`.
Map
---
.. doxygentypedef:: kv::Version
.. doxygentypedef:: ccf::kv::Version
:project: CCF
.. doxygenvariable:: kv::NoVersion
.. doxygenvariable:: ccf::kv::NoVersion
:project: CCF
.. doxygenclass:: kv::TypedMap
.. doxygenclass:: ccf::kv::TypedMap
:project: CCF
.. doxygentypedef:: kv::Map
.. doxygentypedef:: ccf::kv::Map
:project: CCF
.. doxygenclass:: kv::TypedValue
.. doxygenclass:: ccf::kv::TypedValue
:project: CCF
.. doxygentypedef:: kv::Value
.. doxygentypedef:: ccf::kv::Value
:project: CCF
.. doxygenclass:: kv::TypedSet
.. doxygenclass:: ccf::kv::TypedSet
:project: CCF
.. doxygentypedef:: kv::Set
.. doxygentypedef:: ccf::kv::Set
:project: CCF
Transaction
-----------
.. doxygenclass:: kv::ReadOnlyTx
.. doxygenclass:: ccf::kv::ReadOnlyTx
:project: CCF
:members: ro
.. doxygenclass:: kv::Tx
.. doxygenclass:: ccf::kv::Tx
:project: CCF
:members: rw, wo
Handles
-------
.. doxygenclass:: kv::ReadableMapHandle
.. doxygenclass:: ccf::kv::ReadableMapHandle
:project: CCF
:members:
.. doxygenclass:: kv::WriteableMapHandle
.. doxygenclass:: ccf::kv::WriteableMapHandle
:project: CCF
:members:
.. doxygenclass:: kv::MapHandle
.. doxygenclass:: ccf::kv::MapHandle
:project: CCF
.. doxygenclass:: kv::ReadableValueHandle
.. doxygenclass:: ccf::kv::ReadableValueHandle
:project: CCF
:members:
.. doxygenclass:: kv::WriteableValueHandle
.. doxygenclass:: ccf::kv::WriteableValueHandle
:project: CCF
:members:
.. doxygenclass:: kv::ValueHandle
.. doxygenclass:: ccf::kv::ValueHandle
:project: CCF
.. doxygenclass:: kv::ReadableSetHandle
.. doxygenclass:: ccf::kv::ReadableSetHandle
:project: CCF
:members:
.. doxygenclass:: kv::WriteableSetHandle
.. doxygenclass:: ccf::kv::WriteableSetHandle
:project: CCF
:members:
.. doxygenclass:: kv::SetHandle
.. doxygenclass:: ccf::kv::SetHandle
:project: CCF
Serialisation
-------------
.. doxygenenum:: kv::EntryType
.. doxygenenum:: ccf::kv::EntryType
:project: CCF

Просмотреть файл

@ -1,70 +1,70 @@
Key-Value Store How-To
======================
The `Key-Value Store` (KV) consists of a set of :cpp:type:`kv::Map` objects that are available to the endpoints of an application. Endpoint handlers create handles which allow them to read and write from these :cpp:type:`kv::Map` objects. The framework handles conflicts between concurrent execution of multiple transactions, and produces a consistent order of transactions which is replicated between nodes, allowing the entries to be read from multiple nodes. This page outlines the core concepts and C++ APIs used to interact with the KV.
The `Key-Value Store` (KV) consists of a set of :cpp:type:`ccf::kv::Map` objects that are available to the endpoints of an application. Endpoint handlers create handles which allow them to read and write from these :cpp:type:`ccf::kv::Map` objects. The framework handles conflicts between concurrent execution of multiple transactions, and produces a consistent order of transactions which is replicated between nodes, allowing the entries to be read from multiple nodes. This page outlines the core concepts and C++ APIs used to interact with the KV.
Map Naming
----------
A :cpp:type:`kv::Map` (often referred to as a `Table`) is a collection of key-value pairs of a given type. The :cpp:type:`kv::Map` itself is identified by its name, which is used to lookup the map :cpp:type:`kv::Map` from the local store during a transaction.
A :cpp:type:`ccf::kv::Map` (often referred to as a `Table`) is a collection of key-value pairs of a given type. The :cpp:type:`ccf::kv::Map` itself is identified by its name, which is used to lookup the map :cpp:type:`ccf::kv::Map` from the local store during a transaction.
If a :cpp:type:`kv::Map` with the given name did not previously exist, it will be created in this transaction.
If a :cpp:type:`ccf::kv::Map` with the given name did not previously exist, it will be created in this transaction.
A :cpp:type:`kv::Map` can either be created as private (default) or public. Public map's names begin with a ``public:`` prefix, any any other name indicates a private map. For instance the name ``public:foo`` to a public map, while ``foo`` refers to a private map. Transactions on private maps are written to the ledger in encrypted form and can only be decrypted in the enclave of nodes that have joined the network. Transactions on public maps are written to the ledger as plaintext and can be read from outside the enclave; only their integrity is protected. The security domain of a map (public or private) cannot be changed after its creation, since this is encoded in the map's name. Public and private maps with similar names in different domains are distinct; writes to ``public:foo`` have no impact on ``foo``, and vice versa.
A :cpp:type:`ccf::kv::Map` can either be created as private (default) or public. Public map's names begin with a ``public:`` prefix, any any other name indicates a private map. For instance the name ``public:foo`` to a public map, while ``foo`` refers to a private map. Transactions on private maps are written to the ledger in encrypted form and can only be decrypted in the enclave of nodes that have joined the network. Transactions on public maps are written to the ledger as plaintext and can be read from outside the enclave; only their integrity is protected. The security domain of a map (public or private) cannot be changed after its creation, since this is encoded in the map's name. Public and private maps with similar names in different domains are distinct; writes to ``public:foo`` have no impact on ``foo``, and vice versa.
Some table names are reserved for governance of a CCF service and cannot be modified by application code. For more information, see :doc:`/audit/read_write_restrictions`.
Transaction Semantics
---------------------
A transaction (:cpp:class:`kv::Tx`) encapsulates an individual endpoint invocation's atomic interaction with the KV. Transactions may read from and write to multiple :cpp:type:`kv::Map`, and each is automatically ordered, applied, serialised, and committed by the framework.
A transaction (:cpp:class:`ccf::kv::Tx`) encapsulates an individual endpoint invocation's atomic interaction with the KV. Transactions may read from and write to multiple :cpp:type:`ccf::kv::Map`, and each is automatically ordered, applied, serialised, and committed by the framework.
A reference to a new :cpp:class:`kv::Tx` is passed to each endpoint handler, and used to interact with the KV.
A reference to a new :cpp:class:`ccf::kv::Tx` is passed to each endpoint handler, and used to interact with the KV.
Each :cpp:class:`kv::Tx` gets a consistent, opaque view of the KV, including the values which have been left by previous writes. Any writes produced by this transaction will be visible to all future transactions.
Each :cpp:class:`ccf::kv::Tx` gets a consistent, opaque view of the KV, including the values which have been left by previous writes. Any writes produced by this transaction will be visible to all future transactions.
When the endpoint handler indicates that its :cpp:class:`kv::Tx` should be applied (see :ref:`this section <build_apps/kv/kv_how_to:Applying and reverting writes>` for details), the executing node attempts to apply the changes to its local KV. If this produces conflicts with concurrently executing transactions, it will be automatically re-executed. Once the transaction is applied successfully, it is automatically replicated to other nodes and will, if the network is healthy, eventually be committed.
When the endpoint handler indicates that its :cpp:class:`ccf::kv::Tx` should be applied (see :ref:`this section <build_apps/kv/kv_how_to:Applying and reverting writes>` for details), the executing node attempts to apply the changes to its local KV. If this produces conflicts with concurrently executing transactions, it will be automatically re-executed. Once the transaction is applied successfully, it is automatically replicated to other nodes and will, if the network is healthy, eventually be committed.
For each :cpp:type:`kv::Map` that a transaction wants to write to or read from, a :cpp:class:`kv::MapHandle` must first be acquired. These are acquired from the :cpp:func:`kv::Tx::rw` (`read-write`) method. These may be acquired either by name (in which case the desired type must be explicitly specified as a template parameter), or by using a :cpp:type:`kv::Map` instance which defines both the map's name and key-value types.
For each :cpp:type:`ccf::kv::Map` that a transaction wants to write to or read from, a :cpp:class:`ccf::kv::MapHandle` must first be acquired. These are acquired from the :cpp:func:`ccf::kv::Tx::rw` (`read-write`) method. These may be acquired either by name (in which case the desired type must be explicitly specified as a template parameter), or by using a :cpp:type:`ccf::kv::Map` instance which defines both the map's name and key-value types.
By name:
.. code-block:: cpp
// Handle for map1
auto map1_handle = tx.rw<kv::Map<string, string>>("map1");
auto map1_handle = tx.rw<ccf::kv::Map<string, string>>("map1");
// Handles for 2 other maps, one public and one private, with different types
auto map2_handle = tx.rw<kv::Map<string, uint64_t>>("public:map2");
auto map3_handle = tx.rw<kv::Map<uint64_t, MyCustomClass>>("map3");
auto map2_handle = tx.rw<ccf::kv::Map<string, uint64_t>>("public:map2");
auto map3_handle = tx.rw<ccf::kv::Map<uint64_t, MyCustomClass>>("map3");
By :cpp:type:`kv::Map`:
By :cpp:type:`ccf::kv::Map`:
.. code-block:: cpp
kv::Map<string, string> map_priv("map1");
ccf::kv::Map<string, string> map_priv("map1");
auto map1_handle = tx.rw(map_priv);
kv::Map<string, uint64_t> map_pub("public:map2");
ccf::kv::Map<string, uint64_t> map_pub("public:map2");
auto map2_handle = tx.rw(map_pub);
kv::Map<uint64_t, MyCustomClass> map_priv_int("map3");
ccf::kv::Map<uint64_t, MyCustomClass> map_priv_int("map3");
auto map3_handle = tx.rw(map_priv_int);
The latter approach introduces a named binding between the map's name and the types of its keys and values, reducing the chance for errors where code attempts to read a map with the wrong type.
.. note:: As mentioned above, there is no need to explicitly declare a :cpp:type:`kv::Map` before it is used. The first write to a :cpp:type:`kv::Map` implicitly creates it in the underlying KV. Within a transaction, a newly created :cpp:type:`kv::Map` behaves exactly the same as an existing :cpp:type:`kv::Map` with no keys - the framework views these as semantically identical, and offers no way for the application logic to tell them apart. Any writes to a newly created :cpp:type:`kv::Map` will be persisted when the transaction commits, and future transactions will be able to access this :cpp:type:`kv::Map` by name to read those writes.
.. note:: As mentioned above, there is no need to explicitly declare a :cpp:type:`ccf::kv::Map` before it is used. The first write to a :cpp:type:`ccf::kv::Map` implicitly creates it in the underlying KV. Within a transaction, a newly created :cpp:type:`ccf::kv::Map` behaves exactly the same as an existing :cpp:type:`ccf::kv::Map` with no keys - the framework views these as semantically identical, and offers no way for the application logic to tell them apart. Any writes to a newly created :cpp:type:`ccf::kv::Map` will be persisted when the transaction commits, and future transactions will be able to access this :cpp:type:`ccf::kv::Map` by name to read those writes.
Accessing Map content via a Handle
----------------------------------
Once a :cpp:class:`kv::MapHandle` on a specific :cpp:type:`kv::Map` has been obtained, it is possible to:
Once a :cpp:class:`ccf::kv::MapHandle` on a specific :cpp:type:`ccf::kv::Map` has been obtained, it is possible to:
- test (:cpp:func:`kv::ReadableMapHandle::has`) whether a key has any associated value;
- read (:cpp:func:`kv::ReadableMapHandle::get`) the value associated with a key;
- write (:cpp:func:`kv::WriteableMapHandle::put`) a new value for a key;
- delete (:cpp:func:`kv::WriteableMapHandle::remove`) a key and its current value;
- iterate (:cpp:func:`kv::ReadableMapHandle::foreach`) through all key-value pairs.
- test (:cpp:func:`ccf::kv::ReadableMapHandle::has`) whether a key has any associated value;
- read (:cpp:func:`ccf::kv::ReadableMapHandle::get`) the value associated with a key;
- write (:cpp:func:`ccf::kv::WriteableMapHandle::put`) a new value for a key;
- delete (:cpp:func:`ccf::kv::WriteableMapHandle::remove`) a key and its current value;
- iterate (:cpp:func:`ccf::kv::ReadableMapHandle::foreach`) through all key-value pairs.
.. code-block:: cpp
@ -91,7 +91,7 @@ Once a :cpp:class:`kv::MapHandle` on a specific :cpp:type:`kv::Map` has been obt
Read/Write safety
-----------------
If you are only reading from or only writing to a given :cpp:type:`kv::Map` you can retrieve a `read-only` or `write-only` handle for it. This will turn unexpected reads/writes (which would introduce unintended dependencies between transactions) into compile-time errors. Instead of calling :cpp:func:`kv::Tx::rw` to get a handle which can both read and write, you can call :cpp:func:`kv::ReadOnlyTx::ro` to acquire a `read-only` handle or :cpp:func:`kv::Tx::wo` to acquire a `write-only` handle.
If you are only reading from or only writing to a given :cpp:type:`ccf::kv::Map` you can retrieve a `read-only` or `write-only` handle for it. This will turn unexpected reads/writes (which would introduce unintended dependencies between transactions) into compile-time errors. Instead of calling :cpp:func:`ccf::kv::Tx::rw` to get a handle which can both read and write, you can call :cpp:func:`ccf::kv::ReadOnlyTx::ro` to acquire a `read-only` handle or :cpp:func:`ccf::kv::Tx::wo` to acquire a `write-only` handle.
.. code-block:: cpp
@ -122,7 +122,7 @@ Note that, as in the sample above, it is possible to acquire different kinds of
Removing a key
--------------
If a Key-Value pair was written to a :cpp:type:`kv::Map` by a previous :cpp:class:`kv::Tx`, it is possible to delete this key. Because of the append-only nature of the KV, this Key-Value pair is not actually removed from the :cpp:type:`kv::Map` but instead explicitly marked as deleted in the version that the deleting :cpp:class:`kv::Tx` is applied at.
If a Key-Value pair was written to a :cpp:type:`ccf::kv::Map` by a previous :cpp:class:`ccf::kv::Tx`, it is possible to delete this key. Because of the append-only nature of the KV, this Key-Value pair is not actually removed from the :cpp:type:`ccf::kv::Map` but instead explicitly marked as deleted in the version that the deleting :cpp:class:`ccf::kv::Tx` is applied at.
.. code-block:: cpp
@ -141,7 +141,7 @@ Global commit
A transaction is automatically (globally) committed once the consensus protocol has established that a majority of nodes in the CCF network have successfully received and acknowledged that transaction. To operate on durable state, an application may want to query the globally committed state rather than the *current* state of the KV.
The :cpp:func:`kv::MapHandle::get_globally_committed` member function returns the value of a key that we know has been globally committed.
The :cpp:func:`ccf::kv::MapHandle::get_globally_committed` member function returns the value of a key that we know has been globally committed.
.. code-block:: cpp
@ -166,9 +166,9 @@ Miscellaneous
``foreach()``
~~~~~~~~~~~~~
Values can only be retrieved directly (:cpp:func:`kv::MapHandle::get`) for a given target key. However, it is sometimes necessary to access unknown keys, or to iterate through all Key-Value pairs.
Values can only be retrieved directly (:cpp:func:`ccf::kv::MapHandle::get`) for a given target key. However, it is sometimes necessary to access unknown keys, or to iterate through all Key-Value pairs.
CCF offers a member function :cpp:func:`kv::MapHandle::foreach` to iterate over all the elements written to that :cpp:type:`kv::Map` so far, and run a lambda function for each Key-Value pair. Note that a :cpp:class:`kv::MapHandle::foreach` loop can be ended early by returning ``false`` from this lambda, while ``true`` should be returned to continue iteration.
CCF offers a member function :cpp:func:`ccf::kv::MapHandle::foreach` to iterate over all the elements written to that :cpp:type:`ccf::kv::Map` so far, and run a lambda function for each Key-Value pair. Note that a :cpp:class:`ccf::kv::MapHandle::foreach` loop can be ended early by returning ``false`` from this lambda, while ``true`` should be returned to continue iteration.
.. code-block:: cpp
@ -192,7 +192,7 @@ CCF offers a member function :cpp:func:`kv::MapHandle::foreach` to iterate over
Applying and reverting writes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Changes to the KV are made by atomic transactions. For a given :cpp:class:`kv::Tx`, either all of its writes are applied, or none are. Only applied writes are replicated and may be globally committed. Transactions may be abandoned without applying their writes - their changes will never be seen by other transactions.
Changes to the KV are made by atomic transactions. For a given :cpp:class:`ccf::kv::Tx`, either all of its writes are applied, or none are. Only applied writes are replicated and may be globally committed. Transactions may be abandoned without applying their writes - their changes will never be seen by other transactions.
By default CCF decides which transactions are successful (so should be applied to the persistent store) by looking at the status code contained in the response: all transactions producing ``2xx`` status codes will be applied, while any other status code will be treated as an error and will `not` be applied to the persistent store. If this behaviour is not desired, for instance when an app wants to log incoming requests even though they produce an error, then it can be dynamically overridden by explicitly telling CCF whether it should apply a given transaction:

Просмотреть файл

@ -1,14 +1,14 @@
Key-Value Serialisation
=======================
Every transaction executed by the primary on its Key-Value store is serialised before being replicated to all backups of the CCF network and written to the ledger. The serialisation format is defined per :cpp:type:`kv::Map` and distinctly for the key and value types.
Every transaction executed by the primary on its Key-Value store is serialised before being replicated to all backups of the CCF network and written to the ledger. The serialisation format is defined per :cpp:type:`ccf::kv::Map` and distinctly for the key and value types.
.. tip:: Selecting the right serialision format for a KV map depends on the application logic but is generally a trade-off between performance and auditability of the ledger. For example, the default serialisation format for :cpp:type:`kv::Map` is JSON and allows for easy parsing of transactions in the `public` ledger. For more performance sensitive use cases, apps may define or use their own serialisers.
.. tip:: Selecting the right serialision format for a KV map depends on the application logic but is generally a trade-off between performance and auditability of the ledger. For example, the default serialisation format for :cpp:type:`ccf::kv::Map` is JSON and allows for easy parsing of transactions in the `public` ledger. For more performance sensitive use cases, apps may define or use their own serialisers.
Custom key and value types
--------------------------
User-defined types can be used for both the key and value types of a :cpp:type:`kv::Map`. It must be possible to use the key type as the key of an ``std::map`` (so it must be copyable, assignable, and less-comparable), and both types must be serialisable. By default, when using a :cpp:type:`kv::Map`, serialisation converts to JSON. To add support to your custom types, it should usually be possible to use the ``DECLARE_JSON_...`` macros:
User-defined types can be used for both the key and value types of a :cpp:type:`ccf::kv::Map`. It must be possible to use the key type as the key of an ``std::map`` (so it must be copyable, assignable, and less-comparable), and both types must be serialisable. By default, when using a :cpp:type:`ccf::kv::Map`, serialisation converts to JSON. To add support to your custom types, it should usually be possible to use the ``DECLARE_JSON_...`` macros:
.. literalinclude:: ../../../src/kv/test/kv_serialisation.cpp
:language: cpp
@ -22,7 +22,7 @@ Custom serialisers can also be defined. The serialiser itself must be a type imp
:start-after: SNIPPET_START: CustomSerialiser definition
:end-before: SNIPPET_END: CustomSerialiser definition
To use these serialised for a specific map declare the map as a :cpp:class:`kv::TypedMap`, adding the appropriate serialiser types for the key and value types:
To use these serialised for a specific map declare the map as a :cpp:class:`ccf::kv::TypedMap`, adding the appropriate serialiser types for the key and value types:
.. literalinclude:: ../../../src/kv/test/kv_serialisation.cpp
:language: cpp

Просмотреть файл

@ -79,7 +79,7 @@ Glossary
`Transport Layer Security <https://en.wikipedia.org/wiki/Transport_Layer_Security>`_ is an IETF cryptographic protocol standard designed to secure communications between a client and a server over a computer network.
Transaction ID
Unique transaction identifier in CCF, composed of a View and a Sequence Number separated by a period. Sequence Numbers start from 1, and are contiguous. Views are monotonic. E.g. The transaction ID ``2.15`` indicates the View is ``2`` and the Sequence Number is ``15``. Sequence Numbers are also referred to as a :cpp:type:`kv::Version` in the context of the Key-Value store.
Unique transaction identifier in CCF, composed of a View and a Sequence Number separated by a period. Sequence Numbers start from 1, and are contiguous. Views are monotonic. E.g. The transaction ID ``2.15`` indicates the View is ``2`` and the Sequence Number is ``15``. Sequence Numbers are also referred to as a :cpp:type:`ccf::kv::Version` in the context of the Key-Value store.
Users
Directly interact with the application running in CCF. Their public identity should be voted in by members before they are allowed to issue requests.

Просмотреть файл

@ -17,7 +17,7 @@ namespace ccf
class RpcFrontend;
}
namespace kv
namespace ccf::kv
{
class Store;
}

Просмотреть файл

@ -188,7 +188,7 @@ namespace ccf
* does not affect the OpenAPI version of the format of the document.
*/
ApiResult generate_openapi_document_v1(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::string& title,
const std::string& description,
const std::string& document_version,
@ -197,7 +197,7 @@ namespace ccf
/** Get a quote attesting to the hardware this node is running on.
*/
ApiResult get_quote_for_this_node_v1(
kv::ReadOnlyTx& tx, QuoteInfo& quote_info);
ccf::kv::ReadOnlyTx& tx, QuoteInfo& quote_info);
/** Get the id of the currently executing node.
*/
@ -207,7 +207,7 @@ namespace ccf
* running on.
*/
ApiResult get_quotes_for_all_trusted_nodes_v1(
kv::ReadOnlyTx& tx, std::map<NodeId, QuoteInfo>& quotes);
ccf::kv::ReadOnlyTx& tx, std::map<NodeId, QuoteInfo>& quotes);
/** Get the view associated with a given seqno, to construct a valid TxID.
*/
@ -216,26 +216,28 @@ namespace ccf
/** Get the user data associated with a given user id.
*/
ApiResult get_user_data_v1(
kv::ReadOnlyTx& tx, const UserId& user_id, nlohmann::json& user_data);
ccf::kv::ReadOnlyTx& tx,
const UserId& user_id,
nlohmann::json& user_data);
/** Get the member data associated with a given member id.
*/
ApiResult get_member_data_v1(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const MemberId& member_id,
nlohmann::json& member_data);
/** Get the certificate (PEM) of a given user id.
*/
ApiResult get_user_cert_v1(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const UserId& user_id,
ccf::crypto::Pem& user_cert_pem);
/** Get the certificate (PEM) of a given member id.
*/
ApiResult get_member_cert_v1(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const MemberId& member_id,
ccf::crypto::Pem& member_cert_pem);

Просмотреть файл

@ -76,7 +76,7 @@ struct formatter<ccf::crypto::Sha256Hash>
};
FMT_END_NAMESPACE
namespace kv::serialisers
namespace ccf::kv::serialisers
{
template <>
struct BlitSerialiser<ccf::crypto::Sha256Hash>

Просмотреть файл

@ -30,7 +30,7 @@ namespace ccf::endpoints
};
}
namespace kv::serialisers
namespace ccf::kv::serialisers
{
template <>
struct BlitSerialiser<ccf::endpoints::EndpointKey>

Просмотреть файл

@ -53,12 +53,12 @@ namespace ccf::endpoints
struct EndpointContext : public CommandEndpointContext
{
EndpointContext(const std::shared_ptr<ccf::RpcContext>& r, kv::Tx& t) :
EndpointContext(const std::shared_ptr<ccf::RpcContext>& r, ccf::kv::Tx& t) :
CommandEndpointContext(r),
tx(t)
{}
kv::Tx& tx;
ccf::kv::Tx& tx;
};
using EndpointFunction = std::function<void(EndpointContext& args)>;
@ -69,12 +69,12 @@ namespace ccf::endpoints
struct ReadOnlyEndpointContext : public CommandEndpointContext
{
ReadOnlyEndpointContext(
const std::shared_ptr<ccf::RpcContext>& r, kv::ReadOnlyTx& t) :
const std::shared_ptr<ccf::RpcContext>& r, ccf::kv::ReadOnlyTx& t) :
CommandEndpointContext(r),
tx(t)
{}
kv::ReadOnlyTx& tx;
ccf::kv::ReadOnlyTx& tx;
};
using ReadOnlyEndpointFunction =
std::function<void(ReadOnlyEndpointContext& args)>;

Просмотреть файл

@ -15,7 +15,7 @@
#include <regex>
#include <set>
namespace kv
namespace ccf::kv
{
class Consensus;
class TxHistory;
@ -161,8 +161,8 @@ namespace ccf::endpoints
std::map<RESTVerb, std::shared_ptr<PathTemplatedEndpoint>>>
templated_endpoints;
kv::Consensus* consensus = nullptr;
kv::TxHistory* history = nullptr;
ccf::kv::Consensus* consensus = nullptr;
ccf::kv::TxHistory* history = nullptr;
public:
EndpointRegistry(const std::string& method_prefix_) :
@ -254,12 +254,12 @@ namespace ccf::endpoints
* internally, so must be able to populate the document
* with the supported endpoints however it defines them.
*/
virtual void build_api(nlohmann::json& document, kv::ReadOnlyTx&);
virtual void build_api(nlohmann::json& document, ccf::kv::ReadOnlyTx&);
virtual void init_handlers();
virtual EndpointDefinitionPtr find_endpoint(
kv::Tx&, ccf::RpcContext& rpc_ctx);
ccf::kv::Tx&, ccf::RpcContext& rpc_ctx);
virtual void execute_endpoint(
EndpointDefinitionPtr e, EndpointContext& args);
@ -268,7 +268,7 @@ namespace ccf::endpoints
EndpointDefinitionPtr e, CommandEndpointContext& args, const TxID& tx_id);
virtual std::set<RESTVerb> get_allowed_verbs(
kv::Tx&, const ccf::RpcContext& rpc_ctx);
ccf::kv::Tx&, const ccf::RpcContext& rpc_ctx);
virtual bool request_needs_root(const ccf::RpcContext& rpc_ctx);
@ -278,9 +278,9 @@ namespace ccf::endpoints
virtual void tick(std::chrono::milliseconds);
void set_consensus(kv::Consensus* c);
void set_consensus(ccf::kv::Consensus* c);
void set_history(kv::TxHistory* h);
void set_history(ccf::kv::TxHistory* h);
// Override these methods to log or report request metrics.
virtual void handle_event_request_completed(

Просмотреть файл

@ -37,7 +37,7 @@ namespace ccf
const std::vector<std::shared_ptr<AuthnPolicy>>& _policies);
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx&,
ccf::kv::ReadOnlyTx&,
const std::shared_ptr<ccf::RpcContext>&,
std::string&) override;

Просмотреть файл

@ -30,7 +30,7 @@ namespace ccf
virtual ~AuthnPolicy() = default;
virtual std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason) = 0;

Просмотреть файл

@ -38,7 +38,7 @@ namespace ccf
virtual ~UserCertAuthnPolicy();
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason) override;
@ -72,7 +72,7 @@ namespace ccf
virtual ~MemberCertAuthnPolicy();
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason) override;
@ -99,7 +99,7 @@ namespace ccf
static constexpr auto SECURITY_SCHEME_NAME = "node_cert";
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason) override;

Просмотреть файл

@ -125,7 +125,7 @@ namespace ccf
~MemberCOSESign1AuthnPolicy();
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason) override;
@ -158,7 +158,7 @@ namespace ccf
using MemberCOSESign1AuthnPolicy::MemberCOSESign1AuthnPolicy;
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason) override;
@ -182,7 +182,7 @@ namespace ccf
static const OpenAPISecuritySchema security_schema;
virtual std::unique_ptr<UserCOSESign1AuthnIdentity> _authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason);
@ -198,7 +198,7 @@ namespace ccf
~UserCOSESign1AuthnPolicy();
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason) override;
@ -240,7 +240,7 @@ namespace ccf
{}
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason) override;

Просмотреть файл

@ -17,7 +17,7 @@ namespace ccf
static constexpr auto SECURITY_SCHEME_NAME = "no_auth";
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx&,
ccf::kv::ReadOnlyTx&,
const std::shared_ptr<ccf::RpcContext>&,
std::string&) override;

Просмотреть файл

@ -37,7 +37,7 @@ namespace ccf
virtual ~JwtAuthnPolicy();
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason) override;

Просмотреть файл

@ -202,7 +202,7 @@ struct formatter<ccf::EntityId<FmtExtender>>
};
FMT_END_NAMESPACE
namespace kv::serialisers
namespace ccf::kv::serialisers
{
template <typename FmtExtender>
struct BlitSerialiser<ccf::EntityId<FmtExtender>>

Просмотреть файл

@ -9,7 +9,7 @@
#include "ccf/tx_id.h"
#include "ccf/tx_status.h"
namespace kv
namespace ccf::kv
{
class Consensus;
}
@ -51,7 +51,7 @@ namespace ccf::historical
ccf::View view, ccf::SeqNo seqno, std::string& error_reason)>;
HistoricalTxStatus is_tx_committed_v2(
kv::Consensus* consensus,
ccf::kv::Consensus* consensus,
ccf::View view,
ccf::SeqNo seqno,
std::string& error_reason);

Просмотреть файл

@ -16,14 +16,14 @@ namespace ccf::historical
struct State
{
/// Read-only historical store at transaction_id
kv::ReadOnlyStorePtr store = nullptr;
ccf::kv::ReadOnlyStorePtr store = nullptr;
/// Receipt for ledger entry at transaction_id
TxReceiptImplPtr receipt = nullptr;
/// View and Sequence Number for the State
ccf::TxID transaction_id;
State(
const kv::ReadOnlyStorePtr& store_,
const ccf::kv::ReadOnlyStorePtr& store_,
const TxReceiptImplPtr& receipt_,
const ccf::TxID& transaction_id_) :
store(store_),
@ -93,7 +93,7 @@ namespace ccf::historical
* is equivalent to get_store_at(handle, seqno, seqno), but returns nullptr
* if the state is currently unavailable.
*/
virtual kv::ReadOnlyStorePtr get_store_at(
virtual ccf::kv::ReadOnlyStorePtr get_store_at(
RequestHandle handle,
ccf::SeqNo seqno,
ExpiryDuration seconds_until_expiry) = 0;
@ -101,7 +101,7 @@ namespace ccf::historical
/** Same as @c get_store_at but uses default expiry value.
* @see get_store_at
*/
virtual kv::ReadOnlyStorePtr get_store_at(
virtual ccf::kv::ReadOnlyStorePtr get_store_at(
RequestHandle handle, ccf::SeqNo seqno) = 0;
/** Retrieve a full state at a given seqno, including the Store, the TxID
@ -135,7 +135,7 @@ namespace ccf::historical
* vector will be of length (end_seqno - start_seqno + 1) and will contain
* no nullptrs.
*/
virtual std::vector<kv::ReadOnlyStorePtr> get_store_range(
virtual std::vector<ccf::kv::ReadOnlyStorePtr> get_store_range(
RequestHandle handle,
ccf::SeqNo start_seqno,
ccf::SeqNo end_seqno,
@ -144,7 +144,7 @@ namespace ccf::historical
/** Same as @c get_store_range but uses default expiry value.
* @see get_store_range
*/
virtual std::vector<kv::ReadOnlyStorePtr> get_store_range(
virtual std::vector<ccf::kv::ReadOnlyStorePtr> get_store_range(
RequestHandle handle, ccf::SeqNo start_seqno, ccf::SeqNo end_seqno) = 0;
/** Retrieve a range of states at the given indices, including the Store,
@ -165,11 +165,11 @@ namespace ccf::historical
/** Retrieve stores for a set of given indices.
*/
virtual std::vector<kv::ReadOnlyStorePtr> get_stores_for(
virtual std::vector<ccf::kv::ReadOnlyStorePtr> get_stores_for(
RequestHandle handle,
const SeqNoCollection& seqnos,
ExpiryDuration seconds_until_expiry) = 0;
virtual std::vector<kv::ReadOnlyStorePtr> get_stores_for(
virtual std::vector<ccf::kv::ReadOnlyStorePtr> get_stores_for(
RequestHandle handle, const SeqNoCollection& seqnos) = 0;
/** Retrieve states for a set of given indices.

Просмотреть файл

@ -19,7 +19,7 @@ namespace ccf::historical
// additional entries have been requested, in which case the caller should
// retry later.
bool populate_service_endorsements(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
ccf::historical::StatePtr& state,
AbstractStateCache& state_cache,
std::shared_ptr<NetworkIdentitySubsystemInterface>

Просмотреть файл

@ -34,7 +34,7 @@ namespace ccf::indexing::strategies
virtual ~VisitEachEntryInMap() = default;
void handle_committed_transaction(
const ccf::TxID& tx_id, const kv::ReadOnlyStorePtr& store) override;
const ccf::TxID& tx_id, const ccf::kv::ReadOnlyStorePtr& store) override;
std::optional<ccf::SeqNo> next_requested() override;
nlohmann::json describe() override;

Просмотреть файл

@ -38,7 +38,7 @@ namespace ccf::indexing
* transaction.
*/
virtual void handle_committed_transaction(
const ccf::TxID& tx_id, const kv::ReadOnlyStorePtr& store) = 0;
const ccf::TxID& tx_id, const ccf::kv::ReadOnlyStorePtr& store) = 0;
virtual void tick() {}

Просмотреть файл

@ -48,7 +48,7 @@ namespace ccf::js
class WithKVExtension : public Base
{
public:
WithKVExtension(TxAccess acc, kv::Tx* tx) : Base(acc)
WithKVExtension(TxAccess acc, ccf::kv::Tx* tx) : Base(acc)
{
// add ccf.kv.*
Base::add_extension(

Просмотреть файл

@ -21,9 +21,9 @@ namespace ccf::js::extensions
class GovEffectsExtension : public ExtensionInterface
{
public:
kv::Tx* tx;
ccf::kv::Tx* tx;
GovEffectsExtension(kv::Tx* t) : tx(t) {}
GovEffectsExtension(ccf::kv::Tx* t) : tx(t) {}
void install(js::core::Context& ctx) override;
};

Просмотреть файл

@ -7,7 +7,7 @@
#include <memory>
namespace kv
namespace ccf::kv
{
class Tx;
}
@ -28,7 +28,7 @@ namespace ccf::js::extensions
ccf::js::NamespaceRestriction namespace_restriction;
KvExtension(kv::Tx* t, const ccf::js::NamespaceRestriction& nr = {});
KvExtension(ccf::kv::Tx* t, const ccf::js::NamespaceRestriction& nr = {});
~KvExtension();
void install(js::core::Context& ctx);

Просмотреть файл

@ -84,7 +84,7 @@ namespace ccf::js
* later be dispatched to.
*/
ccf::ApiResult install_custom_endpoints_v1(
kv::Tx& tx, const ccf::js::Bundle& bundle);
ccf::kv::Tx& tx, const ccf::js::Bundle& bundle);
/**
* Retrieve all endpoint definitions currently in-use. This returns the same
@ -93,14 +93,14 @@ namespace ccf::js
* due to internal normalisation.
*/
ccf::ApiResult get_custom_endpoints_v1(
ccf::js::Bundle& bundle, kv::ReadOnlyTx& tx);
ccf::js::Bundle& bundle, ccf::kv::ReadOnlyTx& tx);
/**
* Retrieve property definition for a single JS endpoint.
*/
ccf::ApiResult get_custom_endpoint_properties_v1(
ccf::endpoints::EndpointProperties& properties,
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const ccf::RESTVerb& verb,
const ccf::endpoints::URI& uri);
@ -108,7 +108,9 @@ namespace ccf::js
* Retrieve content of a single JS module.
*/
ccf::ApiResult get_custom_endpoint_module_v1(
std::string& code, kv::ReadOnlyTx& tx, const std::string& module_name);
std::string& code,
ccf::kv::ReadOnlyTx& tx,
const std::string& module_name);
/**
* Pass a function to control which maps can be accessed by JS endpoints.
@ -121,7 +123,7 @@ namespace ccf::js
* bound any values specified here.
*/
ccf::ApiResult set_js_runtime_options_v1(
kv::Tx& tx, const ccf::JSRuntimeOptions& options);
ccf::kv::Tx& tx, const ccf::JSRuntimeOptions& options);
/**
* Get the options which currently control JS execution. If no value has
@ -129,14 +131,14 @@ namespace ccf::js
* which will be applied instead.
*/
ccf::ApiResult get_js_runtime_options_v1(
ccf::JSRuntimeOptions& options, kv::ReadOnlyTx& tx);
ccf::JSRuntimeOptions& options, ccf::kv::ReadOnlyTx& tx);
/**
* Record action details by storing them in KV maps using a common format,
* for the purposes of offline audit using the ledger.
*/
ccf::ApiResult record_action_for_audit_v1(
kv::Tx& tx,
ccf::kv::Tx& tx,
ccf::ActionFormat format,
const std::string& user_id,
const std::string& action_name,
@ -148,7 +150,7 @@ namespace ccf::js
* size, an authenticated timestamp (@p created_at) is required.
*/
ccf::ApiResult check_action_not_replayed_v1(
kv::Tx& tx,
ccf::kv::Tx& tx,
uint64_t created_at,
const std::span<const uint8_t> action,
ccf::InvalidArgsReason& reason);
@ -157,7 +159,7 @@ namespace ccf::js
/// endpoints before delegating to base implementation.
///@{
ccf::endpoints::EndpointDefinitionPtr find_endpoint(
kv::Tx& tx, ccf::RpcContext& rpc_ctx) override;
ccf::kv::Tx& tx, ccf::RpcContext& rpc_ctx) override;
void execute_endpoint(
ccf::endpoints::EndpointDefinitionPtr e,
@ -168,7 +170,7 @@ namespace ccf::js
ccf::endpoints::CommandEndpointContext& endpoint_ctx,
const ccf::TxID& tx_id) override;
void build_api(nlohmann::json& document, kv::ReadOnlyTx& tx) override;
void build_api(nlohmann::json& document, ccf::kv::ReadOnlyTx& tx) override;
///@}
virtual ccf::js::extensions::Extensions get_extensions(

Просмотреть файл

@ -2,7 +2,7 @@
// Licensed under the Apache 2.0 License.
#pragma once
namespace kv
namespace ccf::kv
{
class AbstractHandle
{

Просмотреть файл

@ -4,7 +4,7 @@
#include <string>
namespace kv
namespace ccf::kv
{
struct GetName
{

Просмотреть файл

@ -7,7 +7,7 @@
#include <functional>
#include <memory>
namespace kv
namespace ccf::kv
{
class ConfigurableConsensus;

Просмотреть файл

@ -10,7 +10,7 @@
#include "ccf/kv/serialisers/json_serialiser.h"
#include "ccf/kv/untyped.h"
namespace kv
namespace ccf::kv
{
/** Defines the schema of a map accessed by a @c ccf::Tx, exposing associated
* types. This map is an unordered associative container of key-value pairs.
@ -31,11 +31,11 @@ namespace kv
public:
// Expose correct public aliases of types
using ReadOnlyHandle =
kv::ReadableMapHandle<K, V, KSerialiser, VSerialiser>;
ccf::kv::ReadableMapHandle<K, V, KSerialiser, VSerialiser>;
using WriteOnlyHandle =
kv::WriteableMapHandle<K, V, KSerialiser, VSerialiser>;
using Handle = kv::MapHandle<K, V, KSerialiser, VSerialiser>;
using Diff = kv::MapDiff<K, V, KSerialiser, VSerialiser>;
ccf::kv::WriteableMapHandle<K, V, KSerialiser, VSerialiser>;
using Handle = ccf::kv::MapHandle<K, V, KSerialiser, VSerialiser>;
using Diff = ccf::kv::MapDiff<K, V, KSerialiser, VSerialiser>;
using Write = std::map<K, std::optional<V>>;
using CommitHook = CommitHook<Write>;
@ -49,7 +49,7 @@ namespace kv
using GetName::GetName;
private:
static Write deserialise_write(const kv::untyped::Write& w)
static Write deserialise_write(const ccf::kv::untyped::Write& w)
{
Write typed_writes;
for (const auto& [uk, opt_uv] : w)
@ -70,16 +70,16 @@ namespace kv
}
public:
static kv::untyped::CommitHook wrap_commit_hook(const CommitHook& hook)
static ccf::kv::untyped::CommitHook wrap_commit_hook(const CommitHook& hook)
{
return [hook](Version v, const kv::untyped::Write& w) {
return [hook](Version v, const ccf::kv::untyped::Write& w) {
hook(v, deserialise_write(w));
};
}
static kv::untyped::MapHook wrap_map_hook(const MapHook& hook)
static ccf::kv::untyped::MapHook wrap_map_hook(const MapHook& hook)
{
return [hook](Version v, const kv::untyped::Write& w) {
return [hook](Version v, const ccf::kv::untyped::Write& w) {
return hook(v, deserialise_write(w));
};
}
@ -95,14 +95,14 @@ namespace kv
template <typename K, typename V>
using JsonSerialisedMap =
MapSerialisedWith<K, V, kv::serialisers::JsonSerialiser>;
MapSerialisedWith<K, V, ccf::kv::serialisers::JsonSerialiser>;
template <typename K, typename V>
using RawCopySerialisedMap = TypedMap<
K,
V,
kv::serialisers::BlitSerialiser<K>,
kv::serialisers::BlitSerialiser<V>>;
ccf::kv::serialisers::BlitSerialiser<K>,
ccf::kv::serialisers::BlitSerialiser<V>>;
/** Short name for default-serialised maps, using JSON serialisers. Support
* for custom types can be added through the DECLARE_JSON... macros.

Просмотреть файл

@ -4,21 +4,21 @@
#include "ccf/kv/untyped_map_diff.h"
namespace kv
namespace ccf::kv
{
template <typename K, typename V, typename KSerialiser, typename VSerialiser>
class MapDiff : public AbstractHandle
{
protected:
kv::untyped::MapDiff map_diff;
ccf::kv::untyped::MapDiff map_diff;
public:
using KeyType = K;
using ValueType = V;
MapDiff(kv::untyped::MapDiff map_diff_) : map_diff(map_diff_) {}
MapDiff(ccf::kv::untyped::MapDiff map_diff_) : map_diff(map_diff_) {}
MapDiff(kv::untyped::ChangeSet& changes, const std::string& map_name) :
MapDiff(ccf::kv::untyped::ChangeSet& changes, const std::string& map_name) :
map_diff(changes, map_name)
{}
@ -86,8 +86,8 @@ namespace kv
{
const auto& g =
[&](
const kv::serialisers::SerialisedEntry& k_rep,
const std::optional<kv::serialisers::SerialisedEntry>& v_rep)
const ccf::kv::serialisers::SerialisedEntry& k_rep,
const std::optional<ccf::kv::serialisers::SerialisedEntry>& v_rep)
-> bool {
const auto k = KSerialiser::from_serialised(k_rep);
if (v_rep.has_value())
@ -116,8 +116,8 @@ namespace kv
void foreach_key(F&& f)
{
auto g = [&](
const kv::serialisers::SerialisedEntry& k_rep,
const kv::serialisers::SerialisedEntry&) {
const ccf::kv::serialisers::SerialisedEntry& k_rep,
const ccf::kv::serialisers::SerialisedEntry&) {
return f(KSerialiser::from_serialised(k_rep));
};
map_diff.foreach(g);
@ -133,18 +133,19 @@ namespace kv
template <class F>
void foreach_value(F&& f)
{
auto g = [&](
const kv::serialisers::SerialisedEntry&,
const std::optional<kv::serialisers::SerialisedEntry>& v_rep) {
if (v_rep.has_value())
{
return f(VSerialiser::from_serialised(v_rep));
}
else
{
return f(std::nullopt);
}
};
auto g =
[&](
const ccf::kv::serialisers::SerialisedEntry&,
const std::optional<ccf::kv::serialisers::SerialisedEntry>& v_rep) {
if (v_rep.has_value())
{
return f(VSerialiser::from_serialised(v_rep));
}
else
{
return f(std::nullopt);
}
};
map_diff.foreach(g);
}

Просмотреть файл

@ -4,21 +4,21 @@
#include "ccf/kv/untyped_map_handle.h"
namespace kv
namespace ccf::kv
{
/** Grants read access to a @c kv::Map, as part of a @c kv::Tx.
/** Grants read access to a @c ccf::kv::Map, as part of a @c ccf::kv::Tx.
*/
template <typename K, typename V, typename KSerialiser, typename VSerialiser>
class ReadableMapHandle
{
protected:
kv::untyped::MapHandle& read_handle;
ccf::kv::untyped::MapHandle& read_handle;
public:
using KeyType = K;
using ValueType = V;
ReadableMapHandle(kv::untyped::MapHandle& uh) : read_handle(uh) {}
ReadableMapHandle(ccf::kv::untyped::MapHandle& uh) : read_handle(uh) {}
/** Get name of this map.
*
@ -146,8 +146,8 @@ namespace kv
void foreach(F&& f)
{
auto g = [&](
const kv::serialisers::SerialisedEntry& k_rep,
const kv::serialisers::SerialisedEntry& v_rep) {
const ccf::kv::serialisers::SerialisedEntry& k_rep,
const ccf::kv::serialisers::SerialisedEntry& v_rep) {
return f(
KSerialiser::from_serialised(k_rep),
VSerialiser::from_serialised(v_rep));
@ -169,8 +169,8 @@ namespace kv
void foreach_key(F&& f)
{
auto g = [&](
const kv::serialisers::SerialisedEntry& k_rep,
const kv::serialisers::SerialisedEntry&) {
const ccf::kv::serialisers::SerialisedEntry& k_rep,
const ccf::kv::serialisers::SerialisedEntry&) {
return f(KSerialiser::from_serialised(k_rep));
};
read_handle.foreach(g);
@ -190,8 +190,8 @@ namespace kv
void foreach_value(F&& f)
{
auto g = [&](
const kv::serialisers::SerialisedEntry&,
const kv::serialisers::SerialisedEntry& v_rep) {
const ccf::kv::serialisers::SerialisedEntry&,
const ccf::kv::serialisers::SerialisedEntry& v_rep) {
return f(VSerialiser::from_serialised(v_rep));
};
read_handle.foreach(g);
@ -211,16 +211,16 @@ namespace kv
}
};
/** Grants write access to a @c kv::Map, as part of a @c kv::Tx.
/** Grants write access to a @c ccf::kv::Map, as part of a @c ccf::kv::Tx.
*/
template <typename K, typename V, typename KSerialiser, typename VSerialiser>
class WriteableMapHandle
{
protected:
kv::untyped::MapHandle& write_handle;
ccf::kv::untyped::MapHandle& write_handle;
public:
WriteableMapHandle(kv::untyped::MapHandle& uh) : write_handle(uh) {}
WriteableMapHandle(ccf::kv::untyped::MapHandle& uh) : write_handle(uh) {}
/** Write value at key.
*
@ -255,10 +255,11 @@ namespace kv
}
};
/** Grants read and write access to a @c kv::Map, as part of a @c kv::Tx.
/** Grants read and write access to a @c ccf::kv::Map, as part of a @c
* ccf::kv::Tx.
*
* @see kv::ReadableMapHandle
* @see kv::WriteableMapHandle
* @see ccf::kv::ReadableMapHandle
* @see ccf::kv::WriteableMapHandle
*/
template <typename K, typename V, typename KSerialiser, typename VSerialiser>
class MapHandle : public AbstractHandle,
@ -266,13 +267,14 @@ namespace kv
public WriteableMapHandle<K, V, KSerialiser, VSerialiser>
{
protected:
kv::untyped::MapHandle untyped_handle;
ccf::kv::untyped::MapHandle untyped_handle;
using ReadableBase = ReadableMapHandle<K, V, KSerialiser, VSerialiser>;
using WriteableBase = WriteableMapHandle<K, V, KSerialiser, VSerialiser>;
public:
MapHandle(kv::untyped::ChangeSet& changes, const std::string& map_name) :
MapHandle(
ccf::kv::untyped::ChangeSet& changes, const std::string& map_name) :
ReadableBase(untyped_handle),
WriteableBase(untyped_handle),
untyped_handle(changes, map_name)

Просмотреть файл

@ -7,7 +7,7 @@
#include <memory>
namespace kv
namespace ccf::kv
{
class ReadOnlyStore
{
@ -15,9 +15,9 @@ namespace kv
virtual ~ReadOnlyStore() = default;
virtual ccf::TxID get_txid() = 0;
virtual kv::ReadOnlyTx create_read_only_tx() = 0;
virtual std::unique_ptr<kv::ReadOnlyTx> create_read_only_tx_ptr() = 0;
virtual kv::TxDiff create_tx_diff() = 0;
virtual ccf::kv::ReadOnlyTx create_read_only_tx() = 0;
virtual std::unique_ptr<ccf::kv::ReadOnlyTx> create_read_only_tx_ptr() = 0;
virtual ccf::kv::TxDiff create_tx_diff() = 0;
};
using ReadOnlyStorePtr = std::shared_ptr<ReadOnlyStore>;

Просмотреть файл

@ -5,7 +5,7 @@
#include "ccf/ds/nonstd.h"
#include "ccf/kv/serialisers/serialised_entry.h"
namespace kv::serialisers
namespace ccf::kv::serialisers
{
// Converts values to their raw, in-memory representation. To add support for
// custom types, add a specialization of BlitSerialiser for them.

Просмотреть файл

@ -6,7 +6,7 @@
#include <nlohmann/json.hpp>
namespace kv::serialisers
namespace ccf::kv::serialisers
{
// Converts values to and from JSON, using nlohmann JSON. To add support for
// custom types, make them convertible to nlohmann::json. You may do this

Просмотреть файл

@ -3,7 +3,7 @@
#pragma once
#include "ccf/byte_vector.h"
namespace kv::serialisers
namespace ccf::kv::serialisers
{
using SerialisedEntry = ccf::ByteVector;
}

Просмотреть файл

@ -9,7 +9,7 @@
#include "ccf/kv/set_handle.h"
#include "ccf/kv/untyped.h"
namespace kv
namespace ccf::kv
{
/** Defines the schema of a set type accessed by a @c ccf::Tx. This set is an
* unordered container of unique keys. Each key is either present or missing
@ -21,24 +21,26 @@ namespace kv
* evaluated on the serialised form; if unequal Ks produce the same
* serialisation, they will coincide within this set.
*
* This is implemented as a @c kv::Map from K to Unit, and the serialisation
* of the unit values is overridable with the Unit template parameter.
* This is implemented as a @c ccf::kv::Map from K to Unit, and the
* serialisation of the unit values is overridable with the Unit template
* parameter.
*/
template <
typename K,
typename KSerialiser,
typename Unit = kv::serialisers::ZeroBlitUnitCreator>
typename Unit = ccf::kv::serialisers::ZeroBlitUnitCreator>
class TypedSet : public GetName
{
public:
using ReadOnlyHandle = kv::ReadableSetHandle<K, KSerialiser>;
using WriteOnlyHandle = kv::WriteableSetHandle<K, KSerialiser, Unit>;
using Handle = kv::SetHandle<K, KSerialiser, Unit>;
using ReadOnlyHandle = ccf::kv::ReadableSetHandle<K, KSerialiser>;
using WriteOnlyHandle = ccf::kv::WriteableSetHandle<K, KSerialiser, Unit>;
using Handle = ccf::kv::SetHandle<K, KSerialiser, Unit>;
// Note: The type V of the value `std::optional<V>` does not matter here.
// The optional type is required to differentiate additions from deletions,
// and to provide a consistent interface with the more generic `TypedMap`.
using Write = std::map<K, std::optional<kv::serialisers::SerialisedEntry>>;
using Write =
std::map<K, std::optional<ccf::kv::serialisers::SerialisedEntry>>;
using MapHook = MapHook<Write>;
using CommitHook = CommitHook<Write>;
@ -48,7 +50,7 @@ namespace kv
using GetName::GetName;
private:
static Write deserialise_write(const kv::untyped::Write& w)
static Write deserialise_write(const ccf::kv::untyped::Write& w)
{
Write typed_writes;
for (const auto& [uk, opt_uv] : w)
@ -68,16 +70,16 @@ namespace kv
}
public:
static kv::untyped::CommitHook wrap_commit_hook(const CommitHook& hook)
static ccf::kv::untyped::CommitHook wrap_commit_hook(const CommitHook& hook)
{
return [hook](Version v, const kv::untyped::Write& w) {
return [hook](Version v, const ccf::kv::untyped::Write& w) {
hook(v, deserialise_write(w));
};
}
static kv::untyped::MapHook wrap_map_hook(const MapHook& hook)
static ccf::kv::untyped::MapHook wrap_map_hook(const MapHook& hook)
{
return [hook](Version v, const kv::untyped::Write& w) {
return [hook](Version v, const ccf::kv::untyped::Write& w) {
return hook(v, deserialise_write(w));
};
}
@ -87,15 +89,16 @@ namespace kv
typename K,
template <typename>
typename KSerialiser,
typename Unit = kv::serialisers::ZeroBlitUnitCreator>
typename Unit = ccf::kv::serialisers::ZeroBlitUnitCreator>
using SetSerialisedWith = TypedSet<K, KSerialiser<K>, Unit>;
template <typename K>
using JsonSerialisedSet =
SetSerialisedWith<K, kv::serialisers::JsonSerialiser>;
SetSerialisedWith<K, ccf::kv::serialisers::JsonSerialiser>;
template <typename K>
using RawCopySerialisedSet = TypedSet<K, kv::serialisers::BlitSerialiser<K>>;
using RawCopySerialisedSet =
TypedSet<K, ccf::kv::serialisers::BlitSerialiser<K>>;
/** Short name for default-serialised sets, using JSON serialisers. Support
* for custom types can be added through the DECLARE_JSON... macros.

Просмотреть файл

@ -5,20 +5,20 @@
#include "ccf/kv/unit.h"
#include "ccf/kv/untyped_map_handle.h"
namespace kv
namespace ccf::kv
{
/** Grants read access to a @c kv::Set, as part of a @c kv::Tx.
/** Grants read access to a @c ccf::kv::Set, as part of a @c ccf::kv::Tx.
*/
template <typename K, typename KSerialiser>
class ReadableSetHandle
{
protected:
kv::untyped::MapHandle& read_handle;
ccf::kv::untyped::MapHandle& read_handle;
public:
using KeyType = K;
ReadableSetHandle(kv::untyped::MapHandle& uh) : read_handle(uh) {}
ReadableSetHandle(ccf::kv::untyped::MapHandle& uh) : read_handle(uh) {}
/** Test whether a key is present in the set.
*
@ -37,7 +37,7 @@ namespace kv
/** Test whether a key's presence is globally committed, meaning it has been
* replciated and acknowledged by consensus protocol.
*
* @see kv::ReadableMapHandle::get_globally_committed
* @see ccf::kv::ReadableMapHandle::get_globally_committed
*
* @param key Key to test
*
@ -53,7 +53,7 @@ namespace kv
*
* Returns nullopt if the key is not present.
*
* @see kv::ReadableMapHandle::get_version_of_previous_write
* @see ccf::kv::ReadableMapHandle::get_version_of_previous_write
*
* @param key Key to read
*
@ -68,7 +68,7 @@ namespace kv
/** Iterate over all entries in this set.
*
* @see kv::ReadableMapHandle::foreach
* @see ccf::kv::ReadableMapHandle::foreach
*
* @tparam F Functor type. Should usually be derived implicitly from f
* @param f Functor instance, taking (const K& k) and returning a
@ -79,8 +79,8 @@ namespace kv
void foreach(F&& f)
{
auto g = [&](
const kv::serialisers::SerialisedEntry& k_rep,
const kv::serialisers::SerialisedEntry&) {
const ccf::kv::serialisers::SerialisedEntry& k_rep,
const ccf::kv::serialisers::SerialisedEntry&) {
return f(KSerialiser::from_serialised(k_rep));
};
read_handle.foreach(g);
@ -100,16 +100,16 @@ namespace kv
}
};
/** Grants write access to a @c kv::Set, as part of a @c kv::Tx.
/** Grants write access to a @c ccf::kv::Set, as part of a @c ccf::kv::Tx.
*/
template <typename K, typename KSerialiser, typename Unit>
class WriteableSetHandle
{
protected:
kv::untyped::MapHandle& write_handle;
ccf::kv::untyped::MapHandle& write_handle;
public:
WriteableSetHandle(kv::untyped::MapHandle& uh) : write_handle(uh) {}
WriteableSetHandle(ccf::kv::untyped::MapHandle& uh) : write_handle(uh) {}
/** Insert an element into this set.
*
@ -143,24 +143,26 @@ namespace kv
}
};
/** Grants read and write access to a @c kv::Set, as part of a @c kv::Tx.
/** Grants read and write access to a @c ccf::kv::Set, as part of a @c
* ccf::kv::Tx.
*
* @see kv::ReadableSetHandle
* @see kv::WriteableSetHandle
* @see ccf::kv::ReadableSetHandle
* @see ccf::kv::WriteableSetHandle
*/
template <typename K, typename KSerialiser, typename Unit>
class SetHandle : public kv::AbstractHandle,
class SetHandle : public ccf::kv::AbstractHandle,
public ReadableSetHandle<K, KSerialiser>,
public WriteableSetHandle<K, KSerialiser, Unit>
{
protected:
kv::untyped::MapHandle untyped_handle;
ccf::kv::untyped::MapHandle untyped_handle;
using ReadableBase = ReadableSetHandle<K, KSerialiser>;
using WriteableBase = WriteableSetHandle<K, KSerialiser, Unit>;
public:
SetHandle(kv::untyped::ChangeSet& changes, const std::string& map_name) :
SetHandle(
ccf::kv::untyped::ChangeSet& changes, const std::string& map_name) :
ReadableBase(untyped_handle),
WriteableBase(untyped_handle),
untyped_handle(changes, map_name)

Просмотреть файл

@ -4,23 +4,23 @@
#include "ccf/kv/serialisers/serialised_entry.h"
namespace kv::serialisers
namespace ccf::kv::serialisers
{
// Unit serialisations are used as a utility type to convert kv::Maps to
// kv::Maps and kv::Sets. Specifically, these are implemented as wrappers so
// that kv::Value<T> is essentially kv::Map<Unit, T>, and kv::Set<T> is
// kv::Map<T, Unit>.
// This is used as a template parameter allowing the caller to specify what
// value is inserted into the ledger.
// Unit serialisations are used as a utility type to convert ccf::kv::Maps to
// ccf::kv::Maps and ccf::kv::Sets. Specifically, these are implemented as
// wrappers so that ccf::kv::Value<T> is essentially ccf::kv::Map<Unit, T>,
// and ccf::kv::Set<T> is ccf::kv::Map<T, Unit>. This is used as a template
// parameter allowing the caller to specify what value is inserted into the
// ledger.
// This is the default UnitCreator, returning 8 null bytes for compatibility
// with old ledgers (where Values were previously Maps with a single entry
// at key 0, serialised as a uint64_t)
struct ZeroBlitUnitCreator
{
static kv::serialisers::SerialisedEntry get()
static ccf::kv::serialisers::SerialisedEntry get()
{
kv::serialisers::SerialisedEntry e;
ccf::kv::serialisers::SerialisedEntry e;
e.assign(sizeof(uint64_t), 0u);
return e;
}
@ -28,7 +28,7 @@ namespace kv::serialisers
struct EmptyUnitCreator
{
static kv::serialisers::SerialisedEntry get()
static ccf::kv::serialisers::SerialisedEntry get()
{
return {};
}

Просмотреть файл

@ -8,13 +8,13 @@
#include <map>
#include <optional>
namespace kv::untyped
namespace ccf::kv::untyped
{
// nullopt values represent deletions
using Write = std::map<
kv::serialisers::SerialisedEntry,
std::optional<kv::serialisers::SerialisedEntry>>;
ccf::kv::serialisers::SerialisedEntry,
std::optional<ccf::kv::serialisers::SerialisedEntry>>;
using CommitHook = kv::CommitHook<Write>;
using MapHook = kv::MapHook<Write>;
using CommitHook = ccf::kv::CommitHook<Write>;
using MapHook = ccf::kv::MapHook<Write>;
}

Просмотреть файл

@ -11,15 +11,15 @@
#include <optional>
#include <string>
namespace kv::untyped
namespace ccf::kv::untyped
{
struct ChangeSet;
class MapDiff : public kv::AbstractHandle
class MapDiff : public ccf::kv::AbstractHandle
{
public:
using KeyType = kv::serialisers::SerialisedEntry;
using ValueType = kv::serialisers::SerialisedEntry;
using KeyType = ccf::kv::serialisers::SerialisedEntry;
using ValueType = ccf::kv::serialisers::SerialisedEntry;
using ElementVisitor =
std::function<void(const KeyType& k, const std::optional<ValueType>& V)>;
@ -28,13 +28,13 @@ namespace kv::untyped
std::function<bool(const KeyType& k, const std::optional<ValueType>& V)>;
protected:
kv::untyped::Write& writes;
ccf::kv::untyped::Write& writes;
std::string map_name;
void foreach_(const ElementVisitorWithEarlyOut& fn);
public:
MapDiff(kv::untyped::ChangeSet& cs, const std::string& map_name);
MapDiff(ccf::kv::untyped::ChangeSet& cs, const std::string& map_name);
std::optional<std::optional<ValueType>> get(const KeyType& key);

Просмотреть файл

@ -10,17 +10,17 @@
#include <optional>
#include <string>
namespace kv::untyped
namespace ccf::kv::untyped
{
struct ChangeSet;
class MapHandle : public kv::AbstractHandle
class MapHandle : public ccf::kv::AbstractHandle
{
public:
// Expose these types so that other code can use them as MyTx::KeyType or
// MyMap::MapHandle::KeyType, templated on the MapHandle or Map type
using KeyType = kv::serialisers::SerialisedEntry;
using ValueType = kv::serialisers::SerialisedEntry;
using KeyType = ccf::kv::serialisers::SerialisedEntry;
using ValueType = ccf::kv::serialisers::SerialisedEntry;
using ElementVisitor =
std::function<void(const KeyType& k, const ValueType& V)>;
@ -29,7 +29,7 @@ namespace kv::untyped
std::function<bool(const KeyType& k, const ValueType& V)>;
protected:
kv::untyped::ChangeSet& tx_changes;
ccf::kv::untyped::ChangeSet& tx_changes;
std::string map_name;
/** Get pointer to current value if this key exists, else nullptr if it does
@ -45,7 +45,7 @@ namespace kv::untyped
const ElementVisitorWithEarlyOut& fn, bool always_consider_writes);
public:
MapHandle(kv::untyped::ChangeSet& cs, const std::string& map_name);
MapHandle(ccf::kv::untyped::ChangeSet& cs, const std::string& map_name);
std::string get_name_of_map() const;

Просмотреть файл

@ -9,7 +9,7 @@
#include "ccf/kv/untyped.h"
#include "ccf/kv/value_handle.h"
namespace kv
namespace ccf::kv
{
/** Defines the schema of a single-valued type accessed by a @c ccf::Tx. This
* value type is a container for an optional single element of type V. This
@ -20,19 +20,20 @@ namespace kv
* this V is serialised and deserialised, so it may be written to the ledger
* and replicated by the consensus algorithm.
*
* This is implemented as a @c kv::Map from Unit to V, and the serialisation
* of the unit key is overridable with the Unit template parameter.
* This is implemented as a @c ccf::kv::Map from Unit to V, and the
* serialisation of the unit key is overridable with the Unit template
* parameter.
*/
template <
typename V,
typename VSerialiser,
typename Unit = kv::serialisers::ZeroBlitUnitCreator>
typename Unit = ccf::kv::serialisers::ZeroBlitUnitCreator>
class TypedValue : public GetName
{
public:
using ReadOnlyHandle = kv::ReadableValueHandle<V, VSerialiser, Unit>;
using WriteOnlyHandle = kv::WriteableValueHandle<V, VSerialiser, Unit>;
using Handle = kv::ValueHandle<V, VSerialiser, Unit>;
using ReadOnlyHandle = ccf::kv::ReadableValueHandle<V, VSerialiser, Unit>;
using WriteOnlyHandle = ccf::kv::WriteableValueHandle<V, VSerialiser, Unit>;
using Handle = ccf::kv::ValueHandle<V, VSerialiser, Unit>;
using Write = std::optional<V>;
using MapHook = MapHook<Write>;
@ -43,13 +44,13 @@ namespace kv
using GetName::GetName;
static kv::serialisers::SerialisedEntry create_unit()
static ccf::kv::serialisers::SerialisedEntry create_unit()
{
return Unit::get();
}
private:
static Write deserialise_write(const kv::untyped::Write& w)
static Write deserialise_write(const ccf::kv::untyped::Write& w)
{
assert(w.size() == 1); // Value contains only one element
const auto& value = w.begin()->second;
@ -61,16 +62,16 @@ namespace kv
}
public:
static kv::untyped::CommitHook wrap_commit_hook(const CommitHook& hook)
static ccf::kv::untyped::CommitHook wrap_commit_hook(const CommitHook& hook)
{
return [hook](Version v, const kv::untyped::Write& w) {
return [hook](Version v, const ccf::kv::untyped::Write& w) {
hook(v, deserialise_write(w));
};
}
static kv::untyped::MapHook wrap_map_hook(const MapHook& hook)
static ccf::kv::untyped::MapHook wrap_map_hook(const MapHook& hook)
{
return [hook](Version v, const kv::untyped::Write& w) {
return [hook](Version v, const ccf::kv::untyped::Write& w) {
return hook(v, deserialise_write(w));
};
}
@ -80,16 +81,16 @@ namespace kv
typename V,
template <typename>
typename VSerialiser,
typename Unit = kv::serialisers::ZeroBlitUnitCreator>
typename Unit = ccf::kv::serialisers::ZeroBlitUnitCreator>
using ValueSerialisedWith = TypedValue<V, VSerialiser<V>, Unit>;
template <typename V>
using JsonSerialisedValue =
ValueSerialisedWith<V, kv::serialisers::JsonSerialiser>;
ValueSerialisedWith<V, ccf::kv::serialisers::JsonSerialiser>;
template <typename V>
using RawCopySerialisedValue =
TypedValue<V, kv::serialisers::BlitSerialiser<V>>;
TypedValue<V, ccf::kv::serialisers::BlitSerialiser<V>>;
/** Short name for default-serialised values, using JSON serialisers. Support
* for custom types can be added through the DECLARE_JSON... macros.

Просмотреть файл

@ -5,20 +5,20 @@
#include "ccf/kv/unit.h"
#include "ccf/kv/untyped_map_handle.h"
namespace kv
namespace ccf::kv
{
/** Grants read access to a @c kv::Value, as part of a @c kv::Tx.
/** Grants read access to a @c ccf::kv::Value, as part of a @c ccf::kv::Tx.
*/
template <typename V, typename VSerialiser, typename Unit>
class ReadableValueHandle
{
protected:
kv::untyped::MapHandle& read_handle;
ccf::kv::untyped::MapHandle& read_handle;
public:
using ValueType = V;
ReadableValueHandle(kv::untyped::MapHandle& uh) : read_handle(uh) {}
ReadableValueHandle(ccf::kv::untyped::MapHandle& uh) : read_handle(uh) {}
/** Get the stored value.
*
@ -73,7 +73,7 @@ namespace kv
/** Get version when this value was last written to, by a previous
* transaction.
*
* @see kv::ReadableMapHandle::get_version_of_previous_write
* @see ccf::kv::ReadableMapHandle::get_version_of_previous_write
*
* @return Optional containing version of applied transaction which last
* wrote to this value, or nullopt if such a version does not exist
@ -84,16 +84,16 @@ namespace kv
}
};
/** Grants write access to a @c kv::Value, as part of a @c kv::Tx.
/** Grants write access to a @c ccf::kv::Value, as part of a @c ccf::kv::Tx.
*/
template <typename V, typename VSerialiser, typename Unit>
class WriteableValueHandle
{
protected:
kv::untyped::MapHandle& write_handle;
ccf::kv::untyped::MapHandle& write_handle;
public:
WriteableValueHandle(kv::untyped::MapHandle& uh) : write_handle(uh) {}
WriteableValueHandle(ccf::kv::untyped::MapHandle& uh) : write_handle(uh) {}
/** Modify this value.
*
@ -116,10 +116,11 @@ namespace kv
}
};
/** Grants read and write access to a @c kv::Value, as part of a @c kv::Tx.
/** Grants read and write access to a @c ccf::kv::Value, as part of a @c
* ccf::kv::Tx.
*
* @see kv::ReadableValueHandle
* @see kv::WriteableValueHandle
* @see ccf::kv::ReadableValueHandle
* @see ccf::kv::WriteableValueHandle
*/
template <typename V, typename VSerialiser, typename Unit>
class ValueHandle : public AbstractHandle,
@ -127,13 +128,14 @@ namespace kv
public WriteableValueHandle<V, VSerialiser, Unit>
{
protected:
kv::untyped::MapHandle untyped_handle;
ccf::kv::untyped::MapHandle untyped_handle;
using ReadableBase = ReadableValueHandle<V, VSerialiser, Unit>;
using WriteableBase = WriteableValueHandle<V, VSerialiser, Unit>;
public:
ValueHandle(kv::untyped::ChangeSet& changes, const std::string& map_name) :
ValueHandle(
ccf::kv::untyped::ChangeSet& changes, const std::string& map_name) :
ReadableBase(untyped_handle),
WriteableBase(untyped_handle),
untyped_handle(changes, map_name)

Просмотреть файл

@ -2,7 +2,7 @@
// Licensed under the Apache 2.0 License.
#pragma once
namespace kv
namespace ccf::kv
{
// Version indexes modifications to the local kv store.
using Version = uint64_t;

Просмотреть файл

@ -36,7 +36,7 @@ namespace ccf
static std::optional<HostData> get_host_data(const QuoteInfo& quote_info);
static QuoteVerificationResult verify_quote_against_store(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const QuoteInfo& quote_info,
const std::vector<uint8_t>& expected_node_public_key_der,
pal::PlatformAttestationMeasurement& measurement);

Просмотреть файл

@ -143,7 +143,7 @@ namespace ccf::pal
DECLARE_JSON_REQUIRED_FIELDS(PlatformAttestationMeasurement, data);
}
namespace kv::serialisers
namespace ccf::kv::serialisers
{
template <size_t N>
struct BlitSerialiser<ccf::pal::AttestationMeasurement<N>>

Просмотреть файл

@ -13,5 +13,5 @@ namespace ccfapp
* @return an optional claims digest
*/
std::optional<ccf::ClaimsDigest::Digest> get_create_tx_claims_digest(
kv::ReadOnlyTx& tx)
ccf::kv::ReadOnlyTx& tx)
}

Просмотреть файл

@ -46,7 +46,7 @@ namespace ccf
struct Essentials
{
ringbuffer::WriterPtr writer;
std::shared_ptr<kv::ReadOnlyTx> tx;
std::shared_ptr<ccf::kv::ReadOnlyTx> tx;
std::shared_ptr<ccf::endpoints::ReadOnlyEndpointContext> ctx;
};

Просмотреть файл

@ -5,7 +5,7 @@
#include "ccf/crypto/pem.h"
#include "ccf/kv/serialisers/blit_serialiser.h"
namespace kv::serialisers
namespace ccf::kv::serialisers
{
template <>
struct BlitSerialiser<ccf::crypto::Pem>

Просмотреть файл

@ -12,24 +12,24 @@ namespace ccf
// - The raw key is trivially and cheaply deserialisable.
// - The JSON value can conveniently be audited offline.
// Note: Maps which include large values (e.g. certificate or serialised
// Merkle tree) can use the `kv::RawCopySerialisedMap` type to maximise
// Merkle tree) can use the `ccf::kv::RawCopySerialisedMap` type to maximise
// performance.
template <typename K, typename V>
using ServiceMap = kv::MapSerialisedWith<
using ServiceMap = ccf::kv::MapSerialisedWith<
K,
V,
kv::serialisers::BlitSerialiser,
kv::serialisers::JsonSerialiser>;
ccf::kv::serialisers::BlitSerialiser,
ccf::kv::serialisers::JsonSerialiser>;
template <typename V>
using ServiceValue = kv::ValueSerialisedWith<
using ServiceValue = ccf::kv::ValueSerialisedWith<
V,
kv::serialisers::JsonSerialiser,
kv::serialisers::ZeroBlitUnitCreator>;
ccf::kv::serialisers::JsonSerialiser,
ccf::kv::serialisers::ZeroBlitUnitCreator>;
template <typename K>
using ServiceSet = kv::SetSerialisedWith<
using ServiceSet = ccf::kv::SetSerialisedWith<
K,
kv::serialisers::BlitSerialiser,
kv::serialisers::ZeroBlitUnitCreator>;
ccf::kv::serialisers::BlitSerialiser,
ccf::kv::serialisers::ZeroBlitUnitCreator>;
}

Просмотреть файл

@ -37,7 +37,7 @@ namespace ccf
/** Set to the seqno of the latest ledger secret at the time the node is
trusted */
std::optional<kv::Version> ledger_secret_seqno = std::nullopt;
std::optional<ccf::kv::Version> ledger_secret_seqno = std::nullopt;
/// Code identity for the node
std::optional<std::string> code_digest = std::nullopt;

Просмотреть файл

@ -80,7 +80,7 @@ namespace ccf
ProposalInfoSummary, votes, vote_failures, failure);
using ProposalMap =
kv::RawCopySerialisedMap<ccf::ProposalId, std::vector<uint8_t>>;
ccf::kv::RawCopySerialisedMap<ccf::ProposalId, std::vector<uint8_t>>;
using ProposalInfoMap = ServiceMap<ccf::ProposalId, ProposalInfo>;
namespace Tables

Просмотреть файл

@ -86,9 +86,10 @@ namespace ccf
static constexpr auto JWT_PUBLIC_SIGNING_KEY_ISSUER =
"public:ccf.gov.jwt.public_signing_key_issuer";
using JwtPublicSigningKeys = kv::RawCopySerialisedMap<JwtKeyId, Cert>;
using JwtPublicSigningKeys =
ccf::kv::RawCopySerialisedMap<JwtKeyId, Cert>;
using JwtPublicSigningKeyIssuer =
kv::RawCopySerialisedMap<JwtKeyId, JwtIssuer>;
ccf::kv::RawCopySerialisedMap<JwtKeyId, JwtIssuer>;
}
}

Просмотреть файл

@ -76,9 +76,9 @@ namespace ccf
using MemberInfo = ServiceMap<MemberId, MemberDetails>;
using MemberCerts = kv::RawCopySerialisedMap<MemberId, ccf::crypto::Pem>;
using MemberCerts = ccf::kv::RawCopySerialisedMap<MemberId, ccf::crypto::Pem>;
using MemberPublicEncryptionKeys =
kv::RawCopySerialisedMap<MemberId, ccf::crypto::Pem>;
ccf::kv::RawCopySerialisedMap<MemberId, ccf::crypto::Pem>;
namespace Tables
{

Просмотреть файл

@ -12,10 +12,10 @@
namespace ccf
{
using Module = std::string;
using Modules = kv::RawCopySerialisedMap<std::string, Module>;
using Modules = ccf::kv::RawCopySerialisedMap<std::string, Module>;
using ModulesQuickJsBytecode =
kv::RawCopySerialisedMap<std::string, std::vector<uint8_t>>;
using ModulesQuickJsVersion = kv::RawCopySerialisedValue<std::string>;
ccf::kv::RawCopySerialisedMap<std::string, std::vector<uint8_t>>;
using ModulesQuickJsVersion = ccf::kv::RawCopySerialisedValue<std::string>;
using InterpreterFlush = ServiceValue<bool>;
namespace Tables

Просмотреть файл

@ -18,7 +18,7 @@ namespace ccf
{
using Nodes = ServiceMap<NodeId, NodeInfo>;
using NodeEndorsedCertificates =
kv::RawCopySerialisedMap<NodeId, ccf::crypto::Pem>;
ccf::kv::RawCopySerialisedMap<NodeId, ccf::crypto::Pem>;
namespace Tables
{

Просмотреть файл

@ -31,7 +31,8 @@ namespace ccf
/// Status of the service
ServiceStatus status = ServiceStatus::OPENING;
/// Version (seqno) of previous service identity (before the last recovery)
std::optional<kv::Version> previous_service_identity_version = std::nullopt;
std::optional<ccf::kv::Version> previous_service_identity_version =
std::nullopt;
/// Number of disaster recoveries performed on this service
std::optional<size_t> recovery_count = std::nullopt;
/// Free-form user data, can be used by members to store additional

Просмотреть файл

@ -28,7 +28,7 @@ namespace ccf
DECLARE_JSON_TYPE(UserDetails)
DECLARE_JSON_REQUIRED_FIELDS(UserDetails, user_data)
using UserCerts = kv::RawCopySerialisedMap<UserId, ccf::crypto::Pem>;
using UserCerts = ccf::kv::RawCopySerialisedMap<UserId, ccf::crypto::Pem>;
using UserInfo = ServiceMap<UserId, UserDetails>;
namespace Tables

Просмотреть файл

@ -12,7 +12,7 @@
#include <optional>
#include <string>
namespace kv
namespace ccf::kv
{
class AbstractHandle;
class AbstractMap;
@ -196,7 +196,7 @@ namespace kv
* type-safety, prefer restricted handles returned by @c ro or @c wo where
* possible, rather than the general @c rw.
*
* @see kv::ReadOnlyTx
* @see ccf::kv::ReadOnlyTx
*/
class Tx : public ReadOnlyTx
{

Просмотреть файл

@ -18,7 +18,7 @@ using namespace nlohmann;
namespace basicapp
{
using RecordsMap = kv::Map<string, std::vector<uint8_t>>;
using RecordsMap = ccf::kv::Map<string, std::vector<uint8_t>>;
static constexpr auto PRIVATE_RECORDS = "records";
class BasicHandlers : public ccf::UserEndpointRegistry

Просмотреть файл

@ -8,7 +8,7 @@
namespace ccfapp
{
std::optional<ccf::ClaimsDigest::Digest> get_create_tx_claims_digest(
kv::ReadOnlyTx& tx)
ccf::kv::ReadOnlyTx& tx)
{
auto constitution =
tx.ro<ccf::Constitution>(ccf::Tables::CONSTITUTION)->get();

Просмотреть файл

@ -28,7 +28,7 @@ using namespace nlohmann;
namespace loggingapp
{
// SNIPPET: table_definition
using RecordsMap = kv::Map<size_t, string>;
using RecordsMap = ccf::kv::Map<size_t, string>;
static constexpr auto PUBLIC_RECORDS = "public:records";
static constexpr auto PRIVATE_RECORDS = "records";
@ -71,7 +71,7 @@ namespace loggingapp
{
public:
std::unique_ptr<ccf::AuthnIdentity> authenticate(
kv::ReadOnlyTx&,
ccf::kv::ReadOnlyTx&,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason) override
{
@ -169,7 +169,7 @@ namespace loggingapp
{}
void handle_committed_transaction(
const ccf::TxID& tx_id, const kv::ReadOnlyStorePtr& store)
const ccf::TxID& tx_id, const ccf::kv::ReadOnlyStorePtr& store)
{
std::lock_guard<std::mutex> lock(txid_lock);
auto tx_diff = store->create_tx_diff();
@ -1571,7 +1571,7 @@ namespace loggingapp
// Fetch the requested range
auto& historical_cache = context.get_historical_state();
std::vector<kv::ReadOnlyStorePtr> stores;
std::vector<ccf::kv::ReadOnlyStorePtr> stores;
if (!interesting_seqnos->empty())
{
stores =

Просмотреть файл

@ -19,7 +19,7 @@ using namespace nlohmann;
namespace programmabilityapp
{
using RecordsMap = kv::Map<std::string, std::vector<uint8_t>>;
using RecordsMap = ccf::kv::Map<std::string, std::vector<uint8_t>>;
static constexpr auto PRIVATE_RECORDS = "programmability.records";
static constexpr auto CUSTOM_ENDPOINTS_NAMESPACE = "public:custom_endpoints";
@ -43,9 +43,11 @@ namespace programmabilityapp
// This is a pure helper function which can be called from either C++ or JS,
// to implement common functionality in a single place
static inline bool has_role_permitting_action(
kv::ReadOnlyTx& tx, const std::string& user_id, const std::string& action)
ccf::kv::ReadOnlyTx& tx,
const std::string& user_id,
const std::string& action)
{
using RoleSet = kv::Set<std::string>;
using RoleSet = ccf::kv::Set<std::string>;
auto users_handle = tx.ro<ccf::UserInfo>(ccf::Tables::USER_INFO);
const auto user_info = users_handle->get(user_id);
@ -77,9 +79,9 @@ namespace programmabilityapp
// this extension object.
// In this case, since the extension adds a function that wants to read from
// the KV, it needs the current request's Tx.
kv::ReadOnlyTx* tx;
ccf::kv::ReadOnlyTx* tx;
MyExtension(kv::ReadOnlyTx* t) : tx(t) {}
MyExtension(ccf::kv::ReadOnlyTx* t) : tx(t) {}
void install(ccf::js::core::Context& ctx) override;
};
@ -113,7 +115,7 @@ namespace programmabilityapp
return JS_ThrowInternalError(ctx, "No transaction available");
}
kv::ReadOnlyTx& tx = *tx_ptr;
ccf::kv::ReadOnlyTx& tx = *tx_ptr;
// Process the arguments passed to the JS function, confirming they're both
// strings

Просмотреть файл

@ -36,7 +36,7 @@
namespace ccfapp
{
using namespace std;
using namespace kv;
using namespace ccf::kv;
using namespace ccf;
class JSHandlers : public UserEndpointRegistry
@ -592,7 +592,7 @@ namespace ccfapp
}
ccf::endpoints::EndpointDefinitionPtr find_endpoint(
kv::Tx& tx, ccf::RpcContext& rpc_ctx) override
ccf::kv::Tx& tx, ccf::RpcContext& rpc_ctx) override
{
const auto method = rpc_ctx.get_method();
const auto verb = rpc_ctx.get_request_verb();
@ -685,7 +685,7 @@ namespace ccfapp
}
std::set<RESTVerb> get_allowed_verbs(
kv::Tx& tx, const ccf::RpcContext& rpc_ctx) override
ccf::kv::Tx& tx, const ccf::RpcContext& rpc_ctx) override
{
const auto method = rpc_ctx.get_method();
@ -751,7 +751,7 @@ namespace ccfapp
// Since we do our own dispatch within the default handler, report the
// supported methods here
void build_api(nlohmann::json& document, kv::ReadOnlyTx& tx) override
void build_api(nlohmann::json& document, ccf::kv::ReadOnlyTx& tx) override
{
UserEndpointRegistry::build_api(document, tx);

Просмотреть файл

@ -19,10 +19,10 @@
namespace tpcc
{
template <typename T>
kv::serialisers::SerialisedEntry tpcc_serialise(const T& t);
ccf::kv::serialisers::SerialisedEntry tpcc_serialise(const T& t);
template <typename T>
T tpcc_deserialise(const kv::serialisers::SerialisedEntry& rep);
T tpcc_deserialise(const ccf::kv::serialisers::SerialisedEntry& rep);
template <typename T>
constexpr size_t serialised_size()
@ -106,9 +106,9 @@ namespace tpcc
_Pragma("clang diagnostic push"); \
_Pragma("clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\""); \
template <> \
kv::serialisers::SerialisedEntry tpcc_serialise(const TYPE& t) \
ccf::kv::serialisers::SerialisedEntry tpcc_serialise(const TYPE& t) \
{ \
kv::serialisers::SerialisedEntry rep; \
ccf::kv::serialisers::SerialisedEntry rep; \
constexpr size_t required_size = 0 _FOR_JSON_COUNT_NN(__VA_ARGS__)(POP1)( \
ADD_SERIALIZED_SIZE, TYPE, ##__VA_ARGS__); \
rep.resize(required_size); \
@ -118,7 +118,7 @@ namespace tpcc
return rep; \
} \
template <> \
TYPE tpcc_deserialise(const kv::serialisers::SerialisedEntry& rep) \
TYPE tpcc_deserialise(const ccf::kv::serialisers::SerialisedEntry& rep) \
{ \
auto data = rep.data(); \
auto size = rep.size(); \
@ -132,12 +132,12 @@ namespace tpcc
template <typename T>
struct TpccSerialiser
{
static kv::serialisers::SerialisedEntry to_serialised(const T& t)
static ccf::kv::serialisers::SerialisedEntry to_serialised(const T& t)
{
return tpcc_serialise(t);
}
static T from_serialised(const kv::serialisers::SerialisedEntry& rep)
static T from_serialised(const ccf::kv::serialisers::SerialisedEntry& rep)
{
return tpcc_deserialise<T>(rep);
}
@ -539,7 +539,7 @@ namespace tpcc
History, c_id, c_d_id, c_w_id, d_id, w_id, amount, date, data);
template <typename K, typename V>
using TpccMap = kv::MapSerialisedWith<K, V, TpccSerialiser>;
using TpccMap = ccf::kv::MapSerialisedWith<K, V, TpccSerialiser>;
struct TpccTables
{

Просмотреть файл

@ -19,12 +19,12 @@ namespace aft
class ViewHistory
{
// Entry i stores the first version in view i+1
std::vector<kv::Version> views;
std::vector<ccf::kv::Version> views;
public:
static constexpr ccf::View InvalidView = ccf::VIEW_UNKNOWN;
void initialise(const std::vector<kv::Version>& terms_)
void initialise(const std::vector<ccf::kv::Version>& terms_)
{
views.clear();
for (size_t i = 0; i < terms_.size(); ++i)
@ -34,7 +34,7 @@ namespace aft
LOG_DEBUG_FMT("Initialised views: {}", fmt::join(views, ", "));
}
void update(kv::Version idx, ccf::View view)
void update(ccf::kv::Version idx, ccf::View view)
{
LOG_DEBUG_FMT("Updating view to: {} at version: {}", view, idx);
if (!views.empty())
@ -56,7 +56,7 @@ namespace aft
LOG_DEBUG_FMT("Resulting views: {}", fmt::join(views, ", "));
}
ccf::View view_at(kv::Version idx)
ccf::View view_at(ccf::kv::Version idx)
{
auto it = upper_bound(views.begin(), views.end(), idx);
@ -69,11 +69,11 @@ namespace aft
return (it - views.begin());
}
kv::Version start_of_view(ccf::View view)
ccf::kv::Version start_of_view(ccf::View view)
{
if (view > views.size() || view == InvalidView)
{
return kv::NoVersion;
return ccf::kv::NoVersion;
}
// NB: If views == {5, 10, 10}, then view 2 doesn't start at 10. View 2
@ -81,23 +81,23 @@ namespace aft
const auto tentative = views[view - 1];
if (view + 1 <= views.size() && views[view] == tentative)
{
return kv::NoVersion;
return ccf::kv::NoVersion;
}
return tentative;
}
kv::Version end_of_view(ccf::View view)
ccf::kv::Version end_of_view(ccf::View view)
{
// If this view has no start (potentially because it contains no
// transactions), then it can't have an end
if (start_of_view(view) == kv::NoVersion)
if (start_of_view(view) == ccf::kv::NoVersion)
{
return kv::NoVersion;
return ccf::kv::NoVersion;
}
if (view >= views.size() || view == InvalidView)
{
return kv::NoVersion;
return ccf::kv::NoVersion;
}
// Otherwise the end of this view is the transaction before (- 1) the
@ -105,14 +105,14 @@ namespace aft
return views[view] - 1;
}
std::vector<kv::Version> get_history_until(
kv::Version idx = std::numeric_limits<kv::Version>::max())
std::vector<ccf::kv::Version> get_history_until(
ccf::kv::Version idx = std::numeric_limits<ccf::kv::Version>::max())
{
return {views.begin(), std::upper_bound(views.begin(), views.end(), idx)};
}
// view should be non-zero as views start at one in here
std::vector<kv::Version> get_history_since(uint64_t view)
std::vector<ccf::kv::Version> get_history_since(uint64_t view)
{
if (view > views.size())
{
@ -121,7 +121,7 @@ namespace aft
return {views.begin() + view - 1, views.end()};
}
void rollback(kv::Version idx)
void rollback(ccf::kv::Version idx)
{
auto it = upper_bound(views.begin(), views.end(), idx);
views.erase(it, views.end());
@ -157,8 +157,8 @@ namespace aft
ccf::NodeId node_id;
ccf::View current_view = 0;
kv::Version last_idx = 0;
kv::Version commit_idx = 0;
ccf::kv::Version last_idx = 0;
ccf::kv::Version commit_idx = 0;
ViewHistory view_history;
// Indices that are eligible for global commit, from a Node's perspective
@ -176,10 +176,11 @@ namespace aft
// the node
// Leader -> Follower, when receiving entries for a newer term
// Candidate -> Follower, when receiving entries for a newer term
kv::LeadershipState leadership_state = kv::LeadershipState::None;
kv::MembershipState membership_state = kv::MembershipState::Active;
ccf::kv::LeadershipState leadership_state = ccf::kv::LeadershipState::None;
ccf::kv::MembershipState membership_state =
ccf::kv::MembershipState::Active;
std::optional<kv::RetirementPhase> retirement_phase = std::nullopt;
std::optional<ccf::kv::RetirementPhase> retirement_phase = std::nullopt;
// Index at which this node observes its retirement
std::optional<ccf::SeqNo> retirement_idx = std::nullopt;
// Earliest index at which this node's retirement can be committed

Просмотреть файл

@ -89,10 +89,10 @@ static inline void add_committable_indices_start_and_end(
namespace aft
{
using Configuration = kv::Configuration;
using Configuration = ccf::kv::Configuration;
template <class LedgerProxy>
class Aft : public kv::Consensus
class Aft : public ccf::kv::Consensus
{
private:
struct NodeState
@ -216,8 +216,8 @@ namespace aft
std::shared_ptr<aft::State> state_,
std::shared_ptr<ccf::NodeClient> rpc_request_context_,
bool public_only_ = false,
kv::MembershipState initial_membership_state_ =
kv::MembershipState::Active,
ccf::kv::MembershipState initial_membership_state_ =
ccf::kv::MembershipState::Active,
ReconfigurationType reconfiguration_type_ =
ReconfigurationType::ONE_TRANSACTION) :
store(std::move(store_)),
@ -258,12 +258,12 @@ namespace aft
bool is_primary() override
{
return state->leadership_state == kv::LeadershipState::Leader;
return state->leadership_state == ccf::kv::LeadershipState::Leader;
}
bool is_candidate() override
{
return state->leadership_state == kv::LeadershipState::Candidate;
return state->leadership_state == ccf::kv::LeadershipState::Candidate;
}
bool can_replicate() override
@ -284,7 +284,7 @@ namespace aft
return false;
}
std::unique_lock<ccf::pal::Mutex> guard(state->lock);
return state->leadership_state == kv::LeadershipState::Leader &&
return state->leadership_state == ccf::kv::LeadershipState::Leader &&
(state->last_idx - state->commit_idx >= max_uncommitted_tx_count);
}
@ -310,46 +310,46 @@ namespace aft
bool is_backup() override
{
return state->leadership_state == kv::LeadershipState::Follower;
return state->leadership_state == ccf::kv::LeadershipState::Follower;
}
bool is_active() const
{
return state->membership_state == kv::MembershipState::Active;
return state->membership_state == ccf::kv::MembershipState::Active;
}
bool is_retired() const
{
return state->membership_state == kv::MembershipState::Retired;
return state->membership_state == ccf::kv::MembershipState::Retired;
}
bool is_retired_committed() const
{
return state->membership_state == kv::MembershipState::Retired &&
state->retirement_phase == kv::RetirementPhase::RetiredCommitted;
return state->membership_state == ccf::kv::MembershipState::Retired &&
state->retirement_phase == ccf::kv::RetirementPhase::RetiredCommitted;
}
bool is_retired_completed() const
{
return state->membership_state == kv::MembershipState::Retired &&
state->retirement_phase == kv::RetirementPhase::Completed;
return state->membership_state == ccf::kv::MembershipState::Retired &&
state->retirement_phase == ccf::kv::RetirementPhase::Completed;
}
void set_retired_committed(
ccf::SeqNo seqno, const std::vector<kv::NodeId>& node_ids) override
ccf::SeqNo seqno, const std::vector<ccf::kv::NodeId>& node_ids) override
{
for (auto& node_id : node_ids)
{
if (id() == node_id)
{
CCF_ASSERT(
state->membership_state == kv::MembershipState::Retired,
state->membership_state == ccf::kv::MembershipState::Retired,
"Node is not retired, cannot become retired committed");
CCF_ASSERT(
state->retirement_phase == kv::RetirementPhase::Completed,
state->retirement_phase == ccf::kv::RetirementPhase::Completed,
"Node is not retired, cannot become retired committed");
state->retired_committed_idx = seqno;
become_retired(seqno, kv::RetirementPhase::RetiredCommitted);
become_retired(seqno, ccf::kv::RetirementPhase::RetiredCommitted);
}
else
{
@ -531,7 +531,7 @@ namespace aft
public:
void add_configuration(
Index idx,
const kv::Configuration::Nodes& conf,
const ccf::kv::Configuration::Nodes& conf,
const std::unordered_set<ccf::NodeId>& new_learner_nodes = {},
const std::unordered_set<ccf::NodeId>& new_retired_nodes = {}) override
{
@ -561,7 +561,7 @@ namespace aft
configurations.back().nodes.end() &&
conf.find(state->node_id) == conf.end())
{
become_retired(idx, kv::RetirementPhase::Ordered);
become_retired(idx, ccf::kv::RetirementPhase::Ordered);
}
if (conf != configurations.back().nodes)
@ -606,9 +606,9 @@ namespace aft
return get_latest_configuration_unsafe();
}
kv::ConsensusDetails get_details() override
ccf::kv::ConsensusDetails get_details() override
{
kv::ConsensusDetails details;
ccf::kv::ConsensusDetails details;
std::lock_guard<ccf::pal::Mutex> guard(state->lock);
details.primary_id = leader_id;
details.current_view = state->current_view;
@ -632,11 +632,11 @@ namespace aft
return details;
}
bool replicate(const kv::BatchVector& entries, Term term) override
bool replicate(const ccf::kv::BatchVector& entries, Term term) override
{
std::lock_guard<ccf::pal::Mutex> guard(state->lock);
if (state->leadership_state != kv::LeadershipState::Leader)
if (state->leadership_state != ccf::kv::LeadershipState::Leader)
{
RAFT_DEBUG_FMT(
"Failed to replicate {} items: not leader", entries.size());
@ -702,10 +702,10 @@ namespace aft
state->membership_state,
state->leadership_state);
if (
state->membership_state == kv::MembershipState::Retired &&
state->retirement_phase == kv::RetirementPhase::Ordered)
state->membership_state == ccf::kv::MembershipState::Retired &&
state->retirement_phase == ccf::kv::RetirementPhase::Ordered)
{
become_retired(index, kv::RetirementPhase::Signed);
become_retired(index, ccf::kv::RetirementPhase::Signed);
}
state->committable_indices.push_back(index);
start_ticking_if_necessary();
@ -825,7 +825,7 @@ namespace aft
std::unique_lock<ccf::pal::Mutex> guard(state->lock);
timeout_elapsed += elapsed;
if (state->leadership_state == kv::LeadershipState::Leader)
if (state->leadership_state == ccf::kv::LeadershipState::Leader)
{
if (timeout_elapsed >= request_timeout)
{
@ -962,13 +962,13 @@ namespace aft
bool can_replicate_unsafe()
{
return state->leadership_state == kv::LeadershipState::Leader &&
return state->leadership_state == ccf::kv::LeadershipState::Leader &&
!is_retired_committed();
}
bool can_sign_unsafe()
{
return state->leadership_state == kv::LeadershipState::Leader &&
return state->leadership_state == ccf::kv::LeadershipState::Leader &&
!is_retired_committed();
}
@ -998,7 +998,7 @@ namespace aft
const auto term_of_ae = state->view_history.view_at(start);
const auto index_at_end_of_term =
state->view_history.end_of_view(term_of_ae);
if (index_at_end_of_term != kv::NoVersion)
if (index_at_end_of_term != ccf::kv::NoVersion)
{
max_idx = index_at_end_of_term;
}
@ -1116,7 +1116,7 @@ namespace aft
// follower if necessary
if (
state->current_view == r.term &&
state->leadership_state == kv::LeadershipState::Candidate)
state->leadership_state == ccf::kv::LeadershipState::Candidate)
{
become_aware_of_new_term(r.term);
}
@ -1216,8 +1216,9 @@ namespace aft
r.idx,
r.prev_idx);
std::vector<
std::tuple<std::unique_ptr<kv::AbstractExecutionWrapper>, kv::Version>>
std::vector<std::tuple<
std::unique_ptr<ccf::kv::AbstractExecutionWrapper>,
ccf::kv::Version>>
append_entries;
// Finally, deserialise each entry in the batch
for (Index i = r.prev_idx + 1; i <= r.idx; i++)
@ -1299,7 +1300,7 @@ namespace aft
return;
}
kv::TxID expected{r.term_of_idx, i};
ccf::kv::TxID expected{r.term_of_idx, i};
auto ds = store->deserialize(entry, public_only, expected);
if (ds == nullptr)
{
@ -1321,8 +1322,8 @@ namespace aft
void execute_append_entries_sync(
std::vector<std::tuple<
std::unique_ptr<kv::AbstractExecutionWrapper>,
kv::Version>>&& append_entries,
std::unique_ptr<ccf::kv::AbstractExecutionWrapper>,
ccf::kv::Version>>&& append_entries,
const ccf::NodeId& from,
AppendEntries&& r)
{
@ -1341,9 +1342,9 @@ namespace aft
#endif
bool track_deletes_on_missing_keys = false;
kv::ApplyResult apply_success =
ccf::kv::ApplyResult apply_success =
ds->apply(track_deletes_on_missing_keys);
if (apply_success == kv::ApplyResult::FAIL)
if (apply_success == ccf::kv::ApplyResult::FAIL)
{
ledger->truncate(i - 1);
send_append_entries_response_nack(from);
@ -1357,7 +1358,7 @@ namespace aft
}
bool globally_committable =
(apply_success == kv::ApplyResult::PASS_SIGNATURE);
(apply_success == ccf::kv::ApplyResult::PASS_SIGNATURE);
if (globally_committable)
{
start_ticking_if_necessary();
@ -1370,7 +1371,7 @@ namespace aft
switch (apply_success)
{
case kv::ApplyResult::FAIL:
case ccf::kv::ApplyResult::FAIL:
{
RAFT_FAIL_FMT("Follower failed to apply log entry: {}", i);
state->last_idx--;
@ -1379,14 +1380,14 @@ namespace aft
break;
}
case kv::ApplyResult::PASS_SIGNATURE:
case ccf::kv::ApplyResult::PASS_SIGNATURE:
{
RAFT_DEBUG_FMT("Deserialising signature at {}", i);
if (
state->membership_state == kv::MembershipState::Retired &&
state->retirement_phase == kv::RetirementPhase::Ordered)
state->membership_state == ccf::kv::MembershipState::Retired &&
state->retirement_phase == ccf::kv::RetirementPhase::Ordered)
{
become_retired(i, kv::RetirementPhase::Signed);
become_retired(i, ccf::kv::RetirementPhase::Signed);
}
state->committable_indices.push_back(i);
@ -1416,12 +1417,12 @@ namespace aft
break;
}
case kv::ApplyResult::PASS:
case ccf::kv::ApplyResult::PASS:
{
break;
}
case kv::ApplyResult::PASS_ENCRYPTED_PAST_LEDGER_SECRET:
case ccf::kv::ApplyResult::PASS_ENCRYPTED_PAST_LEDGER_SECRET:
{
break;
}
@ -1560,7 +1561,7 @@ namespace aft
#endif
// Ignore if we're not the leader.
if (state->leadership_state != kv::LeadershipState::Leader)
if (state->leadership_state != ccf::kv::LeadershipState::Leader)
{
RAFT_FAIL_FMT(
"Recv append entries response to {} from {}: no longer leader",
@ -1811,7 +1812,7 @@ namespace aft
RAFT_TRACE_JSON_OUT(j);
#endif
if (state->leadership_state != kv::LeadershipState::Candidate)
if (state->leadership_state != ccf::kv::LeadershipState::Candidate)
{
RAFT_INFO_FMT(
"Recv request vote response to {} from: {}: we aren't a candidate",
@ -1929,7 +1930,7 @@ namespace aft
return;
}
state->leadership_state = kv::LeadershipState::Candidate;
state->leadership_state = ccf::kv::LeadershipState::Candidate;
leader_id.reset();
voted_for = state->node_id;
@ -1986,7 +1987,7 @@ namespace aft
store->initialise_term(state->current_view);
}
state->leadership_state = kv::LeadershipState::Leader;
state->leadership_state = ccf::kv::LeadershipState::Leader;
leader_id = state->node_id;
should_sign = true;
@ -2045,7 +2046,7 @@ namespace aft
// receiving a conflicting AppendEntries
rollback(last_committable_index());
state->leadership_state = kv::LeadershipState::Follower;
state->leadership_state = ccf::kv::LeadershipState::Follower;
RAFT_INFO_FMT(
"Becoming follower {}: {}.{}",
state->node_id,
@ -2077,7 +2078,7 @@ namespace aft
}
private:
void become_retired(Index idx, kv::RetirementPhase phase)
void become_retired(Index idx, ccf::kv::RetirementPhase phase)
{
RAFT_INFO_FMT(
"Becoming retired, phase {} (leadership {}): {}: {} at {}",
@ -2087,7 +2088,7 @@ namespace aft
state->current_view,
idx);
if (phase == kv::RetirementPhase::Ordered)
if (phase == ccf::kv::RetirementPhase::Ordered)
{
CCF_ASSERT_FMT(
!state->retirement_idx.has_value(),
@ -2096,7 +2097,7 @@ namespace aft
state->retirement_idx = idx;
RAFT_INFO_FMT("Node retiring at {}", idx);
}
else if (phase == kv::RetirementPhase::Signed)
else if (phase == ccf::kv::RetirementPhase::Signed)
{
assert(state->retirement_idx.has_value());
CCF_ASSERT_FMT(
@ -2107,15 +2108,15 @@ namespace aft
state->retirement_committable_idx = idx;
RAFT_INFO_FMT("Node retirement committable at {}", idx);
}
else if (phase == kv::RetirementPhase::RetiredCommitted)
else if (phase == ccf::kv::RetirementPhase::RetiredCommitted)
{
if (state->leadership_state == kv::LeadershipState::Leader)
if (state->leadership_state == ccf::kv::LeadershipState::Leader)
{
ProposeRequestVote prv{.term = state->current_view};
std::optional<ccf::NodeId> successor = std::nullopt;
Index max_match_idx = 0;
kv::ReconfigurationId reconf_id_of_max_match = 0;
ccf::kv::ReconfigurationId reconf_id_of_max_match = 0;
// Pick the node that has the highest match_idx, and break
// ties by looking at the highest reconfiguration id they are
@ -2131,7 +2132,7 @@ namespace aft
{
if (node_state.match_idx >= max_match_idx)
{
kv::ReconfigurationId latest_reconf_id = 0;
ccf::kv::ReconfigurationId latest_reconf_id = 0;
auto conf = configurations.rbegin();
while (conf != configurations.rend())
{
@ -2160,10 +2161,10 @@ namespace aft
}
leader_id.reset();
state->leadership_state = kv::LeadershipState::None;
state->leadership_state = ccf::kv::LeadershipState::None;
}
state->membership_state = kv::MembershipState::Retired;
state->membership_state = ccf::kv::MembershipState::Retired;
state->retirement_phase = phase;
}
@ -2221,7 +2222,7 @@ namespace aft
// idx.
void update_commit()
{
if (state->leadership_state != kv::LeadershipState::Leader)
if (state->leadership_state != ccf::kv::LeadershipState::Leader)
{
throw std::logic_error(
"update_commit() must only be called while this node is leader");
@ -2357,11 +2358,11 @@ namespace aft
state->commit_idx = idx;
if (
is_retired() &&
state->retirement_phase == kv::RetirementPhase::Signed &&
state->retirement_phase == ccf::kv::RetirementPhase::Signed &&
state->retirement_committable_idx.has_value() &&
idx >= state->retirement_committable_idx.value())
{
become_retired(idx, kv::RetirementPhase::Completed);
become_retired(idx, ccf::kv::RetirementPhase::Completed);
}
RAFT_DEBUG_FMT("Compacting...");
@ -2457,27 +2458,27 @@ namespace aft
}
if (
state->membership_state == kv::MembershipState::Retired &&
state->retirement_phase == kv::RetirementPhase::Signed)
state->membership_state == ccf::kv::MembershipState::Retired &&
state->retirement_phase == ccf::kv::RetirementPhase::Signed)
{
assert(state->retirement_committable_idx.has_value());
if (state->retirement_committable_idx.value() > idx)
{
state->retirement_committable_idx = std::nullopt;
state->retirement_phase = kv::RetirementPhase::Ordered;
state->retirement_phase = ccf::kv::RetirementPhase::Ordered;
}
}
if (
state->membership_state == kv::MembershipState::Retired &&
state->retirement_phase == kv::RetirementPhase::Ordered)
state->membership_state == ccf::kv::MembershipState::Retired &&
state->retirement_phase == ccf::kv::RetirementPhase::Ordered)
{
assert(state->retirement_idx.has_value());
if (state->retirement_idx.value() > idx)
{
state->retirement_idx = std::nullopt;
state->retirement_phase = std::nullopt;
state->membership_state = kv::MembershipState::Active;
state->membership_state = ccf::kv::MembershipState::Active;
RAFT_DEBUG_FMT("Becoming Active after rollback");
}
}
@ -2558,7 +2559,7 @@ namespace aft
all_other_nodes.try_emplace(
node_info.first, node_info.second, index, 0);
if (state->leadership_state == kv::LeadershipState::Leader)
if (state->leadership_state == ccf::kv::LeadershipState::Leader)
{
send_append_entries(node_info.first, index);
}

Просмотреть файл

@ -23,7 +23,7 @@ namespace aft
using ReplyCallback = std::function<bool(
void* owner,
kv::TxHistory::RequestID caller_rid,
ccf::kv::TxHistory::RequestID caller_rid,
int status,
std::vector<uint8_t>&& data)>;
@ -34,12 +34,13 @@ namespace aft
public:
virtual ~Store() {}
virtual void compact(Index v) = 0;
virtual void rollback(const kv::TxID& tx_id, Term term_of_next_version) = 0;
virtual void rollback(
const ccf::kv::TxID& tx_id, Term term_of_next_version) = 0;
virtual void initialise_term(Term t) = 0;
virtual std::unique_ptr<kv::AbstractExecutionWrapper> deserialize(
virtual std::unique_ptr<ccf::kv::AbstractExecutionWrapper> deserialize(
const std::vector<uint8_t> data,
bool public_only = false,
const std::optional<kv::TxID>& expected_txid = std::nullopt) = 0;
const std::optional<ccf::kv::TxID>& expected_txid = std::nullopt) = 0;
};
template <typename T>
@ -60,7 +61,8 @@ namespace aft
}
}
void rollback(const kv::TxID& tx_id, Term term_of_next_version) override
void rollback(
const ccf::kv::TxID& tx_id, Term term_of_next_version) override
{
auto p = x.lock();
if (p)
@ -78,10 +80,10 @@ namespace aft
}
}
std::unique_ptr<kv::AbstractExecutionWrapper> deserialize(
std::unique_ptr<ccf::kv::AbstractExecutionWrapper> deserialize(
const std::vector<uint8_t> data,
bool public_only = false,
const std::optional<kv::TxID>& expected_txid = std::nullopt) override
const std::optional<ccf::kv::TxID>& expected_txid = std::nullopt) override
{
auto p = x.lock();
if (p)

Просмотреть файл

@ -205,7 +205,7 @@ DOCTEST_TEST_CASE("Retention of dead leader's commit")
DOCTEST_INFO("Entry at 1.1 is received by all nodes");
{
auto entry = make_ledger_entry(1, 1);
rA.replicate(kv::BatchVector{{1, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{1, entry, true, hooks}}, 1);
DOCTEST_REQUIRE(rA.get_last_idx() == 1);
DOCTEST_REQUIRE(rA.get_committed_seqno() == 0);
// Size limit was reached, so periodic is not needed
@ -235,21 +235,21 @@ DOCTEST_TEST_CASE("Retention of dead leader's commit")
"committed");
{
auto entry = make_ledger_entry(1, 2);
rA.replicate(kv::BatchVector{{2, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{2, entry, true, hooks}}, 1);
DOCTEST_REQUIRE(rA.get_last_idx() == 2);
DOCTEST_REQUIRE(rA.get_committed_seqno() == 1);
// Size limit was reached, so periodic is not needed
// rA.periodic(request_timeout);
entry = make_ledger_entry(1, 3);
rA.replicate(kv::BatchVector{{3, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{3, entry, true, hooks}}, 1);
DOCTEST_REQUIRE(rA.get_last_idx() == 3);
DOCTEST_REQUIRE(rA.get_committed_seqno() == 1);
// Size limit was reached, so periodic is not needed
// rA.periodic(request_timeout);
entry = make_ledger_entry(1, 4);
rA.replicate(kv::BatchVector{{4, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{4, entry, true, hooks}}, 1);
DOCTEST_REQUIRE(rA.get_last_idx() == 4);
DOCTEST_REQUIRE(rA.get_committed_seqno() == 1);
// Size limit was reached, so periodic is not needed
@ -283,7 +283,7 @@ DOCTEST_TEST_CASE("Retention of dead leader's commit")
"committed");
{
auto entry = make_ledger_entry(1, 5);
rA.replicate(kv::BatchVector{{5, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{5, entry, true, hooks}}, 1);
DOCTEST_REQUIRE(rA.get_last_idx() == 5);
// Size limit was reached, so periodic is not needed
// rB.periodic(request_timeout);
@ -350,11 +350,11 @@ DOCTEST_TEST_CASE("Retention of dead leader's commit")
DOCTEST_INFO("Node B writes some entries, though they are lost");
{
auto entry = make_ledger_entry(2, 6);
rB.replicate(kv::BatchVector{{6, entry, true, hooks}}, 2);
rB.replicate(ccf::kv::BatchVector{{6, entry, true, hooks}}, 2);
DOCTEST_REQUIRE(rB.get_last_idx() == 6);
entry = make_ledger_entry(2, 7);
rB.replicate(kv::BatchVector{{7, entry, true, hooks}}, 2);
rB.replicate(ccf::kv::BatchVector{{7, entry, true, hooks}}, 2);
DOCTEST_REQUIRE(rB.get_last_idx() == 7);
// Size limit was reached, so periodic is not needed
@ -401,15 +401,15 @@ DOCTEST_TEST_CASE("Retention of dead leader's commit")
DOCTEST_REQUIRE("Node C produces 3.5, 3.6, and 3.7");
{
auto entry = make_ledger_entry(3, 5);
rC.replicate(kv::BatchVector{{5, entry, true, hooks}}, 3);
rC.replicate(ccf::kv::BatchVector{{5, entry, true, hooks}}, 3);
DOCTEST_REQUIRE(rC.get_last_idx() == 5);
entry = make_ledger_entry(3, 6);
rC.replicate(kv::BatchVector{{6, entry, true, hooks}}, 3);
rC.replicate(ccf::kv::BatchVector{{6, entry, true, hooks}}, 3);
DOCTEST_REQUIRE(rC.get_last_idx() == 6);
entry = make_ledger_entry(3, 7);
rC.replicate(kv::BatchVector{{7, entry, true, hooks}}, 3);
rC.replicate(ccf::kv::BatchVector{{7, entry, true, hooks}}, 3);
DOCTEST_REQUIRE(rC.get_last_idx() == 7);
// The early AppendEntries that describe this are lost
@ -598,7 +598,7 @@ DOCTEST_TEST_CASE_TEMPLATE("Multi-term divergence", T, WorstCase, RandomCase)
{
auto entry = make_ledger_entry(primary.get_view(), idx);
primary.replicate(
kv::BatchVector{{idx, entry, true, hooks}}, primary.get_view());
ccf::kv::BatchVector{{idx, entry, true, hooks}}, primary.get_view());
}
// All related AppendEntries are lost
@ -627,9 +627,9 @@ DOCTEST_TEST_CASE_TEMPLATE("Multi-term divergence", T, WorstCase, RandomCase)
// be committed
auto entry = make_ledger_entry(1, 1);
rA.replicate(kv::BatchVector{{1, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{1, entry, true, hooks}}, 1);
entry = make_ledger_entry(1, 2);
rA.replicate(kv::BatchVector{{2, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{2, entry, true, hooks}}, 1);
DOCTEST_REQUIRE(rA.get_last_idx() == 2);
DOCTEST_REQUIRE(rA.get_committed_seqno() == 0);
// Size limit was reached, so periodic is not needed
@ -662,18 +662,18 @@ DOCTEST_TEST_CASE_TEMPLATE("Multi-term divergence", T, WorstCase, RandomCase)
// Node A produces 2 additional entries that A and B have, and 2 additional
// entries that are only present on A
entry = make_ledger_entry(1, 3);
rA.replicate(kv::BatchVector{{3, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{3, entry, true, hooks}}, 1);
entry = make_ledger_entry(1, 4);
rA.replicate(kv::BatchVector{{4, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{4, entry, true, hooks}}, 1);
keep_messages_for(node_idB, channelsA->messages);
DOCTEST_REQUIRE(2 == dispatch_all(nodes, node_idA));
entry = make_ledger_entry(1, 5);
rA.replicate(kv::BatchVector{{5, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{5, entry, true, hooks}}, 1);
entry = make_ledger_entry(1, 6);
rA.replicate(kv::BatchVector{{6, entry, true, hooks}}, 1);
rA.replicate(ccf::kv::BatchVector{{6, entry, true, hooks}}, 1);
channelsA->messages.clear();
channelsB->messages.clear();
@ -936,7 +936,7 @@ DOCTEST_TEST_CASE_TEMPLATE("Multi-term divergence", T, WorstCase, RandomCase)
const auto seqno = rPrimary.get_last_idx() + 1;
auto final_entry = make_ledger_entry(view, seqno);
rPrimary.replicate(
kv::BatchVector{{seqno, final_entry, true, hooks}}, view);
ccf::kv::BatchVector{{seqno, final_entry, true, hooks}}, view);
rPrimary.periodic(request_timeout);
keep_earliest_append_entries_for_each_target(channelsPrimary->messages);

Просмотреть файл

@ -48,8 +48,8 @@ struct LedgerStubProxy_Mermaid : public aft::LedgerStubProxy
void put_entry(
const std::vector<uint8_t>& data,
bool globally_committable,
kv::Term term,
kv::Version index) override
ccf::kv::Term term,
ccf::kv::Version index) override
{
RAFT_DRIVER_PRINT(
"{}->>{}: [ledger] appending: {}.{}={}",
@ -78,7 +78,7 @@ struct LoggingStubStore_Mermaid : public aft::LoggingStubStoreConfig
aft::LoggingStubStoreConfig::compact(idx);
}
void rollback(const kv::TxID& tx_id, aft::Term t) override
void rollback(const ccf::kv::TxID& tx_id, aft::Term t) override
{
RAFT_DRIVER_PRINT(
"{}->>{}: [KV] rolling back to {}.{}, in term {}",
@ -124,8 +124,9 @@ private:
std::vector<uint8_t> data,
const size_t lineno,
bool committable = false,
const std::optional<kv::Configuration::Nodes>& configuration = std::nullopt,
const std::optional<kv::Configuration::Nodes>& retired_committed =
const std::optional<ccf::kv::Configuration::Nodes>& configuration =
std::nullopt,
const std::optional<ccf::kv::Configuration::Nodes>& retired_committed =
std::nullopt)
{
const auto opt = find_primary_in_term(term_s, lineno);
@ -150,7 +151,7 @@ private:
configuration.has_value() ? "reconfiguration" : "raw");
aft::ReplicatedDataType type = aft::ReplicatedDataType::raw;
auto hooks = std::make_shared<kv::ConsensusHookPtrs>();
auto hooks = std::make_shared<ccf::kv::ConsensusHookPtrs>();
if (configuration.has_value() && retired_committed.has_value())
{
throw std::logic_error(
@ -184,7 +185,7 @@ private:
auto s = nlohmann::json(aft::ReplicatedData{type, data}).dump();
auto d = std::make_shared<std::vector<uint8_t>>(s.begin(), s.end());
raft->replicate(kv::BatchVector{{idx, d, committable, hooks}}, term);
raft->replicate(ccf::kv::BatchVector{{idx, d, committable, hooks}}, term);
}
void add_node(ccf::NodeId node_id)
@ -199,7 +200,7 @@ private:
std::make_shared<aft::State>(node_id),
nullptr);
kv->set_set_retired_committed_hook(
[raft](aft::Index idx, const std::vector<kv::NodeId>& node_ids) {
[raft](aft::Index idx, const std::vector<ccf::kv::NodeId>& node_ids) {
raft->set_retired_committed(idx, node_ids);
});
raft->start_ticking();
@ -220,7 +221,7 @@ public:
{
// Unrealistic way to create network. Initial configuration is automatically
// added to all nodes.
kv::Configuration::Nodes configuration;
ccf::kv::Configuration::Nodes configuration;
for (auto const& n : node_ids)
{
add_node(n);
@ -248,7 +249,7 @@ public:
{
throw std::logic_error("Start node already exists");
}
kv::Configuration::Nodes configuration;
ccf::kv::Configuration::Nodes configuration;
add_node(start_node_id);
configuration.try_emplace(start_node_id);
_nodes[start_node_id].raft->force_become_primary();
@ -264,7 +265,7 @@ public:
const std::vector<std::string>& node_ids,
const size_t lineno)
{
kv::Configuration::Nodes retired_committed;
ccf::kv::Configuration::Nodes retired_committed;
for (const auto& id : node_ids)
{
if (_nodes.find(id) == _nodes.end())
@ -288,7 +289,7 @@ public:
RAFT_DRIVER_PRINT(
"Note over {}: Node {} trusted", ccf::NodeId(node_id), node_id);
}
kv::Configuration::Nodes configuration;
ccf::kv::Configuration::Nodes configuration;
for (const auto& [id, node] : _nodes)
{
configuration.try_emplace(id);
@ -325,7 +326,7 @@ public:
}
std::set<std::string> out(nodes_out.begin(), nodes_out.end());
kv::Configuration::Nodes configuration;
ccf::kv::Configuration::Nodes configuration;
for (const auto& [id, node] : _nodes)
{
if (out.find(id) == out.end())
@ -352,7 +353,7 @@ public:
std::vector<std::string> node_ids,
const size_t lineno)
{
kv::Configuration::Nodes configuration;
ccf::kv::Configuration::Nodes configuration;
for (const auto& node_id_s : node_ids)
{
ccf::NodeId node_id(node_id_s);

Просмотреть файл

@ -73,9 +73,9 @@ TEST_CASE("Enclave record")
bool globally_committable = false;
const std::vector<uint8_t> entry = {'a', 'b', 'c'};
kv::SerialisedEntryHeader entry_header;
ccf::kv::SerialisedEntryHeader entry_header;
std::vector<uint8_t> tx(kv::serialised_entry_header_size + entry.size());
std::vector<uint8_t> tx(ccf::kv::serialised_entry_header_size + entry.size());
auto tx_ = tx.data();
auto size_ = tx.size();
serialized::write(tx_, size_, entry_header);

Просмотреть файл

@ -30,8 +30,8 @@ namespace aft
virtual void put_entry(
const std::vector<uint8_t>& original,
bool globally_committable,
kv::Term term,
kv::Version index)
ccf::kv::Term term,
ccf::kv::Version index)
{
std::lock_guard<std::mutex> lock(ledger_access);
@ -98,8 +98,8 @@ namespace aft
// Remove the View and Index that were written during put_entry
data->erase(
data->begin(),
data->begin() + sizeof(size_t) + sizeof(kv::Term) +
sizeof(kv::Version));
data->begin() + sizeof(size_t) + sizeof(ccf::kv::Term) +
sizeof(ccf::kv::Version));
}
return data;
@ -286,20 +286,21 @@ namespace aft
DECLARE_JSON_TYPE(ReplicatedData);
DECLARE_JSON_REQUIRED_FIELDS(ReplicatedData, type, data);
class ConfigurationChangeHook : public kv::ConsensusHook
class ConfigurationChangeHook : public ccf::kv::ConsensusHook
{
kv::Configuration::Nodes
ccf::kv::Configuration::Nodes
new_configuration; // Absence of node means that node has been retired
kv::Version version;
ccf::kv::Version version;
public:
ConfigurationChangeHook(
kv::Configuration::Nodes new_configuration_, kv::Version version_) :
ccf::kv::Configuration::Nodes new_configuration_,
ccf::kv::Version version_) :
new_configuration(new_configuration_),
version(version_)
{}
void call(kv::ConfigurableConsensus* consensus) override
void call(ccf::kv::ConfigurableConsensus* consensus) override
{
auto configuration = consensus->get_latest_configuration_unsafe();
std::unordered_set<ccf::NodeId> retired_nodes;
@ -329,7 +330,8 @@ namespace aft
}
};
using RCHook = std::function<void(Index, const std::vector<kv::NodeId>&)>;
using RCHook =
std::function<void(Index, const std::vector<ccf::kv::NodeId>&)>;
class LoggingStubStore
{
@ -348,32 +350,32 @@ namespace aft
virtual void compact(Index i) {}
virtual void rollback(const kv::TxID& tx_id, Term t) {}
virtual void rollback(const ccf::kv::TxID& tx_id, Term t) {}
virtual void initialise_term(Term t) {}
kv::Version current_version()
ccf::kv::Version current_version()
{
return kv::NoVersion;
return ccf::kv::NoVersion;
}
class ExecutionWrapper : public kv::AbstractExecutionWrapper
class ExecutionWrapper : public ccf::kv::AbstractExecutionWrapper
{
private:
kv::ConsensusHookPtrs hooks;
ccf::kv::ConsensusHookPtrs hooks;
aft::Term term;
kv::Version index;
ccf::kv::Version index;
std::vector<uint8_t> entry;
ccf::ClaimsDigest claims_digest;
std::optional<ccf::crypto::Sha256Hash> commit_evidence_digest =
std::nullopt;
kv::ApplyResult result;
ccf::kv::ApplyResult result;
public:
ExecutionWrapper(
const std::vector<uint8_t>& data_,
const std::optional<kv::TxID>& expected_txid,
kv::ConsensusHookPtrs&& hooks_) :
const std::optional<ccf::kv::TxID>& expected_txid,
ccf::kv::ConsensusHookPtrs&& hooks_) :
hooks(std::move(hooks_))
{
const uint8_t* data = data_.data();
@ -381,17 +383,17 @@ namespace aft
const auto committable = serialized::read<bool>(data, size);
term = serialized::read<aft::Term>(data, size);
index = serialized::read<kv::Version>(data, size);
index = serialized::read<ccf::kv::Version>(data, size);
entry = serialized::read(data, size, size);
result =
committable ? kv::ApplyResult::PASS_SIGNATURE : kv::ApplyResult::PASS;
result = committable ? ccf::kv::ApplyResult::PASS_SIGNATURE :
ccf::kv::ApplyResult::PASS;
if (expected_txid.has_value())
{
if (term != expected_txid->term || index != expected_txid->version)
{
result = kv::ApplyResult::FAIL;
result = ccf::kv::ApplyResult::FAIL;
}
}
}
@ -407,12 +409,12 @@ namespace aft
return std::move(commit_evidence_digest);
}
kv::ApplyResult apply(bool track_deletes_on_missing_keys) override
ccf::kv::ApplyResult apply(bool track_deletes_on_missing_keys) override
{
return result;
}
kv::ConsensusHookPtrs& get_hooks() override
ccf::kv::ConsensusHookPtrs& get_hooks() override
{
return hooks;
}
@ -427,7 +429,7 @@ namespace aft
return term;
}
kv::Version get_index() override
ccf::kv::Version get_index() override
{
return index;
}
@ -448,22 +450,22 @@ namespace aft
}
};
virtual std::unique_ptr<kv::AbstractExecutionWrapper> deserialize(
virtual std::unique_ptr<ccf::kv::AbstractExecutionWrapper> deserialize(
const std::vector<uint8_t>& data,
bool public_only = false,
const std::optional<kv::TxID>& expected_txid = std::nullopt)
const std::optional<ccf::kv::TxID>& expected_txid = std::nullopt)
{
kv::ConsensusHookPtrs hooks = {};
ccf::kv::ConsensusHookPtrs hooks = {};
return std::make_unique<ExecutionWrapper>(
data, expected_txid, std::move(hooks));
}
bool flag_enabled(kv::AbstractStore::Flag)
bool flag_enabled(ccf::kv::AbstractStore::Flag)
{
return false;
}
void unset_flag(kv::AbstractStore::Flag) {}
void unset_flag(ccf::kv::AbstractStore::Flag) {}
};
class LoggingStubStoreConfig : public LoggingStubStore
@ -483,7 +485,7 @@ namespace aft
{
if (version <= i)
{
std::vector<kv::NodeId> retired_committed_node_ids;
std::vector<ccf::kv::NodeId> retired_committed_node_ids;
for (auto& [node_id, _] : configuration.items())
{
retired_committed_node_ids.push_back(node_id);
@ -503,7 +505,7 @@ namespace aft
retired_committed_entries.end());
}
virtual void rollback(const kv::TxID& tx_id, Term t) override
virtual void rollback(const ccf::kv::TxID& tx_id, Term t) override
{
retired_committed_entries.erase(
std::remove_if(
@ -513,10 +515,10 @@ namespace aft
retired_committed_entries.end());
}
virtual std::unique_ptr<kv::AbstractExecutionWrapper> deserialize(
virtual std::unique_ptr<ccf::kv::AbstractExecutionWrapper> deserialize(
const std::vector<uint8_t>& data,
bool public_only = false,
const std::optional<kv::TxID>& expected_txid = std::nullopt) override
const std::optional<ccf::kv::TxID>& expected_txid = std::nullopt) override
{
// Set reconfiguration hook if there are any new nodes
// Read wrapping term and version
@ -524,19 +526,21 @@ namespace aft
auto size = data.size();
const auto committable = serialized::read<bool>(data_, size);
serialized::read<aft::Term>(data_, size);
auto version = serialized::read<kv::Version>(data_, size);
auto version = serialized::read<ccf::kv::Version>(data_, size);
ReplicatedData r = nlohmann::json::parse(std::span{data_, size});
kv::ConsensusHookPtrs hooks = {};
ccf::kv::ConsensusHookPtrs hooks = {};
if (r.type == ReplicatedDataType::reconfiguration)
{
kv::Configuration::Nodes configuration = nlohmann::json::parse(r.data);
ccf::kv::Configuration::Nodes configuration =
nlohmann::json::parse(r.data);
auto hook = std::make_unique<aft::ConfigurationChangeHook>(
configuration, version);
hooks.push_back(std::move(hook));
}
if (r.type == ReplicatedDataType::retired_committed)
{
kv::Configuration::Nodes configuration = nlohmann::json::parse(r.data);
ccf::kv::Configuration::Nodes configuration =
nlohmann::json::parse(r.data);
retired_committed_entries.emplace_back(version, configuration);
}

Просмотреть файл

@ -14,7 +14,7 @@ using ms = std::chrono::milliseconds;
DOCTEST_TEST_CASE("Single node startup" * doctest::test_suite("single"))
{
ccf::NodeId node_id = kv::test::PrimaryNodeId;
ccf::NodeId node_id = ccf::kv::test::PrimaryNodeId;
auto kv_store = std::make_shared<Store>(node_id);
TRaft r0(
@ -26,7 +26,7 @@ DOCTEST_TEST_CASE("Single node startup" * doctest::test_suite("single"))
nullptr);
r0.start_ticking();
kv::Configuration::Nodes config;
ccf::kv::Configuration::Nodes config;
config.try_emplace(node_id);
r0.add_configuration(0, config);
@ -50,7 +50,7 @@ DOCTEST_TEST_CASE("Single node startup" * doctest::test_suite("single"))
DOCTEST_TEST_CASE("Single node commit" * doctest::test_suite("single"))
{
ccf::NodeId node_id = kv::test::PrimaryNodeId;
ccf::NodeId node_id = ccf::kv::test::PrimaryNodeId;
auto kv_store = std::make_shared<Store>(node_id);
TRaft r0(
@ -80,9 +80,9 @@ DOCTEST_TEST_CASE("Single node commit" * doctest::test_suite("single"))
entry->push_back(2);
entry->push_back(3);
auto hooks = std::make_shared<kv::ConsensusHookPtrs>();
auto hooks = std::make_shared<ccf::kv::ConsensusHookPtrs>();
r0.replicate(kv::BatchVector{{i, entry, true, hooks}}, 1);
r0.replicate(ccf::kv::BatchVector{{i, entry, true, hooks}}, 1);
DOCTEST_REQUIRE(r0.get_last_idx() == i);
DOCTEST_REQUIRE(r0.get_committed_seqno() == i);
}
@ -91,10 +91,10 @@ DOCTEST_TEST_CASE("Single node commit" * doctest::test_suite("single"))
DOCTEST_TEST_CASE(
"Multiple nodes startup and election" * doctest::test_suite("multiple"))
{
ccf::NodeId node_id0 = kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = kv::test::FirstBackupNodeId;
ccf::NodeId node_id2 = kv::test::SecondBackupNodeId;
ccf::NodeId node_id3 = kv::test::ThirdBackupNodeId;
ccf::NodeId node_id0 = ccf::kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = ccf::kv::test::FirstBackupNodeId;
ccf::NodeId node_id2 = ccf::kv::test::SecondBackupNodeId;
ccf::NodeId node_id3 = ccf::kv::test::ThirdBackupNodeId;
auto kv_store0 = std::make_shared<Store>(node_id0);
auto kv_store1 = std::make_shared<Store>(node_id1);
@ -275,9 +275,9 @@ DOCTEST_TEST_CASE(
DOCTEST_TEST_CASE(
"Multiple nodes append entries" * doctest::test_suite("multiple"))
{
ccf::NodeId node_id0 = kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = kv::test::FirstBackupNodeId;
ccf::NodeId node_id2 = kv::test::SecondBackupNodeId;
ccf::NodeId node_id0 = ccf::kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = ccf::kv::test::FirstBackupNodeId;
ccf::NodeId node_id2 = ccf::kv::test::SecondBackupNodeId;
auto kv_store0 = std::make_shared<Store>(node_id0);
auto kv_store1 = std::make_shared<Store>(node_id1);
@ -359,12 +359,13 @@ DOCTEST_TEST_CASE(
DOCTEST_INFO("Try to replicate on a follower, and fail");
std::vector<uint8_t> entry = {1, 2, 3};
auto data = std::make_shared<std::vector<uint8_t>>(entry);
auto hooks = std::make_shared<kv::ConsensusHookPtrs>();
auto hooks = std::make_shared<ccf::kv::ConsensusHookPtrs>();
DOCTEST_REQUIRE_FALSE(
r1.replicate(kv::BatchVector{{1, data, true, hooks}}, 1));
r1.replicate(ccf::kv::BatchVector{{1, data, true, hooks}}, 1));
DOCTEST_INFO("Tell the leader to replicate a message");
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{1, data, true, hooks}}, 1));
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{1, data, true, hooks}}, 1));
DOCTEST_REQUIRE(r0.ledger->ledger.size() == 1);
// The test ledger adds its own header. Confirm that the expected data is
@ -411,9 +412,9 @@ DOCTEST_TEST_CASE(
DOCTEST_TEST_CASE("Multiple nodes late join" * doctest::test_suite("multiple"))
{
ccf::NodeId node_id0 = kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = kv::test::FirstBackupNodeId;
ccf::NodeId node_id2 = kv::test::SecondBackupNodeId;
ccf::NodeId node_id0 = ccf::kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = ccf::kv::test::FirstBackupNodeId;
ccf::NodeId node_id2 = ccf::kv::test::SecondBackupNodeId;
auto kv_store0 = std::make_shared<Store>(node_id0);
auto kv_store1 = std::make_shared<Store>(node_id1);
@ -475,8 +476,9 @@ DOCTEST_TEST_CASE("Multiple nodes late join" * doctest::test_suite("multiple"))
std::vector<uint8_t> first_entry = {1, 2, 3};
auto data = std::make_shared<std::vector<uint8_t>>(first_entry);
auto hooks = std::make_shared<kv::ConsensusHookPtrs>();
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{1, data, true, hooks}}, 1));
auto hooks = std::make_shared<ccf::kv::ConsensusHookPtrs>();
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{1, data, true, hooks}}, 1));
r0.periodic(request_timeout);
DOCTEST_REQUIRE(
@ -528,8 +530,8 @@ DOCTEST_TEST_CASE("Multiple nodes late join" * doctest::test_suite("multiple"))
DOCTEST_TEST_CASE("Recv append entries logic" * doctest::test_suite("multiple"))
{
ccf::NodeId node_id0 = kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = kv::test::FirstBackupNodeId;
ccf::NodeId node_id0 = ccf::kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = ccf::kv::test::FirstBackupNodeId;
auto kv_store0 = std::make_shared<Store>(node_id0);
auto kv_store1 = std::make_shared<Store>(node_id1);
@ -548,7 +550,7 @@ DOCTEST_TEST_CASE("Recv append entries logic" * doctest::test_suite("multiple"))
std::make_shared<aft::ChannelStubProxy>(),
std::make_shared<aft::State>(node_id1),
nullptr);
auto hooks = std::make_shared<kv::ConsensusHookPtrs>();
auto hooks = std::make_shared<ccf::kv::ConsensusHookPtrs>();
aft::Configuration::Nodes config0;
config0[node_id0] = {};
@ -586,8 +588,10 @@ DOCTEST_TEST_CASE("Recv append entries logic" * doctest::test_suite("multiple"))
std::vector<uint8_t> second_entry = {2, 2, 2};
auto data_2 = std::make_shared<std::vector<uint8_t>>(second_entry);
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{1, data_1, true, hooks}}, 1));
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{2, data_2, true, hooks}}, 1));
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{1, data_1, true, hooks}}, 1));
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{2, data_2, true, hooks}}, 1));
DOCTEST_REQUIRE(r0.ledger->ledger.size() == 2);
r0.periodic(request_timeout);
DOCTEST_REQUIRE(r0c->messages.size() == 1);
@ -608,7 +612,8 @@ DOCTEST_TEST_CASE("Recv append entries logic" * doctest::test_suite("multiple"))
{
std::vector<uint8_t> third_entry = {3, 3, 3};
auto data = std::make_shared<std::vector<uint8_t>>(third_entry);
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{3, data, true, hooks}}, 1));
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{3, data, true, hooks}}, 1));
DOCTEST_REQUIRE(r0.ledger->ledger.size() == 3);
// Simulate that the append entries was not deserialised successfully
@ -640,7 +645,8 @@ DOCTEST_TEST_CASE("Recv append entries logic" * doctest::test_suite("multiple"))
{
std::vector<uint8_t> fourth_entry = {4, 4, 4};
auto data = std::make_shared<std::vector<uint8_t>>(fourth_entry);
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{4, data, true, hooks}}, 1));
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{4, data, true, hooks}}, 1));
DOCTEST_REQUIRE(r0.ledger->ledger.size() == 4);
r0.periodic(request_timeout);
DOCTEST_REQUIRE(r0c->messages.size() == 1);
@ -653,7 +659,8 @@ DOCTEST_TEST_CASE("Recv append entries logic" * doctest::test_suite("multiple"))
{
std::vector<uint8_t> fifth_entry = {5, 5, 5};
auto data = std::make_shared<std::vector<uint8_t>>(fifth_entry);
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{5, data, true, hooks}}, 1));
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{5, data, true, hooks}}, 1));
DOCTEST_REQUIRE(r0.ledger->ledger.size() == 5);
r0.periodic(request_timeout);
DOCTEST_REQUIRE(r0c->messages.size() == 1);
@ -682,7 +689,8 @@ DOCTEST_TEST_CASE("Recv append entries logic" * doctest::test_suite("multiple"))
{
std::vector<uint8_t> entry_6 = {6, 6, 6};
auto data = std::make_shared<std::vector<uint8_t>>(entry_6);
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{6, data, true, hooks}}, 1));
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{6, data, true, hooks}}, 1));
DOCTEST_REQUIRE(r0.ledger->ledger.size() == 6);
}
const auto last_correct_version = r0.ledger->ledger.size();
@ -691,7 +699,8 @@ DOCTEST_TEST_CASE("Recv append entries logic" * doctest::test_suite("multiple"))
{
std::vector<uint8_t> entry_7 = {7, 7, 7};
auto data = std::make_shared<std::vector<uint8_t>>(entry_7);
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{7, data, true, hooks}}, 1));
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{7, data, true, hooks}}, 1));
DOCTEST_REQUIRE(r0.ledger->ledger.size() == 7);
dead_branch = r0.ledger->ledger.back();
}
@ -712,7 +721,8 @@ DOCTEST_TEST_CASE("Recv append entries logic" * doctest::test_suite("multiple"))
{
std::vector<uint8_t> entry_7b = {7, 7, 'b'};
auto data = std::make_shared<std::vector<uint8_t>>(entry_7b);
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{7, data, true, hooks}}, 4));
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{7, data, true, hooks}}, 4));
DOCTEST_REQUIRE(r0.ledger->ledger.size() == 7);
live_branch = r0.ledger->ledger.back();
}
@ -720,7 +730,8 @@ DOCTEST_TEST_CASE("Recv append entries logic" * doctest::test_suite("multiple"))
{
std::vector<uint8_t> entry_8 = {8, 8, 8};
auto data = std::make_shared<std::vector<uint8_t>>(entry_8);
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{8, data, true, hooks}}, 4));
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{8, data, true, hooks}}, 4));
DOCTEST_REQUIRE(r0.ledger->ledger.size() == 8);
DOCTEST_REQUIRE(r0.ledger->ledger.size() > last_correct_version);
}
@ -771,9 +782,9 @@ DOCTEST_TEST_CASE("Exceed append entries limit")
{
ccf::logger::config::level() = LoggerLevel::INFO;
ccf::NodeId node_id0 = kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = kv::test::FirstBackupNodeId;
ccf::NodeId node_id2 = kv::test::SecondBackupNodeId;
ccf::NodeId node_id0 = ccf::kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = ccf::kv::test::FirstBackupNodeId;
ccf::NodeId node_id2 = ccf::kv::test::SecondBackupNodeId;
auto kv_store0 = std::make_shared<Store>(node_id0);
auto kv_store1 = std::make_shared<Store>(node_id1);
@ -847,8 +858,9 @@ DOCTEST_TEST_CASE("Exceed append entries limit")
for (size_t i = 1; i <= num_big_entries; ++i)
{
auto hooks = std::make_shared<kv::ConsensusHookPtrs>();
DOCTEST_REQUIRE(r0.replicate(kv::BatchVector{{i, data, true, hooks}}, 1));
auto hooks = std::make_shared<ccf::kv::ConsensusHookPtrs>();
DOCTEST_REQUIRE(
r0.replicate(ccf::kv::BatchVector{{i, data, true, hooks}}, 1));
const auto received_ae =
dispatch_all_and_DOCTEST_CHECK<aft::AppendEntries>(
nodes, node_id0, r0c->messages, [&i](const auto& msg) {
@ -864,9 +876,9 @@ DOCTEST_TEST_CASE("Exceed append entries limit")
for (size_t i = num_big_entries + 1; i <= individual_entries; ++i)
{
auto hooks = std::make_shared<kv::ConsensusHookPtrs>();
auto hooks = std::make_shared<ccf::kv::ConsensusHookPtrs>();
DOCTEST_REQUIRE(
r0.replicate(kv::BatchVector{{i, smaller_data, true, hooks}}, 1));
r0.replicate(ccf::kv::BatchVector{{i, smaller_data, true, hooks}}, 1));
dispatch_all(nodes, node_id0, r0c->messages);
}
@ -925,8 +937,8 @@ DOCTEST_TEST_CASE(
"Nodes only run for election when they should" *
doctest::test_suite("multiple"))
{
ccf::NodeId node_id0 = kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = kv::test::FirstBackupNodeId;
ccf::NodeId node_id0 = ccf::kv::test::PrimaryNodeId;
ccf::NodeId node_id1 = ccf::kv::test::FirstBackupNodeId;
auto kv_store0 = std::make_shared<Store>(node_id0);
auto kv_store1 = std::make_shared<Store>(node_id1);

Просмотреть файл

@ -24,7 +24,7 @@ static const std::chrono::milliseconds election_timeout = election_timeout_;
static const ccf::consensus::Configuration raft_settings{
request_timeout_, election_timeout_, max_uncommitted_tx_count_};
static auto hooks = std::make_shared<kv::ConsensusHookPtrs>();
static auto hooks = std::make_shared<ccf::kv::ConsensusHookPtrs>();
static aft::ChannelStubProxy* channel_stub_proxy(const TRaft& r)
{

Просмотреть файл

@ -19,8 +19,8 @@ TEST_CASE("Advancing view history" * doctest::test_suite("viewhistory"))
CHECK(history.view_at(3) == ViewHistory::InvalidView);
CHECK(history.view_at(4) == ViewHistory::InvalidView);
CHECK(history.start_of_view(1) == kv::NoVersion);
CHECK(history.end_of_view(1) == kv::NoVersion);
CHECK(history.start_of_view(1) == ccf::kv::NoVersion);
CHECK(history.end_of_view(1) == ccf::kv::NoVersion);
}
{
@ -64,9 +64,9 @@ TEST_CASE("Advancing view history" * doctest::test_suite("viewhistory"))
CHECK(history.start_of_view(2) == 3);
CHECK(history.end_of_view(2) == 3);
CHECK(history.start_of_view(3) == 4);
CHECK(history.end_of_view(3) == kv::NoVersion);
CHECK(history.start_of_view(4) == kv::NoVersion);
CHECK(history.end_of_view(4) == kv::NoVersion);
CHECK(history.end_of_view(3) == ccf::kv::NoVersion);
CHECK(history.start_of_view(4) == ccf::kv::NoVersion);
CHECK(history.end_of_view(4) == ccf::kv::NoVersion);
}
}
@ -143,14 +143,14 @@ TEST_CASE("Edge case view histories" * doctest::test_suite("viewhistory"))
CHECK(history.view_at(4) == 4);
CHECK(history.start_of_view(4) == 2);
CHECK(history.end_of_view(4) == kv::NoVersion);
CHECK(history.end_of_view(4) == ccf::kv::NoVersion);
CHECK(history.start_of_view(1) == kv::NoVersion);
CHECK(history.end_of_view(1) == kv::NoVersion);
CHECK(history.start_of_view(2) == kv::NoVersion);
CHECK(history.end_of_view(2) == kv::NoVersion);
CHECK(history.start_of_view(3) == kv::NoVersion);
CHECK(history.end_of_view(3) == kv::NoVersion);
CHECK(history.start_of_view(1) == ccf::kv::NoVersion);
CHECK(history.end_of_view(1) == ccf::kv::NoVersion);
CHECK(history.start_of_view(2) == ccf::kv::NoVersion);
CHECK(history.end_of_view(2) == ccf::kv::NoVersion);
CHECK(history.start_of_view(3) == ccf::kv::NoVersion);
CHECK(history.end_of_view(3) == ccf::kv::NoVersion);
}
}
@ -168,12 +168,12 @@ TEST_CASE("Initialised view histories" * doctest::test_suite("viewhistory"))
CHECK(history.start_of_view(1) == 2);
CHECK(history.end_of_view(1) == 3);
CHECK(history.start_of_view(2) == kv::NoVersion);
CHECK(history.end_of_view(2) == kv::NoVersion);
CHECK(history.start_of_view(2) == ccf::kv::NoVersion);
CHECK(history.end_of_view(2) == ccf::kv::NoVersion);
CHECK(history.start_of_view(3) == 4);
CHECK(history.end_of_view(3) == 9);
CHECK(history.start_of_view(4) == 10);
CHECK(history.end_of_view(4) == kv::NoVersion);
CHECK(history.end_of_view(4) == ccf::kv::NoVersion);
CHECK_THROWS(history.initialise({2, 1}));
CHECK_THROWS(history.initialise({1, 2, 1}));
@ -203,8 +203,8 @@ TEST_CASE("Initialised view histories" * doctest::test_suite("viewhistory"))
CHECK(history.view_at(19) == 6);
CHECK(history.view_at(20) == 6);
CHECK(history.start_of_view(1) == kv::NoVersion);
CHECK(history.end_of_view(1) == kv::NoVersion);
CHECK(history.start_of_view(1) == ccf::kv::NoVersion);
CHECK(history.end_of_view(1) == ccf::kv::NoVersion);
CHECK(history.start_of_view(3) == 3);
CHECK(history.end_of_view(3) == 4);
CHECK(history.start_of_view(4) == 5);
@ -212,7 +212,7 @@ TEST_CASE("Initialised view histories" * doctest::test_suite("viewhistory"))
CHECK(history.start_of_view(5) == 6);
CHECK(history.end_of_view(5) == 11);
CHECK(history.start_of_view(6) == 12);
CHECK(history.end_of_view(6) == kv::NoVersion);
CHECK(history.end_of_view(6) == ccf::kv::NoVersion);
}
}
@ -234,23 +234,28 @@ TEST_CASE(
{
INFO("Test that view history is correct");
REQUIRE(history.get_history_until(kv::NoVersion).size() == 0);
REQUIRE(history.get_history_until(1) == std::vector<kv::Version>({1}));
REQUIRE(history.get_history_until(2) == std::vector<kv::Version>({1, 2}));
REQUIRE(history.get_history_until(3) == std::vector<kv::Version>({1, 2}));
REQUIRE(history.get_history_until(4) == std::vector<kv::Version>({1, 2}));
REQUIRE(history.get_history_until(ccf::kv::NoVersion).size() == 0);
REQUIRE(history.get_history_until(1) == std::vector<ccf::kv::Version>({1}));
REQUIRE(
history.get_history_until(5) == std::vector<kv::Version>({1, 2, 5, 5}));
history.get_history_until(2) == std::vector<ccf::kv::Version>({1, 2}));
REQUIRE(
history.get_history_until(9) == std::vector<kv::Version>({1, 2, 5, 5}));
history.get_history_until(3) == std::vector<ccf::kv::Version>({1, 2}));
REQUIRE(
history.get_history_until(4) == std::vector<ccf::kv::Version>({1, 2}));
REQUIRE(
history.get_history_until(5) ==
std::vector<ccf::kv::Version>({1, 2, 5, 5}));
REQUIRE(
history.get_history_until(9) ==
std::vector<ccf::kv::Version>({1, 2, 5, 5}));
REQUIRE(
history.get_history_until(10) ==
std::vector<kv::Version>({1, 2, 5, 5, 10}));
std::vector<ccf::kv::Version>({1, 2, 5, 5, 10}));
REQUIRE(
history.get_history_until(11) ==
std::vector<kv::Version>({1, 2, 5, 5, 10}));
std::vector<ccf::kv::Version>({1, 2, 5, 5, 10}));
REQUIRE(
history.get_history_until() ==
std::vector<kv::Version>({1, 2, 5, 5, 10}));
std::vector<ccf::kv::Version>({1, 2, 5, 5, 10}));
}
}

Просмотреть файл

@ -25,8 +25,9 @@ namespace consensus
*/
static std::vector<uint8_t> get_entry(const uint8_t*& data, size_t& size)
{
auto header = serialized::peek<kv::SerialisedEntryHeader>(data, size);
size_t entry_size = kv::serialised_entry_header_size + header.size;
auto header =
serialized::peek<ccf::kv::SerialisedEntryHeader>(data, size);
size_t entry_size = ccf::kv::serialised_entry_header_size + header.size;
std::vector<uint8_t> entry(data, data + entry_size);
serialized::skip(data, size, entry_size);
return entry;
@ -51,8 +52,8 @@ namespace consensus
void put_entry(
const std::vector<uint8_t>& entry,
bool globally_committable,
kv::Term term,
kv::Version index)
ccf::kv::Term term,
ccf::kv::Version index)
{
put_entry(entry.data(), entry.size(), globally_committable, term, index);
}
@ -72,8 +73,8 @@ namespace consensus
const uint8_t* data,
size_t size,
bool globally_committable,
kv::Term term,
kv::Version index)
ccf::kv::Term term,
ccf::kv::Version index)
{
serializer::ByteRange byte_range = {data, size};
RINGBUFFER_WRITE_MESSAGE(
@ -90,7 +91,8 @@ namespace consensus
*/
static void skip_entry(const uint8_t*& data, size_t& size)
{
auto header = serialized::read<kv::SerialisedEntryHeader>(data, size);
auto header =
serialized::read<ccf::kv::SerialisedEntryHeader>(data, size);
serialized::skip(data, size, header.size);
}

Просмотреть файл

@ -22,8 +22,8 @@ struct CollisionHash
}
};
using K = kv::serialisers::SerialisedEntry;
using V = kv::serialisers::SerialisedEntry;
using K = ccf::kv::serialisers::SerialisedEntry;
using V = ccf::kv::serialisers::SerialisedEntry;
constexpr static size_t max_key_value_size = 128;
namespace map

Просмотреть файл

@ -11,7 +11,7 @@
#include <stdint.h>
#include <vector>
namespace kv
namespace ccf::kv
{
class CommittableTx;
}

Просмотреть файл

@ -66,7 +66,7 @@ namespace ccf
}
std::unique_ptr<AuthnIdentity> AllOfAuthnPolicy::authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason)
{

Просмотреть файл

@ -104,7 +104,7 @@ namespace ccf
UserCertAuthnPolicy::~UserCertAuthnPolicy() = default;
std::unique_ptr<AuthnIdentity> UserCertAuthnPolicy::authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason)
{
@ -141,7 +141,7 @@ namespace ccf
MemberCertAuthnPolicy::~MemberCertAuthnPolicy() = default;
std::unique_ptr<AuthnIdentity> MemberCertAuthnPolicy::authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason)
{
@ -167,7 +167,7 @@ namespace ccf
}
std::unique_ptr<AuthnIdentity> NodeCertAuthnPolicy::authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason)
{

Просмотреть файл

@ -300,7 +300,7 @@ namespace ccf
MemberCOSESign1AuthnPolicy::~MemberCOSESign1AuthnPolicy() = default;
std::unique_ptr<AuthnIdentity> MemberCOSESign1AuthnPolicy::authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason)
{
@ -406,7 +406,7 @@ namespace ccf
"Signer must be a member identity registered with this service."}});
std::unique_ptr<AuthnIdentity> ActiveMemberCOSESign1AuthnPolicy::authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason)
{
@ -441,7 +441,7 @@ namespace ccf
std::unique_ptr<UserCOSESign1AuthnIdentity> UserCOSESign1AuthnPolicy::
_authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason)
{
@ -502,7 +502,7 @@ namespace ccf
}
std::unique_ptr<AuthnIdentity> UserCOSESign1AuthnPolicy::authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason)
{
@ -533,7 +533,7 @@ namespace ccf
"Signer must be a user identity registered with this service."}});
std::unique_ptr<AuthnIdentity> TypedUserCOSESign1AuthnPolicy::authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason)
{

Просмотреть файл

@ -6,7 +6,7 @@
namespace ccf
{
std::unique_ptr<AuthnIdentity> EmptyAuthnPolicy::authenticate(
kv::ReadOnlyTx&, const std::shared_ptr<ccf::RpcContext>&, std::string&)
ccf::kv::ReadOnlyTx&, const std::shared_ptr<ccf::RpcContext>&, std::string&)
{
return std::make_unique<EmptyAuthnIdentity>();
}

Просмотреть файл

@ -115,7 +115,7 @@ namespace ccf
JwtAuthnPolicy::~JwtAuthnPolicy() = default;
std::unique_ptr<AuthnIdentity> JwtAuthnPolicy::authenticate(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::shared_ptr<ccf::RpcContext>& ctx,
std::string& error_reason)
{

Просмотреть файл

@ -115,7 +115,7 @@ namespace ccf
}
ApiResult BaseEndpointRegistry::generate_openapi_document_v1(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const std::string& title,
const std::string& description,
const std::string& document_version,
@ -136,7 +136,7 @@ namespace ccf
}
ApiResult BaseEndpointRegistry::get_quote_for_this_node_v1(
kv::ReadOnlyTx& tx, QuoteInfo& quote_info)
ccf::kv::ReadOnlyTx& tx, QuoteInfo& quote_info)
{
try
{
@ -175,7 +175,7 @@ namespace ccf
}
ApiResult BaseEndpointRegistry::get_quotes_for_all_trusted_nodes_v1(
kv::ReadOnlyTx& tx, std::map<NodeId, QuoteInfo>& quotes)
ccf::kv::ReadOnlyTx& tx, std::map<NodeId, QuoteInfo>& quotes)
{
try
{
@ -230,7 +230,7 @@ namespace ccf
}
ApiResult BaseEndpointRegistry::get_user_data_v1(
kv::ReadOnlyTx& tx, const UserId& user_id, nlohmann::json& user_data)
ccf::kv::ReadOnlyTx& tx, const UserId& user_id, nlohmann::json& user_data)
{
try
{
@ -252,7 +252,9 @@ namespace ccf
}
ApiResult BaseEndpointRegistry::get_member_data_v1(
kv::ReadOnlyTx& tx, const MemberId& member_id, nlohmann::json& member_data)
ccf::kv::ReadOnlyTx& tx,
const MemberId& member_id,
nlohmann::json& member_data)
{
try
{
@ -274,7 +276,9 @@ namespace ccf
}
ApiResult BaseEndpointRegistry::get_user_cert_v1(
kv::ReadOnlyTx& tx, const UserId& user_id, ccf::crypto::Pem& user_cert_pem)
ccf::kv::ReadOnlyTx& tx,
const UserId& user_id,
ccf::crypto::Pem& user_cert_pem)
{
try
{
@ -296,7 +300,7 @@ namespace ccf
}
ApiResult BaseEndpointRegistry::get_member_cert_v1(
kv::ReadOnlyTx& tx,
ccf::kv::ReadOnlyTx& tx,
const MemberId& member_id,
ccf::crypto::Pem& member_cert_pem)
{

Просмотреть файл

@ -304,7 +304,8 @@ namespace ccf::endpoints
default_endpoint = std::move(tmp);
}
void EndpointRegistry::build_api(nlohmann::json& document, kv::ReadOnlyTx&)
void EndpointRegistry::build_api(
nlohmann::json& document, ccf::kv::ReadOnlyTx&)
{
// Add common components:
// - Descriptions of each kind of forwarding
@ -389,7 +390,7 @@ namespace ccf::endpoints
void EndpointRegistry::init_handlers() {}
EndpointDefinitionPtr EndpointRegistry::find_endpoint(
kv::Tx&, ccf::RpcContext& rpc_ctx)
ccf::kv::Tx&, ccf::RpcContext& rpc_ctx)
{
auto method = rpc_ctx.get_method();
auto endpoints_for_exact_method = fully_qualified_endpoints.find(method);
@ -497,7 +498,7 @@ namespace ccf::endpoints
}
std::set<RESTVerb> EndpointRegistry::get_allowed_verbs(
kv::Tx& tx, const ccf::RpcContext& rpc_ctx)
ccf::kv::Tx& tx, const ccf::RpcContext& rpc_ctx)
{
auto method = rpc_ctx.get_method();
@ -555,12 +556,12 @@ namespace ccf::endpoints
// Default implementation does nothing
void EndpointRegistry::tick(std::chrono::milliseconds) {}
void EndpointRegistry::set_consensus(kv::Consensus* c)
void EndpointRegistry::set_consensus(ccf::kv::Consensus* c)
{
consensus = c;
}
void EndpointRegistry::set_history(kv::TxHistory* h)
void EndpointRegistry::set_history(ccf::kv::TxHistory* h)
{
history = h;
}

Просмотреть файл

@ -187,8 +187,8 @@ namespace ccf
};
}
// Note: For now, only command endpoints (i.e. with no kv::Tx) support gRPC
// server streaming.
// Note: For now, only command endpoints (i.e. with no ccf::kv::Tx) support
// gRPC server streaming.
template <typename In, typename Out>
endpoints::CommandEndpointFunction grpc_command_unary_stream_adapter(
const GrpcCommandUnaryStreamEndpoint<In, Out>& f)

Просмотреть файл

@ -288,12 +288,13 @@ namespace asynchost
total_len = sizeof(positions_offset_header_t);
auto len = total_file_size - total_len;
kv::SerialisedEntryHeader entry_header = {};
ccf::kv::SerialisedEntryHeader entry_header = {};
size_t current_idx = start_idx;
while (len >= kv::serialised_entry_header_size)
while (len >= ccf::kv::serialised_entry_header_size)
{
if (
fread(&entry_header, kv::serialised_entry_header_size, 1, file) !=
fread(
&entry_header, ccf::kv::serialised_entry_header_size, 1, file) !=
1)
{
LOG_FAIL_FMT(
@ -303,7 +304,7 @@ namespace asynchost
return;
}
len -= kv::serialised_entry_header_size;
len -= ccf::kv::serialised_entry_header_size;
const auto& entry_size = entry_header.size;
if (len < entry_size)
@ -330,7 +331,7 @@ namespace asynchost
current_idx++;
positions.push_back(total_len);
total_len += (kv::serialised_entry_header_size + entry_size);
total_len += (ccf::kv::serialised_entry_header_size + entry_size);
}
completed = false;
}
@ -1297,9 +1298,10 @@ namespace asynchost
TimeBoundLogger log_if_slow(fmt::format(
"Writing ledger entry - {} bytes, committable={}", size, committable));
auto header = serialized::peek<kv::SerialisedEntryHeader>(data, size);
auto header =
serialized::peek<ccf::kv::SerialisedEntryHeader>(data, size);
if (header.flags & kv::EntryFlags::FORCE_LEDGER_CHUNK_BEFORE)
if (header.flags & ccf::kv::EntryFlags::FORCE_LEDGER_CHUNK_BEFORE)
{
LOG_TRACE_FMT(
"Forcing ledger chunk before entry as required by the entry header "
@ -1314,7 +1316,7 @@ namespace asynchost
}
bool force_chunk_after =
header.flags & kv::EntryFlags::FORCE_LEDGER_CHUNK_AFTER;
header.flags & ccf::kv::EntryFlags::FORCE_LEDGER_CHUNK_AFTER;
if (force_chunk_after)
{
if (!committable)

Просмотреть файл

@ -149,12 +149,12 @@ void verify_framed_entries_range(
const uint8_t* data = &framed_entries[pos];
size_t size = framed_entries.size() - pos;
auto header = serialized::read<kv::SerialisedEntryHeader>(data, size);
auto header = serialized::read<ccf::kv::SerialisedEntryHeader>(data, size);
auto header_size = header.size;
REQUIRE(header_size == sizeof(TestLedgerEntry));
REQUIRE(TestLedgerEntry(data, size).value() == idx);
pos += kv::serialised_entry_header_size + sizeof(TestLedgerEntry);
pos += ccf::kv::serialised_entry_header_size + sizeof(TestLedgerEntry);
idx++;
}
@ -169,7 +169,7 @@ void read_entry_from_ledger(Ledger& ledger, size_t idx)
auto& entry = framed_entry->data;
const uint8_t* data = entry.data();
auto size = entry.size();
auto header = serialized::read<kv::SerialisedEntryHeader>(data, size);
auto header = serialized::read<ccf::kv::SerialisedEntryHeader>(data, size);
auto header_size = header.size;
REQUIRE(header_size == sizeof(TestLedgerEntry));
@ -212,11 +212,11 @@ std::vector<uint8_t> make_ledger_entry(size_t idx, uint8_t header_flags = 0)
{
auto e = TestLedgerEntry(idx);
std::vector<uint8_t> framed_entry(
kv::serialised_entry_header_size + sizeof(TestLedgerEntry));
ccf::kv::serialised_entry_header_size + sizeof(TestLedgerEntry));
auto data = framed_entry.data();
auto size = framed_entry.size();
kv::SerialisedEntryHeader header;
ccf::kv::SerialisedEntryHeader header;
header.set_size(sizeof(TestLedgerEntry));
header.flags = header_flags;
@ -283,7 +283,7 @@ size_t get_entries_per_chunk(size_t chunk_threshold)
// size of each entry
return ceil(
(static_cast<float>(chunk_threshold - sizeof(size_t))) /
(kv::serialised_entry_header_size + sizeof(TestLedgerEntry)));
(ccf::kv::serialised_entry_header_size + sizeof(TestLedgerEntry)));
}
// Assumes that no entries have been written yet
@ -385,7 +385,7 @@ TEST_CASE("Regular chunking")
// Write a new committable entry that forces a new ledger chunk
is_committable = true;
entry_submitter.write(is_committable, kv::FORCE_LEDGER_CHUNK_AFTER);
entry_submitter.write(is_committable, ccf::kv::FORCE_LEDGER_CHUNK_AFTER);
REQUIRE(number_of_files_in_ledger_dir() == number_of_files_after);
// Because of forcing a new chunk, the next entry will create a new chunk
@ -396,7 +396,7 @@ TEST_CASE("Regular chunking")
REQUIRE(number_of_files_in_ledger_dir() == number_of_files_after + 1);
is_committable = true;
entry_submitter.write(is_committable, kv::FORCE_LEDGER_CHUNK_BEFORE);
entry_submitter.write(is_committable, ccf::kv::FORCE_LEDGER_CHUNK_BEFORE);
// A new chunk is created before, as the entry is committable and forced
REQUIRE(number_of_files_in_ledger_dir() == number_of_files_after + 2);
}
@ -1078,7 +1078,7 @@ void corrupt_ledger_file(
else if (corrupt_first_hdr)
{
REQUIRE(fread(&table_offset, sizeof(table_offset), 1, file) == 1);
kv::SerialisedEntryHeader entry_header = {.size = 0xffffffff};
ccf::kv::SerialisedEntryHeader entry_header = {.size = 0xffffffff};
fwrite(&entry_header, sizeof(entry_header), 1, file);
}
else if (corrupt_last_entry)
@ -1087,7 +1087,7 @@ void corrupt_ledger_file(
std::vector<uint8_t> last_entry = {};
while (true)
{
kv::SerialisedEntryHeader entry_header = {};
ccf::kv::SerialisedEntryHeader entry_header = {};
if (fread(&entry_header, sizeof(entry_header), 1, file) != 1)
{
break;
@ -1396,7 +1396,7 @@ TEST_CASE("Chunking according to entry header flag")
INFO("Write an entry with the ledger chunking after header flag enabled");
{
entry_submitter.write(
is_committable, kv::EntryFlags::FORCE_LEDGER_CHUNK_AFTER);
is_committable, ccf::kv::EntryFlags::FORCE_LEDGER_CHUNK_AFTER);
REQUIRE(number_of_files_in_ledger_dir() == 1);
@ -1419,7 +1419,7 @@ TEST_CASE("Chunking according to entry header flag")
{
auto ledger_files_count = number_of_files_in_ledger_dir();
entry_submitter.write(
is_committable, kv::EntryFlags::FORCE_LEDGER_CHUNK_BEFORE);
is_committable, ccf::kv::EntryFlags::FORCE_LEDGER_CHUNK_BEFORE);
// Forcing a new chunk before creating a new chunk to store this entry
REQUIRE(number_of_files_in_ledger_dir() == ledger_files_count + 1);

Просмотреть файл

@ -19,15 +19,15 @@ namespace ccf::indexing
historical_cache(sc)
{}
kv::ReadOnlyStorePtr deserialise_transaction(
ccf::kv::ReadOnlyStorePtr deserialise_transaction(
ccf::SeqNo seqno, const uint8_t* data, size_t size) override
{
kv::ApplyResult result;
ccf::kv::ApplyResult result;
ccf::ClaimsDigest claims_digest;
bool has_commit_evidence;
auto store = historical_cache->deserialise_ledger_entry(
seqno, data, size, result, claims_digest, has_commit_evidence);
if (store != nullptr && result != kv::ApplyResult::FAIL)
if (store != nullptr && result != ccf::kv::ApplyResult::FAIL)
{
return store;
}
@ -39,7 +39,7 @@ namespace ccf::indexing
return nullptr;
}
std::vector<kv::ReadOnlyStorePtr> fetch_transactions(
std::vector<ccf::kv::ReadOnlyStorePtr> fetch_transactions(
const SeqNoCollection& seqnos) override
{
const ccf::historical::CompoundHandle handle{

Просмотреть файл

@ -436,7 +436,9 @@ namespace ccf::indexing::strategies
size_t max_buckets_) :
VisitEachEntryInMap(map_name_, "SeqnosByKey")
{
if (kv::get_security_domain(map_name_) != kv::SecurityDomain::PUBLIC)
if (
ccf::kv::get_security_domain(map_name_) !=
ccf::kv::SecurityDomain::PUBLIC)
{
throw std::logic_error(fmt::format(
"This Strategy ({}) is currently only implemented for public tables, "

Просмотреть файл

@ -14,12 +14,12 @@ namespace ccf::indexing::strategies
{}
void VisitEachEntryInMap::handle_committed_transaction(
const ccf::TxID& tx_id, const kv::ReadOnlyStorePtr& store)
const ccf::TxID& tx_id, const ccf::kv::ReadOnlyStorePtr& store)
{
// NB: Get an untyped view over the map with the same name. This saves
// deserialisation here, where we hand on the raw key and value.
auto tx = store->create_read_only_tx();
auto handle = tx.ro<kv::untyped::Map>(map_name);
auto handle = tx.ro<ccf::kv::untyped::Map>(map_name);
handle->foreach([this, &tx_id](const auto& k, const auto& v) {
visit_entry(tx_id, k, v);

Просмотреть файл

@ -8,16 +8,16 @@
// Needed by TestTransactionFetcher
#include "kv/test/null_encryptor.h"
using MapA = kv::Map<std::string, std::string>;
using MapA = ccf::kv::Map<std::string, std::string>;
static MapA map_a("public:map_a");
using MapB = kv::Map<size_t, size_t>;
using MapB = ccf::kv::Map<size_t, size_t>;
static MapB map_b("public:map_b");
using ValueA = kv::Value<std::string>;
using ValueA = ccf::kv::Value<std::string>;
static ValueA value_a("public:value_a");
using SetA = kv::Set<std::string>;
using SetA = ccf::kv::Set<std::string>;
static SetA set_a("public:set_a");
static const std::chrono::milliseconds step_time(10);
@ -25,16 +25,16 @@ static const std::chrono::milliseconds step_time(10);
class TestTransactionFetcher : public ccf::indexing::TransactionFetcher
{
public:
std::shared_ptr<kv::NullTxEncryptor> encryptor =
std::make_shared<kv::NullTxEncryptor>();
std::shared_ptr<ccf::kv::NullTxEncryptor> encryptor =
std::make_shared<ccf::kv::NullTxEncryptor>();
ccf::SeqNoCollection requested;
std::unordered_map<ccf::SeqNo, kv::ReadOnlyStorePtr> fetched_stores;
std::unordered_map<ccf::SeqNo, ccf::kv::ReadOnlyStorePtr> fetched_stores;
kv::ReadOnlyStorePtr deserialise_transaction(
ccf::kv::ReadOnlyStorePtr deserialise_transaction(
ccf::SeqNo seqno, const uint8_t* data, size_t size)
{
auto store = std::make_shared<kv::Store>(
auto store = std::make_shared<ccf::kv::Store>(
false /* Do not start from very first seqno */,
true /* Make use of historical secrets */);
@ -48,7 +48,7 @@ public:
}
auto result = exec->apply();
if (result == kv::ApplyResult::FAIL)
if (result == ccf::kv::ApplyResult::FAIL)
{
return nullptr;
}
@ -56,10 +56,10 @@ public:
return store;
}
std::vector<kv::ReadOnlyStorePtr> fetch_transactions(
std::vector<ccf::kv::ReadOnlyStorePtr> fetch_transactions(
const ccf::SeqNoCollection& seqnos)
{
std::vector<kv::ReadOnlyStorePtr> stores;
std::vector<ccf::kv::ReadOnlyStorePtr> stores;
for (auto seqno : seqnos)
{
@ -87,11 +87,11 @@ class AllCommittableWrapper : public TConsensus
public:
using TConsensus::TConsensus;
bool replicate(const kv::BatchVector& entries_, ccf::View view) override
bool replicate(const ccf::kv::BatchVector& entries_, ccf::View view) override
{
// Rather than building a history that produces real signatures, we just
// overwrite the entries here to say that everything is committable
kv::BatchVector entries(entries_);
ccf::kv::BatchVector entries(entries_);
for (auto& [seqno, data, committable, hooks] : entries)
{
committable = true;
@ -101,7 +101,8 @@ public:
}
};
using AllCommittableConsensus = AllCommittableWrapper<kv::test::StubConsensus>;
using AllCommittableConsensus =
AllCommittableWrapper<ccf::kv::test::StubConsensus>;
using ExpectedSeqNos = std::set<ccf::SeqNo>;
@ -161,7 +162,7 @@ static inline bool check_seqnos(
return true;
}
using Action = std::function<bool(size_t, kv::Tx&)>;
using Action = std::function<bool(size_t, ccf::kv::Tx&)>;
struct ActionDesc
{
ExpectedSeqNos& expected;
@ -169,7 +170,7 @@ struct ActionDesc
};
static inline bool create_transactions(
kv::Store& kv_store,
ccf::kv::Store& kv_store,
const std::vector<ActionDesc>& actions,
size_t count = ccf::indexing::Indexer::MAX_REQUESTABLE * 3)
{
@ -185,7 +186,7 @@ static inline bool create_transactions(
}
}
if (tx.commit() != kv::CommitResult::SUCCESS)
if (tx.commit() != ccf::kv::CommitResult::SUCCESS)
{
return false;
}

Просмотреть файл

@ -41,11 +41,11 @@ static std::vector<ActionDesc> create_actions(
ExpectedSeqNos& seqnos_2)
{
std::vector<ActionDesc> actions;
actions.push_back({seqnos_hello, [](size_t i, kv::Tx& tx) {
actions.push_back({seqnos_hello, [](size_t i, ccf::kv::Tx& tx) {
tx.wo(map_a)->put("hello", "value doesn't matter");
return true;
}});
actions.push_back({seqnos_saluton, [](size_t i, kv::Tx& tx) {
actions.push_back({seqnos_saluton, [](size_t i, ccf::kv::Tx& tx) {
if (i % 2 == 0)
{
tx.wo(map_a)->put("saluton", "value doesn't matter");
@ -53,7 +53,7 @@ static std::vector<ActionDesc> create_actions(
}
return false;
}});
actions.push_back({seqnos_1, [](size_t i, kv::Tx& tx) {
actions.push_back({seqnos_1, [](size_t i, ccf::kv::Tx& tx) {
if (i % 3 == 0)
{
tx.wo(map_b)->put(1, 42);
@ -61,7 +61,7 @@ static std::vector<ActionDesc> create_actions(
}
return false;
}});
actions.push_back({seqnos_2, [](size_t i, kv::Tx& tx) {
actions.push_back({seqnos_2, [](size_t i, ccf::kv::Tx& tx) {
if (i % 4 == 0)
{
tx.wo(map_b)->put(2, 42);
@ -75,7 +75,7 @@ static std::vector<ActionDesc> create_actions(
template <typename AA>
void run_tests(
const std::function<void()>& tick_until_caught_up,
kv::Store& kv_store,
ccf::kv::Store& kv_store,
ccf::indexing::Indexer& indexer,
ExpectedSeqNos& seqnos_hello,
ExpectedSeqNos& seqnos_saluton,
@ -172,7 +172,7 @@ void run_tests(
// Uses stub classes to test just indexing logic in isolation
TEST_CASE("basic indexing" * doctest::test_suite("indexing"))
{
kv::Store kv_store;
ccf::kv::Store kv_store;
auto consensus = std::make_shared<AllCommittableConsensus>();
kv_store.set_consensus(consensus);
@ -180,7 +180,7 @@ TEST_CASE("basic indexing" * doctest::test_suite("indexing"))
auto fetcher = std::make_shared<TestTransactionFetcher>();
ccf::indexing::Indexer indexer(fetcher);
auto encryptor = std::make_shared<kv::NullTxEncryptor>();
auto encryptor = std::make_shared<ccf::kv::NullTxEncryptor>();
kv_store.set_encryptor(encryptor);
REQUIRE_THROWS(indexer.install_strategy(nullptr));
@ -253,8 +253,8 @@ TEST_CASE("basic indexing" * doctest::test_suite("indexing"))
index_b);
}
kv::Version rekey(
kv::Store& kv_store,
ccf::kv::Version rekey(
ccf::kv::Store& kv_store,
const std::shared_ptr<ccf::LedgerSecrets>& ledger_secrets)
{
ccf::ShareManager share_manager(ledger_secrets);
@ -262,7 +262,7 @@ kv::Version rekey(
auto tx = kv_store.create_tx();
auto new_ledger_secret = ccf::make_ledger_secret();
share_manager.issue_recovery_shares(tx, new_ledger_secret);
REQUIRE(tx.commit() == kv::CommitResult::SUCCESS);
REQUIRE(tx.commit() == ccf::kv::CommitResult::SUCCESS);
auto tx_version = tx.commit_version();
@ -275,7 +275,7 @@ kv::Version rekey(
}
aft::LedgerStubProxy* add_raft_consensus(
std::shared_ptr<kv::Store> kv_store,
std::shared_ptr<ccf::kv::Store> kv_store,
std::shared_ptr<ccf::indexing::Indexer> indexer)
{
using TRaft = aft::Aft<aft::LedgerStubProxy>;
@ -285,7 +285,7 @@ aft::LedgerStubProxy* add_raft_consensus(
const ccf::consensus::Configuration settings{{"20ms"}, {"100ms"}};
auto consensus = std::make_shared<AllCommittableRaftConsensus>(
settings,
std::make_unique<aft::Adaptor<kv::Store>>(kv_store),
std::make_unique<aft::Adaptor<ccf::kv::Store>>(kv_store),
std::make_unique<aft::LedgerStubProxy>(node_id),
std::make_shared<aft::ChannelStubProxy>(),
std::make_shared<aft::State>(node_id),
@ -309,7 +309,7 @@ TEST_CASE_TEMPLATE(
IndexA,
LazyIndexA)
{
auto kv_store_p = std::make_shared<kv::Store>();
auto kv_store_p = std::make_shared<ccf::kv::Store>();
auto& kv_store = *kv_store_p;
auto ledger_secrets = std::make_shared<ccf::LedgerSecrets>();
@ -350,7 +350,7 @@ TEST_CASE_TEMPLATE(
member_info->put(member_id, {ccf::MemberStatus::ACTIVE});
member_public_encryption_keys->put(
member_id, ccf::crypto::make_rsa_key_pair()->public_key_pem());
REQUIRE(tx.commit() == kv::CommitResult::SUCCESS);
REQUIRE(tx.commit() == ccf::kv::CommitResult::SUCCESS);
}
ExpectedSeqNos seqnos_hello, seqnos_saluton, seqnos_1, seqnos_2;
@ -457,7 +457,7 @@ const auto max_multithread_run_time = 100s;
TEST_CASE(
"multi-threaded indexing - in memory" * doctest::test_suite("indexing"))
{
auto kv_store_p = std::make_shared<kv::Store>();
auto kv_store_p = std::make_shared<ccf::kv::Store>();
auto& kv_store = *kv_store_p;
auto ledger_secrets = std::make_shared<ccf::LedgerSecrets>();
@ -501,7 +501,7 @@ TEST_CASE(
member_info->put(member_id, {ccf::MemberStatus::ACTIVE});
member_public_encryption_keys->put(
member_id, ccf::crypto::make_rsa_key_pair()->public_key_pem());
REQUIRE(tx.commit() == kv::CommitResult::SUCCESS);
REQUIRE(tx.commit() == ccf::kv::CommitResult::SUCCESS);
}
std::atomic<bool> finished = false;
@ -528,7 +528,7 @@ TEST_CASE(
tx.wo(map_b)->put(42, i);
}
REQUIRE(tx.commit() == kv::CommitResult::SUCCESS);
REQUIRE(tx.commit() == ccf::kv::CommitResult::SUCCESS);
++i;
std::this_thread::yield();
}
@ -661,19 +661,20 @@ TEST_CASE(
class MockTransactionFetcher : public ccf::indexing::TransactionFetcher
{
std::shared_ptr<kv::AbstractTxEncryptor> encryptor;
std::shared_ptr<ccf::kv::AbstractTxEncryptor> encryptor;
public:
aft::LedgerStubProxy* ledger;
MockTransactionFetcher(const std::shared_ptr<kv::AbstractTxEncryptor>& e) :
MockTransactionFetcher(
const std::shared_ptr<ccf::kv::AbstractTxEncryptor>& e) :
encryptor(e)
{}
kv::ReadOnlyStorePtr deserialise_transaction(
ccf::kv::ReadOnlyStorePtr deserialise_transaction(
ccf::SeqNo seqno, const uint8_t* data, size_t size) override
{
auto store = std::make_shared<kv::Store>(
auto store = std::make_shared<ccf::kv::Store>(
false /* Do not start from very first seqno */,
true /* Make use of historical secrets */);
@ -687,7 +688,7 @@ public:
}
auto result = exec->apply();
if (result == kv::ApplyResult::FAIL)
if (result == ccf::kv::ApplyResult::FAIL)
{
return nullptr;
}
@ -695,10 +696,10 @@ public:
return store;
}
std::vector<kv::ReadOnlyStorePtr> fetch_transactions(
std::vector<ccf::kv::ReadOnlyStorePtr> fetch_transactions(
const ccf::SeqNoCollection& seqnos) override
{
std::vector<kv::ReadOnlyStorePtr> ret;
std::vector<ccf::kv::ReadOnlyStorePtr> ret;
for (const auto& seqno : seqnos)
{
@ -723,7 +724,7 @@ TEST_CASE(
INFO("Using seed: ", seed);
srand(seed);
auto kv_store_p = std::make_shared<kv::Store>();
auto kv_store_p = std::make_shared<ccf::kv::Store>();
auto& kv_store = *kv_store_p;
auto ledger_secrets = std::make_shared<ccf::LedgerSecrets>();
@ -790,7 +791,7 @@ TEST_CASE(
member_info->put(member_id, {ccf::MemberStatus::ACTIVE});
member_public_encryption_keys->put(
member_id, ccf::crypto::make_rsa_key_pair()->public_key_pem());
REQUIRE(tx.commit() == kv::CommitResult::SUCCESS);
REQUIRE(tx.commit() == ccf::kv::CommitResult::SUCCESS);
}
std::atomic<bool> all_submitted = false;
@ -824,7 +825,7 @@ TEST_CASE(
tx.wo(map_b)->put(42, i);
}
REQUIRE(tx.commit() == kv::CommitResult::SUCCESS);
REQUIRE(tx.commit() == ccf::kv::CommitResult::SUCCESS);
++i;
std::this_thread::yield();
}

Просмотреть файл

@ -42,11 +42,11 @@ static std::vector<ActionDesc> create_actions(
ExpectedSeqNos& seqnos_value)
{
std::vector<ActionDesc> actions;
actions.push_back({seqnos_hello, [](size_t i, kv::Tx& tx) {
actions.push_back({seqnos_hello, [](size_t i, ccf::kv::Tx& tx) {
tx.wo(map_a)->put("hello", "value doesn't matter");
return true;
}});
actions.push_back({seqnos_saluton, [](size_t i, kv::Tx& tx) {
actions.push_back({seqnos_saluton, [](size_t i, ccf::kv::Tx& tx) {
if (i % 2 == 0)
{
tx.wo(map_a)->put("saluton", "value doesn't matter");
@ -54,7 +54,7 @@ static std::vector<ActionDesc> create_actions(
}
return false;
}});
actions.push_back({seqnos_1, [](size_t i, kv::Tx& tx) {
actions.push_back({seqnos_1, [](size_t i, ccf::kv::Tx& tx) {
if (i % 3 == 0)
{
tx.wo(map_b)->put(1, 42);
@ -62,7 +62,7 @@ static std::vector<ActionDesc> create_actions(
}
return false;
}});
actions.push_back({seqnos_2, [](size_t i, kv::Tx& tx) {
actions.push_back({seqnos_2, [](size_t i, ccf::kv::Tx& tx) {
if (i % 4 == 0)
{
tx.wo(map_b)->put(2, 42);
@ -70,7 +70,7 @@ static std::vector<ActionDesc> create_actions(
}
return false;
}});
actions.push_back({seqnos_set, [](size_t i, kv::Tx& tx) {
actions.push_back({seqnos_set, [](size_t i, ccf::kv::Tx& tx) {
if (i % 5 == 0)
{
tx.wo(set_a)->insert("set key");
@ -78,7 +78,7 @@ static std::vector<ActionDesc> create_actions(
}
return false;
}});
actions.push_back({seqnos_value, [](size_t i, kv::Tx& tx) {
actions.push_back({seqnos_value, [](size_t i, ccf::kv::Tx& tx) {
if (i % 6 == 0)
{
tx.wo(value_a)->put("value doesn't matter");
@ -181,7 +181,7 @@ TEST_CASE("Basic cache" * doctest::test_suite("lfs"))
TEST_CASE("Integrated cache" * doctest::test_suite("lfs"))
{
kv::Store kv_store;
ccf::kv::Store kv_store;
auto consensus = std::make_shared<AllCommittableConsensus>();
kv_store.set_consensus(consensus);
@ -189,7 +189,7 @@ TEST_CASE("Integrated cache" * doctest::test_suite("lfs"))
auto fetcher = std::make_shared<TestTransactionFetcher>();
ccf::indexing::Indexer indexer(fetcher);
auto encryptor = std::make_shared<kv::NullTxEncryptor>();
auto encryptor = std::make_shared<ccf::kv::NullTxEncryptor>();
kv_store.set_encryptor(encryptor);
messaging::BufferProcessor host_bp("lfs_host");
@ -394,7 +394,7 @@ TEST_CASE("Integrated cache" * doctest::test_suite("lfs"))
auto index_b = std::make_shared<StratB>(map_b, node_context, 100, 4);
REQUIRE(indexer.install_strategy(index_b));
kv::TxID current_ = kv_store.current_txid();
ccf::kv::TxID current_ = kv_store.current_txid();
ccf::TxID current{current_.term, current_.version};
REQUIRE(index_a->get_indexed_watermark() == current);
REQUIRE(index_b->get_indexed_watermark() == ccf::TxID());
@ -505,7 +505,7 @@ TEST_CASE("Integrated cache" * doctest::test_suite("lfs"))
void run_sparse_index_test(size_t bucket_size, size_t num_buckets)
{
kv::Store kv_store;
ccf::kv::Store kv_store;
auto consensus = std::make_shared<AllCommittableConsensus>();
kv_store.set_consensus(consensus);
@ -513,7 +513,7 @@ void run_sparse_index_test(size_t bucket_size, size_t num_buckets)
auto fetcher = std::make_shared<TestTransactionFetcher>();
ccf::indexing::Indexer indexer(fetcher);
auto encryptor = std::make_shared<kv::NullTxEncryptor>();
auto encryptor = std::make_shared<ccf::kv::NullTxEncryptor>();
kv_store.set_encryptor(encryptor);
messaging::BufferProcessor host_bp("lfs_host");
@ -565,7 +565,7 @@ void run_sparse_index_test(size_t bucket_size, size_t num_buckets)
{
handle_b->put(k, k);
}
REQUIRE(tx.commit() == kv::CommitResult::SUCCESS);
REQUIRE(tx.commit() == ccf::kv::CommitResult::SUCCESS);
const auto seqno = tx.get_txid()->version;
for (const auto& k : keys)
{
@ -580,7 +580,7 @@ void run_sparse_index_test(size_t bucket_size, size_t num_buckets)
auto tx = kv_store.create_tx();
auto handle_a = tx.wo(map_a);
handle_a->put("ignore", "ignore");
REQUIRE(tx.commit() == kv::CommitResult::SUCCESS);
REQUIRE(tx.commit() == ccf::kv::CommitResult::SUCCESS);
}
};

Просмотреть файл

@ -12,10 +12,10 @@ namespace ccf::indexing
public:
virtual ~TransactionFetcher() = default;
virtual kv::ReadOnlyStorePtr deserialise_transaction(
virtual ccf::kv::ReadOnlyStorePtr deserialise_transaction(
ccf::SeqNo seqno, const uint8_t* data, size_t size) = 0;
virtual std::vector<kv::ReadOnlyStorePtr> fetch_transactions(
virtual std::vector<ccf::kv::ReadOnlyStorePtr> fetch_transactions(
const SeqNoCollection& seqnos) = 0;
};
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше