@ -6,6 +6,7 @@
# define BITCOIN_IPC_CAPNP_COMMON_TYPES_H
# include <clientversion.h>
# include <primitives/transaction.h>
# include <serialize.h>
# include <streams.h>
# include <univalue.h>
@ -17,6 +18,24 @@
namespace ipc {
namespace capnp {
//! Construct a ParamStream wrapping a data stream with serialization parameters
//! needed to pass transaction objects between bitcoin processes.
//! In the future, more params may be added here to serialize other objects that
//! require serialization parameters. Params should just be chosen to serialize
//! objects completely and ensure that serializing and deserializing objects
//! with the specified parameters produces equivalent objects. It's also
//! harmless to specify serialization parameters here that are not used.
template < typename S >
auto Wrap ( S & s )
{
return ParamsStream { s , TX_WITH_WITNESS } ;
}
//! Detect if type has a deserialize_type constructor, which is
//! used to deserialize types like CTransaction that can't be unserialized into
//! existing objects because they are immutable.
template < typename T >
concept Deserializable = std : : is_constructible_v < T , : : deserialize_type , : : DataStream & > ;
} // namespace capnp
} // namespace ipc
@ -36,7 +55,8 @@ void CustomBuildField(TypeList<LocalType>, Priority<1>, InvokeContext& invoke_co
requires Serializable < LocalType , DataStream > & & std : : is_same_v < LocalType , std : : remove_cv_t < std : : remove_reference_t < LocalType > > >
{
DataStream stream ;
value . Serialize ( stream ) ;
auto wrapper { ipc : : capnp : : Wrap ( stream ) } ;
value . Serialize ( wrapper ) ;
auto result = output . init ( stream . size ( ) ) ;
memcpy ( result . begin ( ) , stream . data ( ) , stream . size ( ) ) ;
}
@ -47,16 +67,32 @@ requires Serializable<LocalType, DataStream> && std::is_same_v<LocalType, std::r
//! priority, and higher priority hooks could take precedence over this one.
template < typename LocalType , typename Input , typename ReadDest >
decltype ( auto ) CustomReadField ( TypeList < LocalType > , Priority < 1 > , InvokeContext & invoke_context , Input & & input , ReadDest & & read_dest )
requires Unserializable < LocalType , DataStream >
requires Unserializable < LocalType , DataStream > & & ( ! ipc : : capnp : : Deserializable < LocalType > )
{
return read_dest . update ( [ & ] ( auto & value ) {
if ( ! input . has ( ) ) return ;
auto data = input . get ( ) ;
SpanReader stream ( { data . begin ( ) , data . end ( ) } ) ;
value . Unserialize ( stream ) ;
auto wrapper { ipc : : capnp : : Wrap ( stream ) } ;
value . Unserialize ( wrapper ) ;
} ) ;
}
//! Overload multiprocess library's CustomReadField hook to allow any object
//! with a deserialize constructor to be read from a capnproto Data field or
//! returned from capnproto interface. Use Priority<1> so this hook has medium
//! priority, and higher priority hooks could take precedence over this one.
template < typename LocalType , typename Input , typename ReadDest >
decltype ( auto ) CustomReadField ( TypeList < LocalType > , Priority < 1 > , InvokeContext & invoke_context , Input & & input , ReadDest & & read_dest )
requires ipc : : capnp : : Deserializable < LocalType >
{
assert ( input . has ( ) ) ;
auto data = input . get ( ) ;
SpanReader stream ( { data . begin ( ) , data . end ( ) } ) ;
auto wrapper { ipc : : capnp : : Wrap ( stream ) } ;
return read_dest . construct ( : : deserialize , wrapper ) ;
}
//! Overload CustomBuildField and CustomReadField to serialize UniValue
//! parameters and return values as JSON strings.
template < typename Value , typename Output >