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 }));