Bitcoin Core 28.99.0
P2P Digital Currency
common-types.h
Go to the documentation of this file.
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>
11#include <serialize.h>
12#include <streams.h>
13#include <univalue.h>
14
15#include <cstddef>
16#include <mp/proxy-types.h>
17#include <type_traits>
18#include <utility>
19
20namespace ipc {
21namespace capnp {
29template <typename S>
30auto Wrap(S& s)
31{
33}
34
38template <typename T>
39concept Deserializable = std::is_constructible_v<T, ::deserialize_type, ::DataStream&>;
40} // namespace capnp
41} // namespace ipc
42
44namespace mp {
49template <typename LocalType, typename Value, typename Output>
50void CustomBuildField(TypeList<LocalType>, Priority<1>, InvokeContext& invoke_context, Value&& value, Output&& output)
51// Enable if serializeable and if LocalType is not cv or reference qualified. If
52// LocalType is cv or reference qualified, it is important to fall back to
53// lower-priority Priority<0> implementation of this function that strips cv
54// references, to prevent this CustomBuildField overload from taking precedence
55// over more narrow overloads for specific LocalTypes.
56requires Serializable<LocalType, DataStream> && std::is_same_v<LocalType, std::remove_cv_t<std::remove_reference_t<LocalType>>>
57{
58 DataStream stream;
59 auto wrapper{ipc::capnp::Wrap(stream)};
60 value.Serialize(wrapper);
61 auto result = output.init(stream.size());
62 memcpy(result.begin(), stream.data(), stream.size());
63}
64
69template <typename LocalType, typename Input, typename ReadDest>
70decltype(auto) CustomReadField(TypeList<LocalType>, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest)
72{
73 return read_dest.update([&](auto& value) {
74 if (!input.has()) return;
75 auto data = input.get();
76 SpanReader stream({data.begin(), data.end()});
77 auto wrapper{ipc::capnp::Wrap(stream)};
78 value.Unserialize(wrapper);
79 });
80}
81
86template <typename LocalType, typename Input, typename ReadDest>
87decltype(auto) CustomReadField(TypeList<LocalType>, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest)
89{
90 assert(input.has());
91 auto data = input.get();
92 SpanReader stream({data.begin(), data.end()});
93 auto wrapper{ipc::capnp::Wrap(stream)};
94 return read_dest.construct(::deserialize, wrapper);
95}
96
99template <class Rep, class Period, typename Value, typename Output>
100void CustomBuildField(TypeList<std::chrono::duration<Rep, Period>>, Priority<1>, InvokeContext& invoke_context, Value&& value,
101 Output&& output)
102{
103 static_assert(std::numeric_limits<decltype(output.get())>::lowest() <= std::numeric_limits<Rep>::lowest(),
104 "capnp type does not have enough range to hold lowest std::chrono::duration value");
105 static_assert(std::numeric_limits<decltype(output.get())>::max() >= std::numeric_limits<Rep>::max(),
106 "capnp type does not have enough range to hold highest std::chrono::duration value");
107 output.set(value.count());
108}
109
110template <class Rep, class Period, typename Input, typename ReadDest>
111decltype(auto) CustomReadField(TypeList<std::chrono::duration<Rep, Period>>, Priority<1>, InvokeContext& invoke_context,
112 Input&& input, ReadDest&& read_dest)
113{
114 return read_dest.construct(input.get());
115}
116
119template <typename Value, typename Output>
120void CustomBuildField(TypeList<UniValue>, Priority<1>, InvokeContext& invoke_context, Value&& value, Output&& output)
121{
122 std::string str = value.write();
123 auto result = output.init(str.size());
124 memcpy(result.begin(), str.data(), str.size());
125}
126
127template <typename Input, typename ReadDest>
128decltype(auto) CustomReadField(TypeList<UniValue>, Priority<1>, InvokeContext& invoke_context, Input&& input,
129 ReadDest&& read_dest)
130{
131 return read_dest.update([&](auto& value) {
132 auto data = input.get();
133 value.read(std::string_view{data.begin(), data.size()});
134 });
135}
136
150template <typename LocalType, typename Value, typename Output>
151void CustomBuildField(TypeList<LocalType>, Priority<2>, InvokeContext& invoke_context, Value&& value, Output&& output)
152requires
153 (std::is_same_v<decltype(output.get()), ::capnp::Data::Builder>) &&
154 (std::convertible_to<Value, std::span<const std::byte>> ||
155 std::convertible_to<Value, std::span<const char>> ||
156 std::convertible_to<Value, std::span<const unsigned char>> ||
157 std::convertible_to<Value, std::span<const signed char>>)
158{
159 auto data = std::span{value};
160 auto result = output.init(data.size());
161 memcpy(result.begin(), data.data(), data.size());
162}
163} // namespace mp
164
165#endif // BITCOIN_IPC_CAPNP_COMMON_TYPES_H
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:147
size_type size() const
Definition: streams.h:181
value_type * data()
Definition: streams.h:188
Wrapper that overrides the GetParams() function of a stream.
Definition: serialize.h:1113
Minimal stream for reading from an existing byte array by Span.
Definition: streams.h:101
If none of the specialized versions above matched, default to calling member function.
Definition: serialize.h:747
Detect if type has a deserialize_type constructor, which is used to deserialize types like CTransacti...
Definition: common-types.h:39
auto Wrap(S &s)
Construct a ParamStream wrapping a data stream with serialization parameters needed to pass transacti...
Definition: common-types.h:30
Definition: ipc.h:12
Functions to serialize / deserialize common bitcoin types.
Definition: common-types.h:44
decltype(auto) CustomReadField(TypeList< LocalType >, Priority< 1 >, InvokeContext &invoke_context, Input &&input, ReadDest &&read_dest)
Overload multiprocess library's CustomReadField hook to allow any object with an Unserialize method t...
Definition: common-types.h:70
void CustomBuildField(TypeList< LocalType >, Priority< 1 >, InvokeContext &invoke_context, Value &&value, Output &&output)
Overload multiprocess library's CustomBuildField hook to allow any serializable object to be stored i...
Definition: common-types.h:50
#define S(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
static constexpr TransactionSerParams TX_WITH_WITNESS
Definition: transaction.h:195
constexpr deserialize_type deserialize
Definition: serialize.h:49
assert(!tx.IsCoinBase())