Treat std::shared_ptr nullptr as empty Data #235

issue Sjors openend this issue on December 5, 2025
  1. Sjors commented at 5:24 pm on December 5, 2025: member

    E.g. we have:

    0virtual bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CTransactionRef coinbase) = 0;
    

    Which maps to:

    0submitSolution [@9](/bitcoin-core-multiprocess/contributor/9/) (context: Proxy.Context, version: UInt32, timestamp: UInt32, nonce: UInt32, coinbase :Data) -> (result: Bool);
    

    Which crashes when you pass an empty coinbase.

    I think the solution is to convert an empty Data to nullptr and vice versa.

    That would make my life easier in https://github.com/bitcoin/bitcoin/pull/34020 where I introduce:

    0virtual std::vector<CTransactionRef> getTransactions(const std::vector<Txid>& txids) = 0;
    
    0getTransactions [@6](/bitcoin-core-multiprocess/contributor/6/) (context :Proxy.Context, txids: List(Data)) -> (result: List(Data));
    

    A quick LLM session suggests this should do the trick:

     0diff --git a/src/ipc/libmultiprocess/include/mp/type-pointer.h b/src/ipc/libmultiprocess/include/mp/type-pointer.h
     1index 98b7aa817f..af7d42c710 100644
     2--- a/src/ipc/libmultiprocess/include/mp/type-pointer.h
     3+++ b/src/ipc/libmultiprocess/include/mp/type-pointer.h
     4@@ -50,34 +50,40 @@ decltype(auto) CustomReadField(TypeList<std::shared_ptr<LocalType>>,
     5     ReadDest&& read_dest)
     6 {
     7     return read_dest.update([&](auto& value) {
     8         if (!input.has()) {
     9             value.reset();
    10+        } else if (input.get().size() == 0) {
    11+            value.reset();
    12         } else if (value) {
    13             ReadField(TypeList<LocalType>(), invoke_context, input, ReadDestUpdate(*value));
    14         } else {
    15             ReadField(TypeList<LocalType>(), invoke_context, input,
    16                 ReadDestEmplace(TypeList<LocalType>(), [&](auto&&... args) -> auto& {
    17                     value = std::make_shared<LocalType>(std::forward<decltype(args)>(args)...);
    18                     return *value;
    19                 }));
    20         }
    21     });
    22 }
    23
    24 template <typename LocalType, typename Input, typename ReadDest>
    25 decltype(auto) CustomReadField(TypeList<std::shared_ptr<const LocalType>>,
    26     Priority<1>,
    27     InvokeContext& invoke_context,
    28     Input&& input,
    29     ReadDest&& read_dest)
    30 {
    31     return read_dest.update([&](auto& value) {
    32         if (!input.has()) {
    33             value.reset();
    34             return;
    35         }
    36+        if (input.get().size() == 0) {
    37+            value.reset();
    38+            return;
    39+        }
    40         ReadField(TypeList<LocalType>(), invoke_context, std::forward<Input>(input),
    41             ReadDestEmplace(TypeList<LocalType>(), [&](auto&&... args) -> auto& {
    42                 value = std::make_shared<LocalType>(std::forward<decltype(args)>(args)...);
    43                 return *value;
    44             }));
    
  2. Sjors commented at 5:22 am on January 5, 2026: member
    @ryanofsky do you plan to open a PR for this or should I take your commit from https://github.com/bitcoin/bitcoin/pull/34020#issuecomment-3624001654 and open one?


Sjors


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/libmultiprocess. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-01-07 07:30 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me