LCOV - code coverage report
Current view: top level - src/ipc/capnp - common-types.h (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 100.0 % 33 33
Test Date: 2025-08-25 05:11:47 Functions: 45.0 % 40 18
Branches: 28.1 % 32 9

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2023 The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :             : 
       5                 :             : #ifndef BITCOIN_IPC_CAPNP_COMMON_TYPES_H
       6                 :             : #define BITCOIN_IPC_CAPNP_COMMON_TYPES_H
       7                 :             : 
       8                 :             : #include <clientversion.h>
       9                 :             : #include <interfaces/types.h>
      10                 :             : #include <primitives/transaction.h>
      11                 :             : #include <serialize.h>
      12                 :             : #include <streams.h>
      13                 :             : #include <univalue.h>
      14                 :             : 
      15                 :             : #include <cstddef>
      16                 :             : #include <mp/proxy-types.h>
      17                 :             : #include <mp/type-chrono.h>
      18                 :             : #include <mp/type-context.h>
      19                 :             : #include <mp/type-data.h>
      20                 :             : #include <mp/type-decay.h>
      21                 :             : #include <mp/type-interface.h>
      22                 :             : #include <mp/type-message.h>
      23                 :             : #include <mp/type-number.h>
      24                 :             : #include <mp/type-optional.h>
      25                 :             : #include <mp/type-pointer.h>
      26                 :             : #include <mp/type-string.h>
      27                 :             : #include <mp/type-struct.h>
      28                 :             : #include <mp/type-threadmap.h>
      29                 :             : #include <mp/type-vector.h>
      30                 :             : #include <type_traits>
      31                 :             : #include <utility>
      32                 :             : 
      33                 :             : namespace ipc {
      34                 :             : namespace capnp {
      35                 :             : //! Construct a ParamStream wrapping a data stream with serialization parameters
      36                 :             : //! needed to pass transaction objects between bitcoin processes.
      37                 :             : //! In the future, more params may be added here to serialize other objects that
      38                 :             : //! require serialization parameters. Params should just be chosen to serialize
      39                 :             : //! objects completely and ensure that serializing and deserializing objects
      40                 :             : //! with the specified parameters produces equivalent objects. It's also
      41                 :             : //! harmless to specify serialization parameters here that are not used.
      42                 :             : template <typename S>
      43                 :           8 : auto Wrap(S& s)
      44                 :             : {
      45                 :           8 :     return ParamsStream{s, TX_WITH_WITNESS};
      46                 :             : }
      47                 :             : 
      48                 :             : //! Detect if type has a deserialize_type constructor, which is
      49                 :             : //! used to deserialize types like CTransaction that can't be unserialized into
      50                 :             : //! existing objects because they are immutable.
      51                 :             : template <typename T>
      52                 :             : concept Deserializable = std::is_constructible_v<T, ::deserialize_type, ::DataStream&>;
      53                 :             : } // namespace capnp
      54                 :             : } // namespace ipc
      55                 :             : 
      56                 :             : //! Functions to serialize / deserialize common bitcoin types.
      57                 :             : namespace mp {
      58                 :             : //! Overload multiprocess library's CustomBuildField hook to allow any
      59                 :             : //! serializable object to be stored in a capnproto Data field or passed to a
      60                 :             : //! capnproto interface. Use Priority<1> so this hook has medium priority, and
      61                 :             : //! higher priority hooks could take precedence over this one.
      62                 :             : template <typename LocalType, typename Value, typename Output>
      63                 :           4 : void CustomBuildField(TypeList<LocalType>, Priority<1>, InvokeContext& invoke_context, Value&& value, Output&& output)
      64                 :             : // Enable if serializeable and if LocalType is not cv or reference qualified. If
      65                 :             : // LocalType is cv or reference qualified, it is important to fall back to
      66                 :             : // lower-priority Priority<0> implementation of this function that strips cv
      67                 :             : // references, to prevent this CustomBuildField overload from taking precedence
      68                 :             : // over more narrow overloads for specific LocalTypes.
      69                 :             : requires Serializable<LocalType, DataStream> && std::is_same_v<LocalType, std::remove_cv_t<std::remove_reference_t<LocalType>>>
      70                 :             : {
      71                 :           4 :     DataStream stream;
      72         [ +  - ]:           4 :     auto wrapper{ipc::capnp::Wrap(stream)};
      73         [ -  + ]:           4 :     value.Serialize(wrapper);
           [ #  #  #  # ]
      74   [ +  -  -  + ]:           4 :     auto result = output.init(stream.size());
      75                 :           4 :     memcpy(result.begin(), stream.data(), stream.size());
      76                 :           4 : }
      77                 :             : 
      78                 :             : //! Overload multiprocess library's CustomReadField hook to allow any object
      79                 :             : //! with an Unserialize method to be read from a capnproto Data field or
      80                 :             : //! returned from capnproto interface. Use Priority<1> so this hook has medium
      81                 :             : //! priority, and higher priority hooks could take precedence over this one.
      82                 :             : template <typename LocalType, typename Input, typename ReadDest>
      83                 :           2 : decltype(auto) CustomReadField(TypeList<LocalType>, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest)
      84                 :             : requires Unserializable<LocalType, DataStream> && (!ipc::capnp::Deserializable<LocalType>)
      85                 :             : {
      86                 :           2 :     return read_dest.update([&](auto& value) {
      87 [ +  - ][ #  #  :           2 :         if (!input.has()) return;
             #  #  #  # ]
           [ #  #  #  # ]
      88                 :           2 :         auto data = input.get();
      89                 :           2 :         SpanReader stream({data.begin(), data.end()});
      90                 :           2 :         auto wrapper{ipc::capnp::Wrap(stream)};
      91                 :           2 :         value.Unserialize(wrapper);
      92                 :           2 :     });
      93                 :             : }
      94                 :             : 
      95                 :             : //! Overload multiprocess library's CustomReadField hook to allow any object
      96                 :             : //! with a deserialize constructor to be read from a capnproto Data field or
      97                 :             : //! returned from capnproto interface. Use Priority<1> so this hook has medium
      98                 :             : //! priority, and higher priority hooks could take precedence over this one.
      99                 :             : template <typename LocalType, typename Input, typename ReadDest>
     100                 :           2 : decltype(auto) CustomReadField(TypeList<LocalType>, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest)
     101                 :             : requires ipc::capnp::Deserializable<LocalType>
     102                 :             : {
     103         [ -  + ]:           2 :     assert(input.has());
     104                 :           2 :     auto data = input.get();
     105                 :           2 :     SpanReader stream({data.begin(), data.end()});
     106                 :           2 :     auto wrapper{ipc::capnp::Wrap(stream)};
     107                 :           2 :     return read_dest.construct(::deserialize, wrapper);
     108                 :             : }
     109                 :             : 
     110                 :             : //! Overload CustomBuildField and CustomReadField to serialize UniValue
     111                 :             : //! parameters and return values as JSON strings.
     112                 :             : template <typename Value, typename Output>
     113                 :           2 : void CustomBuildField(TypeList<UniValue>, Priority<1>, InvokeContext& invoke_context, Value&& value, Output&& output)
     114                 :             : {
     115         [ -  + ]:           2 :     std::string str = value.write();
     116   [ +  -  -  + ]:           4 :     auto result = output.init(str.size());
     117                 :           2 :     memcpy(result.begin(), str.data(), str.size());
     118                 :           2 : }
     119                 :             : 
     120                 :             : template <typename Input, typename ReadDest>
     121                 :           2 : decltype(auto) CustomReadField(TypeList<UniValue>, Priority<1>, InvokeContext& invoke_context, Input&& input,
     122                 :             :                                ReadDest&& read_dest)
     123                 :             : {
     124                 :           2 :     return read_dest.update([&](auto& value) {
     125                 :           2 :         auto data = input.get();
     126                 :           2 :         value.read(std::string_view{data.begin(), data.size()});
     127                 :           2 :     });
     128                 :             : }
     129                 :             : 
     130                 :             : } // namespace mp
     131                 :             : 
     132                 :             : #endif // BITCOIN_IPC_CAPNP_COMMON_TYPES_H
        

Generated by: LCOV version 2.0-1