Skip to content

Treat std::shared_ptr nullptr as empty Data #235

Description

@Sjors

E.g. we have:

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

Which maps to:

submitSolution @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 bitcoin/bitcoin#34020 where I introduce:

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

A quick LLM session suggests this should do the trick:

diff --git a/src/ipc/libmultiprocess/include/mp/type-pointer.h b/src/ipc/libmultiprocess/include/mp/type-pointer.h
index 98b7aa817f..af7d42c710 100644
--- a/src/ipc/libmultiprocess/include/mp/type-pointer.h
+++ b/src/ipc/libmultiprocess/include/mp/type-pointer.h
@@ -50,34 +50,40 @@ decltype(auto) CustomReadField(TypeList<std::shared_ptr<LocalType>>,
     ReadDest&& read_dest)
 {
     return read_dest.update([&](auto& value) {
         if (!input.has()) {
             value.reset();
+        } else if (input.get().size() == 0) {
+            value.reset();
         } else if (value) {
             ReadField(TypeList<LocalType>(), invoke_context, input, ReadDestUpdate(*value));
         } else {
             ReadField(TypeList<LocalType>(), invoke_context, input,
                 ReadDestEmplace(TypeList<LocalType>(), [&](auto&&... args) -> auto& {
                     value = std::make_shared<LocalType>(std::forward<decltype(args)>(args)...);
                     return *value;
                 }));
         }
     });
 }

 template <typename LocalType, typename Input, typename ReadDest>
 decltype(auto) CustomReadField(TypeList<std::shared_ptr<const LocalType>>,
     Priority<1>,
     InvokeContext& invoke_context,
     Input&& input,
     ReadDest&& read_dest)
 {
     return read_dest.update([&](auto& value) {
         if (!input.has()) {
             value.reset();
             return;
         }
+        if (input.get().size() == 0) {
+            value.reset();
+            return;
+        }
         ReadField(TypeList<LocalType>(), invoke_context, std::forward<Input>(input),
             ReadDestEmplace(TypeList<LocalType>(), [&](auto&&... args) -> auto& {
                 value = std::make_shared<LocalType>(std::forward<decltype(args)>(args)...);
                 return *value;
             }));

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions