diff options
author | Ryan Ofsky <ryan@ofsky.org> | 2024-07-16 12:38:12 -0400 |
---|---|---|
committer | Ryan Ofsky <ryan@ofsky.org> | 2024-09-23 16:03:04 -0400 |
commit | d043950ba245cdcd09dc389a71d43b0a58e41a8b (patch) | |
tree | dd16cbd16ff1c7314603891b8ecddd1c2bb46692 /src | |
parent | 33c2eee285e35db50b33efb6e782ff002f9d18ec (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.txt | 1 | ||||
-rw-r--r-- | src/ipc/capnp/mining-types.h | 10 | ||||
-rw-r--r-- | src/ipc/capnp/mining.capnp | 10 | ||||
-rw-r--r-- | src/ipc/capnp/mining.cpp | 47 | ||||
-rw-r--r-- | src/test/ipc_test.capnp | 5 | ||||
-rw-r--r-- | src/test/ipc_test.cpp | 20 | ||||
-rw-r--r-- | src/test/ipc_test.h | 2 | ||||
-rw-r--r-- | src/test/ipc_test_types.h | 12 |
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 |