Disclaimer: I am not very familiar with this codebase, so I would appreciate feedback on whether this is a desirable change, or if there is a preferred way to handle this case.
This PR updates proxy generation for methods where the Cap’n Proto result field is declared before other output fields, but the corresponding C++ method has output parameters before its return value.
A concrete example is Bitcoin Core’s BlockTemplate.submitSolution IPC method. It currently returns:
submitSolution (...) -> (result: Bool);
But if we need to add rejection details:
submitSolution (...) -> (result: Bool, reason: Text, debug: Text);
The result field needs to stay first to preserve the existing wire field number for compatibility. But the C++ method naturally looks like:
bool submitSolution(..., std::string& reason, std::string& debug);
The issue is that the Cap’n Proto field order would be result, reason, debug, but the corresponding C++ order is reason, debug, result: reason and debug are output parameters, while result is the method return value. Current mpgen output follows the Cap’n Proto order, so it generates C++ code that passes the fields in the wrong order for this method signature.
This PR changes mpgen to emit non-return fields first, then emit the result return-value field last. That keeps Cap’n Proto schema order independent from C++ invocation order, allowing schemas to preserve wire compatibility while still mapping correctly to C++ signatures.
The test changes add a regression method:
addResultOut [@23](/bitcoin-core-multiprocess/contributor/23/) (value :Int32) -> (result :Int32, text :Text);
mapped to:
int addResultOut(int value, std::string& text);
The test verifies both the C++ return value and output parameter are transmitted correctly.