aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRyan Ofsky <ryan@ofsky.org>2024-07-16 12:38:12 -0400
committerRyan Ofsky <ryan@ofsky.org>2024-09-23 16:03:04 -0400
commitd043950ba245cdcd09dc389a71d43b0a58e41a8b (patch)
treedd16cbd16ff1c7314603891b8ecddd1c2bb46692 /src
parent33c2eee285e35db50b33efb6e782ff002f9d18ec (diff)
multiprocess: Add serialization code for BlockValidationState
Co-authored-by: TheCharlatan <seb.kung@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/ipc/CMakeLists.txt1
-rw-r--r--src/ipc/capnp/mining-types.h10
-rw-r--r--src/ipc/capnp/mining.capnp10
-rw-r--r--src/ipc/capnp/mining.cpp47
-rw-r--r--src/test/ipc_test.capnp5
-rw-r--r--src/test/ipc_test.cpp20
-rw-r--r--src/test/ipc_test.h2
-rw-r--r--src/test/ipc_test_types.h12
8 files changed, 104 insertions, 3 deletions
diff --git a/src/ipc/CMakeLists.txt b/src/ipc/CMakeLists.txt
index 427cd6ea3f..904d72f56e 100644
--- a/src/ipc/CMakeLists.txt
+++ b/src/ipc/CMakeLists.txt
@@ -3,6 +3,7 @@
# file COPYING or https://opensource.org/license/mit/.
add_library(bitcoin_ipc STATIC EXCLUDE_FROM_ALL
+ capnp/mining.cpp
capnp/protocol.cpp
interfaces.cpp
process.cpp
diff --git a/src/ipc/capnp/mining-types.h b/src/ipc/capnp/mining-types.h
index 3204a0b661..2e60b43fcf 100644
--- a/src/ipc/capnp/mining-types.h
+++ b/src/ipc/capnp/mining-types.h
@@ -13,4 +13,14 @@
#include <node/types.h>
#include <validation.h>
+namespace mp {
+// Custom serialization for BlockValidationState.
+void CustomBuildMessage(InvokeContext& invoke_context,
+ const BlockValidationState& src,
+ ipc::capnp::messages::BlockValidationState::Builder&& builder);
+void CustomReadMessage(InvokeContext& invoke_context,
+ const ipc::capnp::messages::BlockValidationState::Reader& reader,
+ BlockValidationState& dest);
+} // namespace mp
+
#endif // BITCOIN_IPC_CAPNP_MINING_TYPES_H
diff --git a/src/ipc/capnp/mining.capnp b/src/ipc/capnp/mining.capnp
index 13d9e2ffb0..4ea69d16c9 100644
--- a/src/ipc/capnp/mining.capnp
+++ b/src/ipc/capnp/mining.capnp
@@ -39,6 +39,12 @@ struct BlockCreateOptions $Proxy.wrap("node::BlockCreateOptions") {
coinbaseOutputMaxAdditionalSigops @2 :UInt64 $Proxy.name("coinbase_output_max_additional_sigops");
}
-# TODO add fields to this struct
-struct BlockValidationState $Proxy.wrap("BlockValidationState") {
+# Note: serialization of the BlockValidationState C++ type is somewhat fragile
+# and using the struct can be awkward. It would be good if testBlockValidity
+# method were changed to return validity information in a simpler format.
+struct BlockValidationState {
+ mode @0 :Int32;
+ result @1 :Int32;
+ rejectReason @2 :Text;
+ debugMessage @3 :Text;
}
diff --git a/src/ipc/capnp/mining.cpp b/src/ipc/capnp/mining.cpp
new file mode 100644
index 0000000000..0f9533c1c7
--- /dev/null
+++ b/src/ipc/capnp/mining.cpp
@@ -0,0 +1,47 @@
+// Copyright (c) 2024 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <ipc/capnp/mining-types.h>
+#include <ipc/capnp/mining.capnp.proxy-types.h>
+
+#include <mp/proxy-types.h>
+
+namespace mp {
+void CustomBuildMessage(InvokeContext& invoke_context,
+ const BlockValidationState& src,
+ ipc::capnp::messages::BlockValidationState::Builder&& builder)
+{
+ if (src.IsValid()) {
+ builder.setMode(0);
+ } else if (src.IsInvalid()) {
+ builder.setMode(1);
+ } else if (src.IsError()) {
+ builder.setMode(2);
+ } else {
+ assert(false);
+ }
+ builder.setResult(static_cast<int>(src.GetResult()));
+ builder.setRejectReason(src.GetRejectReason());
+ builder.setDebugMessage(src.GetDebugMessage());
+}
+
+void CustomReadMessage(InvokeContext& invoke_context,
+ const ipc::capnp::messages::BlockValidationState::Reader& reader,
+ BlockValidationState& dest)
+{
+ if (reader.getMode() == 0) {
+ assert(reader.getResult() == 0);
+ assert(reader.getRejectReason().size() == 0);
+ assert(reader.getDebugMessage().size() == 0);
+ } else if (reader.getMode() == 1) {
+ dest.Invalid(static_cast<BlockValidationResult>(reader.getResult()), reader.getRejectReason(), reader.getDebugMessage());
+ } else if (reader.getMode() == 2) {
+ assert(reader.getResult() == 0);
+ dest.Error(reader.getRejectReason());
+ assert(reader.getDebugMessage().size() == 0);
+ } else {
+ assert(false);
+ }
+}
+} // namespace mp
diff --git a/src/test/ipc_test.capnp b/src/test/ipc_test.capnp
index 32c01dba46..46cd08b94a 100644
--- a/src/test/ipc_test.capnp
+++ b/src/test/ipc_test.capnp
@@ -9,7 +9,9 @@ $Cxx.namespace("gen");
using Proxy = import "/mp/proxy.capnp";
$Proxy.include("test/ipc_test.h");
-$Proxy.includeTypes("ipc/capnp/common-types.h");
+$Proxy.includeTypes("test/ipc_test_types.h");
+
+using Mining = import "../ipc/capnp/mining.capnp";
interface FooInterface $Proxy.wrap("FooImplementation") {
add @0 (a :Int32, b :Int32) -> (result :Int32);
@@ -17,4 +19,5 @@ interface FooInterface $Proxy.wrap("FooImplementation") {
passUniValue @2 (arg :Text) -> (result :Text);
passTransaction @3 (arg :Data) -> (result :Data);
passVectorChar @4 (arg :Data) -> (result :Data);
+ passBlockState @5 (arg :Mining.BlockValidationState) -> (result :Mining.BlockValidationState);
}
diff --git a/src/test/ipc_test.cpp b/src/test/ipc_test.cpp
index 91afce7778..91eba9214f 100644
--- a/src/test/ipc_test.cpp
+++ b/src/test/ipc_test.cpp
@@ -12,6 +12,7 @@
#include <test/ipc_test.capnp.proxy.h>
#include <test/ipc_test.h>
#include <tinyformat.h>
+#include <validation.h>
#include <future>
#include <thread>
@@ -101,6 +102,25 @@ void IpcPipeTest()
std::vector<char> vec2{foo->passVectorChar(vec1)};
BOOST_CHECK_EQUAL(std::string_view(vec1.begin(), vec1.end()), std::string_view(vec2.begin(), vec2.end()));
+ BlockValidationState bs1;
+ bs1.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, "reject reason", "debug message");
+ BlockValidationState bs2{foo->passBlockState(bs1)};
+ BOOST_CHECK_EQUAL(bs1.IsValid(), bs2.IsValid());
+ BOOST_CHECK_EQUAL(bs1.IsError(), bs2.IsError());
+ BOOST_CHECK_EQUAL(bs1.IsInvalid(), bs2.IsInvalid());
+ BOOST_CHECK_EQUAL(static_cast<int>(bs1.GetResult()), static_cast<int>(bs2.GetResult()));
+ BOOST_CHECK_EQUAL(bs1.GetRejectReason(), bs2.GetRejectReason());
+ BOOST_CHECK_EQUAL(bs1.GetDebugMessage(), bs2.GetDebugMessage());
+
+ BlockValidationState bs3;
+ BlockValidationState bs4{foo->passBlockState(bs3)};
+ BOOST_CHECK_EQUAL(bs3.IsValid(), bs4.IsValid());
+ BOOST_CHECK_EQUAL(bs3.IsError(), bs4.IsError());
+ BOOST_CHECK_EQUAL(bs3.IsInvalid(), bs4.IsInvalid());
+ BOOST_CHECK_EQUAL(static_cast<int>(bs3.GetResult()), static_cast<int>(bs4.GetResult()));
+ BOOST_CHECK_EQUAL(bs3.GetRejectReason(), bs4.GetRejectReason());
+ BOOST_CHECK_EQUAL(bs3.GetDebugMessage(), bs4.GetDebugMessage());
+
// Test cleanup: disconnect pipe and join thread
disconnect_client();
thread.join();
diff --git a/src/test/ipc_test.h b/src/test/ipc_test.h
index ca8a5f61b5..2d215a20f1 100644
--- a/src/test/ipc_test.h
+++ b/src/test/ipc_test.h
@@ -8,6 +8,7 @@
#include <primitives/transaction.h>
#include <univalue.h>
#include <util/fs.h>
+#include <validation.h>
class FooImplementation
{
@@ -17,6 +18,7 @@ public:
UniValue passUniValue(UniValue v) { return v; }
CTransactionRef passTransaction(CTransactionRef t) { return t; }
std::vector<char> passVectorChar(std::vector<char> v) { return v; }
+ BlockValidationState passBlockState(BlockValidationState s) { return s; }
};
void IpcPipeTest();
diff --git a/src/test/ipc_test_types.h b/src/test/ipc_test_types.h
new file mode 100644
index 0000000000..b1d4829aa7
--- /dev/null
+++ b/src/test/ipc_test_types.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2024 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TEST_IPC_TEST_TYPES_H
+#define BITCOIN_TEST_IPC_TEST_TYPES_H
+
+#include <ipc/capnp/common-types.h>
+#include <ipc/capnp/mining-types.h>
+#include <test/ipc_test.capnp.h>
+
+#endif // BITCOIN_TEST_IPC_TEST_TYPES_H