diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7e3634374..b0a0499bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Build device tree automatically into machine's ROM, eliminating the need for a ROM image
- Enabled rollup by default
- Updated libboost version to 1.81
+- Removed remote-cartesi-machine-proxy
## [0.15.2] - 2023-08-21
### Changed
diff --git a/Dockerfile b/Dockerfile
index 3553bcd99..dbafc662a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -7,7 +7,7 @@ ARG SANITIZE=no
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -y \
build-essential vim wget git clang-tidy-15 clang-format-15 lcov \
- libreadline-dev libboost-coroutine1.81-dev libboost-context1.81-dev \
+ libreadline-dev libboost-context1.81-dev \
libboost-filesystem1.81-dev libssl-dev libc-ares-dev zlib1g-dev \
ca-certificates automake libtool patchelf cmake pkg-config lua5.4 liblua5.4-dev \
libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc \
diff --git a/Makefile b/Makefile
index da632cee4..30747c049 100644
--- a/Makefile
+++ b/Makefile
@@ -56,7 +56,7 @@ CHMOD_EXEC= chmod 0755
CHMOD_DATA= chmod 0644
STRIP_EXEC= strip -x
-EMU_TO_BIN= jsonrpc-remote-cartesi-machine remote-cartesi-machine remote-cartesi-machine-proxy merkle-tree-hash
+EMU_TO_BIN= jsonrpc-remote-cartesi-machine remote-cartesi-machine merkle-tree-hash
EMU_TO_LIB= $(LIBCARTESI_SO_$(UNAME)) $(LIBCARTESI_SO_GRPC_$(UNAME))
EMU_LUA_TO_BIN= cartesi-machine.lua cartesi-machine-stored-hash.lua rollup-memory-range.lua
EMU_LUA_TEST_TO_BIN= cartesi-machine-tests.lua uarch-riscv-tests.lua
diff --git a/README.md b/README.md
index d59b987b8..2405b7339 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ Obs: Please note that Apple Clang Version number does not follow upstream LLVM/C
```
apt-get install build-essential wget git clang-tidy-15 clang-format-15 \
- libreadline-dev libboost-coroutine1.81-dev libboost-context1.81-dev \
+ libreadline-dev libboost-context1.81-dev \
libboost-filesystem1.81-dev libssl-dev libc-ares-dev zlib1g-dev \
ca-certificates automake libtool patchelf cmake pkg-config lua5.4 liblua5.4-dev \
libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc \
diff --git a/src/Makefile b/src/Makefile
index 0117896b1..1299f50e3 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -85,7 +85,6 @@ PROTOBUF_LIB_Darwin:=-L/opt/local/lib -lprotobuf -lpthread
endif
endif
-BOOST_CORO_LIB_Darwin:=$(BOOST_LIB_DIR_Darwin) -lboost_coroutine-mt -lboost_context-mt
BOOST_FILESYSTEM_LIB_Darwin:=$(BOOST_LIB_DIR_Darwin) -lboost_system-mt -lboost_filesystem-mt
BOOST_PROCESS_LIB_Darwin:=-lpthread
LIBCARTESI_Darwin=libcartesi-$(EMULATOR_VERSION_MAJOR).$(EMULATOR_VERSION_MINOR).dylib
@@ -106,7 +105,6 @@ CC_Linux=gcc
CXX_Linux=g++
INCS_Linux=
FS_LIB_Linux=-lstdc++fs
-BOOST_CORO_LIB_Linux:=-lboost_coroutine -lboost_context
BOOST_FILESYSTEM_LIB_Linux:=-lboost_system -lboost_filesystem
BOOST_PROCESS_LIB_Linux:=-lpthread
BOOST_INC_Linux=
@@ -132,7 +130,6 @@ PROFILE_DATA_Linux=
CC=$(CC_$(UNAME))
CXX=$(CXX_$(UNAME))
SOLDFLAGS:=$(SOLDFLAGS_$(UNAME)) $(GCLDFLAGS)
-BOOST_CORO_LIB=$(BOOST_CORO_LIB_$(UNAME))
BOOST_PROCESS_LIB=$(BOOST_PROCESS_LIB_$(UNAME))
BOOST_FILESYSTEM_LIB=$(BOOST_FILESYSTEM_LIB_$(UNAME))
BOOST_INC=$(BOOST_INC_$(UNAME))
@@ -163,7 +160,6 @@ LUACARTESI_GRPC_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) $(LIBCARTESI_GRPC_LIB)
LUACARTESI_JSONRPC_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) $(B64_LIB)
REMOTE_CARTESI_MACHINE_LIBS:=$(CRYPTOPP_LIB) $(GRPC_LIB) $(PROTOBUF_LIB) $(B64_LIB)
JSONRPC_REMOTE_CARTESI_MACHINE_LIBS:=$(CRYPTOPP_LIB) $(B64_LIB)
-REMOTE_CARTESI_MACHINE_PROXY_LIBS:=$(CRYPTOPP_LIB) $(GRPC_LIB) $(PROTOBUF_LIB) $(BOOST_CORO_LIB) -ldl
TEST_MACHINE_C_API_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) $(LIBCARTESI_GRPC_LIB) $(BOOST_PROCESS_LIB) $(BOOST_FILESYSTEM_LIB) $(B64_LIB)
HASH_LIBS:=$(CRYPTOPP_LIB)
@@ -523,7 +519,7 @@ luacartesi-pgo:
$(MAKE) --no-print-directory use
$(MAKE) clean-profile
-grpc: cartesi/jsonrpc.so cartesi/grpc.so remote-cartesi-machine remote-cartesi-machine-proxy
+grpc: cartesi/jsonrpc.so cartesi/grpc.so remote-cartesi-machine
jsonrpc: cartesi/jsonrpc.so jsonrpc-remote-cartesi-machine
@@ -556,11 +552,6 @@ $(PROTO_OBJS): CXXFLAGS += -Wno-zero-length-array -Wno-unused-parameter -Wno-de
PROTO_SOURCES:=$(PROTO_OBJS:.o=.cc)
-REMOTE_CARTESI_MACHINE_PROXY_OBJS:= \
- $(GRPC_GEN_OBJS) \
- $(PROTOBUF_GEN_OBJS) \
- remote-machine-proxy.o
-
REMOTE_CARTESI_MACHINE_OBJS:= \
$(GRPC_GEN_OBJS) \
$(PROTOBUF_GEN_OBJS) \
@@ -699,10 +690,7 @@ $(BUILDDIR)/lib/mongoose.o: CFLAGS := $(patsubst %-std=c99,%,$(CFLAGS))
jsonrpc-remote-cartesi-machine: $(JSONRPC_REMOTE_CARTESI_MACHINE_OBJS)
$(CXX) $(LDFLAGS) $(CARTESI_EXECUTABLE_LDFLAGS) -o $@ $(JSONRPC_REMOTE_CARTESI_MACHINE_OBJS) $(JSONRPC_REMOTE_CARTESI_MACHINE_LIBS)
-remote-cartesi-machine-proxy: $(REMOTE_CARTESI_MACHINE_PROXY_OBJS)
- $(CXX) $(LDFLAGS) $(CARTESI_EXECUTABLE_LDFLAGS) -o $@ $(REMOTE_CARTESI_MACHINE_PROXY_OBJS) $(REMOTE_CARTESI_MACHINE_PROXY_LIBS)
-
-remote-cartesi-machine remote-cartesi-machine-proxy: CXXFLAGS := $(GRPC_INC) $(CXXFLAGS)
+remote-cartesi-machine: CXXFLAGS := $(GRPC_INC) $(CXXFLAGS)
tests/test-machine-c-api: $(TEST_MACHINE_C_API_OBJS) $(LIBCARTESI) $(LIBCARTESI_GRPC)
$(CXX) $(LDFLAGS) $(CARTESI_EXECUTABLE_LDFLAGS) -o $@ $(TEST_MACHINE_C_API_OBJS) $(TEST_MACHINE_C_API_LIBS)
@@ -717,7 +705,7 @@ tests/test-machine-c-api: $(TEST_MACHINE_C_API_OBJS) $(LIBCARTESI) $(LIBCARTESI_
protobuf-util.o: $(PROTOBUF_GEN_OBJS)
-grpc-virtual-machine.o grpc-machine-c-api.o remote-machine.o proxy.o: $(GRPC_GEN_OBJS) $(PROTOBUF_GEN_OBJS)
+grpc-virtual-machine.o grpc-machine-c-api.o remote-machine.o: $(GRPC_GEN_OBJS) $(PROTOBUF_GEN_OBJS)
machine-c-version.h: ../tools/template/machine-c-version.h.template
sed "s|EMULATOR_MARCHID|$(EMULATOR_MARCHID)|g;s|EMULATOR_VERSION_MAJOR|$(EMULATOR_VERSION_MAJOR)|g;s|EMULATOR_VERSION_MINOR|$(EMULATOR_VERSION_MINOR)|g;s|EMULATOR_VERSION_PATCH|$(EMULATOR_VERSION_PATCH)|g;s|EMULATOR_VERSION_LABEL|$(EMULATOR_VERSION_LABEL)|g" $< > $@
@@ -767,7 +755,7 @@ clean-libcartesi: clean-objs
@rm -f $(LIBCARTESI) $(LIBCARTESI_GRPC) cartesi.so cartesi/grpc.so cartesi/jsonrpc.so
clean-executables:
- @rm -f jsonrpc-remote-cartesi-machine remote-cartesi-machine remote-cartesi-machine-proxy merkle-tree-hash
+ @rm -f jsonrpc-remote-cartesi-machine remote-cartesi-machine merkle-tree-hash
clean-tests:
@rm -f tests/test-merkle-tree-hash tests/test-machine-c-api
diff --git a/src/remote-machine-proxy.cpp b/src/remote-machine-proxy.cpp
deleted file mode 100644
index 884496051..000000000
--- a/src/remote-machine-proxy.cpp
+++ /dev/null
@@ -1,1006 +0,0 @@
-// Copyright Cartesi and individual authors (see AUTHORS)
-// SPDX-License-Identifier: LGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation, either version 3 of the License, or (at your option) any
-// later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-// PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License along
-// with this program (see COPYING). If not, see .
-//
-
-#include
-#include
-#include
-
-using namespace std::string_literals;
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#pragma GCC diagnostic ignored "-Wdeprecated-copy"
-#include
-#include
-#define BOOST_DLL_USE_STD_FS
-#include
-#pragma GCC diagnostic pop
-
-static constexpr uint32_t proxy_version_major = 0;
-static constexpr uint32_t proxy_version_minor = 7;
-static constexpr uint32_t proxy_version_patch = 0;
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#pragma GCC diagnostic ignored "-Wdeprecated-copy"
-#pragma GCC diagnostic ignored "-Wtype-limits"
-#include
-#include
-
-#include "cartesi-machine-checkin.grpc.pb.h"
-#include "cartesi-machine.grpc.pb.h"
-#pragma GCC diagnostic pop
-
-using namespace CartesiMachine;
-using namespace Versioning;
-
-// gRPC async server calls involve a variety of objects:
-// 1) The service object;
-// 2) A server context object;
-// 3) One or two server completion queues;
-// 4) The protobuf request and response messages;
-// 5) A writer object for the response message.
-// 6) A request status object
-//
-// gRPC async server calls have the following life-cycle
-// 1) We "request" from the service object that it starts accepting requests
-// for a given by calling service->Request() method, and
-// passing the server context, a request message to receive the request, the
-// writer object for the response, the completion queue, and a tag.
-// 2) Once a request for arrives, the completion queue will return
-// the corresponding tag
-// 3) After performing the requested task, we fill out a response message, and
-// ask the writer object to send the response, using writer->Finish(), passing
-// the response message, a status object, and a tag
-// 4) Once the response has been acknowledged, the completion queue will return
-// the tag
-//
-// PS: To allow for overlapped processing of multiple calls to , we
-// can call service->Request() with a new tag as soon as the
-// completion queue returns the previous tag in 2).
-// PS2: In 1), we can pass two completion queues, one to return the tag in 2)
-// and another to return the tag in 4). These queues are usually the same.
-// PS3: It seems as though a different server context object must be used for
-// each call
-//
-// gRPC async client calls involve fewer objects
-// 1) A stub object
-// 2) A client context object
-// 3) A vanila completion queue
-// 4) Protobuf request and response messages
-// 5) A reader object for the response message
-// 6) A request status object
-//
-// gRPC async client calls have the following life-cycle
-// 1) After filling out a request message, we tell the stub to perform
-// by calling stub->Async(), passing the client context,
-// the request message, and the completion queue. This method returns the reader
-// object.
-// 2) We then call reader->Finish() passing the response object to be filled,
-// the status object to be filled, and a tag
-// 3) Once the response is received, the completion queue will return the tag.
-//
-// In the case of a proxy, the typical situation is that the proxy receives a
-// server call that it can only complete after it performed a client call.
-// The idea is as follows:
-// 1) Completion queue returns tag-1 identifying an server call
-// 2) Processing of tag-1 starts the appropriate client call
-// using stub->Async() and reader->Finish(), and specifes tag-2 for completion
-// 4) Completion queue returns tag-2 identifying the client call is complete
-// 5) Processing of tag-2 passes result back using write->Finish(), and specifies tag-3 for completion
-// 6) Completion queue returns tag-3 identifying results were received
-// 7) Processing of tag-3 calls service->Request() to specify a new
-// tag to handle the next server call
-//
-// Rather than using a state-machine to advance the call state through
-// all these steps, we use coroutines. Each coroutine handles the entire
-// sequence of steps above.
-//
-// The coroutine always arrives in the completion queue. If it is already
-// "finished", it will be deleted. Otherwise, it will be "resumed". If the
-// coroutine returns because it is finished, it will be deleted. If the
-// coroutine returns because it "yielded", and if it yielded
-// side_effect::shutdown, it will be deleted and the server will be shutdown.
-// Otherwise, the coroutine must have yielded side_effect::none, and therefore
-// it *must* arrange for itself to arrive again in the completion queue. If it
-// doesn't arrange this, it will never be deleted. THIS WILL LEAK.
-// Conversely, if the coroutine arranged to be returned from the completion
-// queue, it *must* yield instead of finishing. Otherwise, it will be
-// immediately deleted and a dangling pointer will be returned by the completion
-// queue. THIS WILL CRASH!
-//
-
-struct checkin_context { // NOLINT(bugprone-exception-escape)
- checkin_context(const char *session_id, const char *checkin_address) :
- session_id(session_id),
- checkin_address(checkin_address) {}
- checkin_context(std::string session_id, std::string checkin_address) :
- session_id(std::move(session_id)),
- checkin_address(std::move(checkin_address)) {}
- std::string session_id;
- std::string checkin_address;
-};
-
-struct handler_context {
- std::string proxy_address;
- std::optional checkin;
- std::string session_id;
- Machine::AsyncService async_service;
- MachineCheckIn::AsyncService checkin_async_service;
- std::unique_ptr stub;
- std::unique_ptr completion_queue;
- bool ok;
-};
-
-enum class side_effect { none, shutdown };
-
-using handler = boost::coroutines2::coroutine;
-
-template
-static void writer_finish(grpc::ServerAsyncResponseWriter &writer, const RESP &response,
- const grpc::Status &status, handler::pull_type *self) {
- if (status.ok()) {
- writer.Finish(response, grpc::Status::OK, self);
- } else {
- writer.FinishWithError(status, self);
- }
-}
-
-template request message type
- typename RESP_TYPE, // response message type
- typename SRV_REQ, // functor that invokes Request
- typename CLNT_REQ // functor that invokes Async
- >
-static handler::pull_type *new_handler(const std::string &rpc_name, SRV_REQ start_server_request,
- CLNT_REQ start_client_request, side_effect last_effect = side_effect::none) {
- // Here we had a fun conundrum to solve. We want to allocate a new
- // handler::pull_type object and initialize it with a lambda function that
- // contains the coroutine implementation. However, we want to give this lambda
- // access to the value of the pointer holding the new handler::pull_type object.
- // This is because it needs to use this this pointer in gRPC calls that will
- // return it in the completion queue. If we used the normal new operator, the
- // lambda would be constructed before the value was returned by the operator, and
- // therefore would capture an uninitialized value. So we break the
- // construction into an allocation with operator new and construction with
- // placement new.
- auto *self = static_cast(operator new(sizeof(handler::pull_type)));
- new (self) handler::pull_type{
- [self, rpc_name, start_server_request, start_client_request, last_effect](handler::push_type &yield) {
- using namespace grpc;
- ServerContext server_context;
- REQ_TYPE request;
- ServerAsyncResponseWriter writer(&server_context);
- // Advertise we are ready to process requests
- start_server_request(server_context, request, writer, self);
- // Yield until a request arrives, we are returned in the completion
- // queue, and the dispatcher resumes us
- yield(side_effect::none);
- ClientContext client_context;
- Status status;
- // Start a client request
- auto reader = start_client_request(client_context, request);
- RESP_TYPE response;
- // Advertise we are waiting for the response
- reader->Finish(&response, &status, self);
- // Yield until the response arrives, we are returned in the
- // completion queue, and the dispatcher resumes us
- yield(side_effect::none);
- // Start client response
- writer_finish(writer, response, status, self); // NOLINT: suppress warning caused by gRPC
- // Yield until done sending response, we are returned in the
- // completion queue, and the dispatcher resumes us
- yield(last_effect);
- // Create a new handler for the same
- new_handler(rpc_name, start_server_request, start_client_request);
- // Allow the coroutine to finish. The dispatcher loop will
- // immediately delete it.
- }};
- return self;
-}
-
-static auto new_GetVersion_handler(handler_context &hctx) {
- return new_handler(
- "GetVersion",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestGetVersion(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncGetVersion(&client_context, request, cq);
- });
-}
-
-static auto new_Machine_handler(handler_context &hctx) {
- return new_handler(
- "Machine",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestMachine(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncMachine(&client_context, request, cq);
- });
-}
-
-static auto new_Run_handler(handler_context &hctx) {
- return new_handler(
- "Run",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestRun(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncRun(&client_context, request, cq);
- });
-}
-
-static auto new_RunUarch_handler(handler_context &hctx) {
- return new_handler(
- "RunUarch",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestRunUarch(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncRunUarch(&client_context, request, cq);
- });
-}
-
-static auto new_ResetUarchState_handler(handler_context &hctx) {
- return new_handler(
- "ResetUarchState",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestResetUarchState(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncResetUarchState(&client_context, request, cq);
- });
-}
-
-static auto new_Store_handler(handler_context &hctx) {
- return new_handler(
- "Store",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestStore(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncStore(&client_context, request, cq);
- });
-}
-
-static auto new_Destroy_handler(handler_context &hctx) {
- return new_handler(
- "Destroy",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestDestroy(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncDestroy(&client_context, request, cq);
- });
-}
-
-static auto new_Snapshot_handler(handler_context &hctx) {
- return new_handler(
- "Snapshot",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestSnapshot(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncSnapshot(&client_context, request, cq);
- });
-}
-
-static auto new_Rollback_handler(handler_context &hctx) {
- return new_handler(
- "Rollback",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestRollback(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncRollback(&client_context, request, cq);
- });
-}
-
-static auto new_Shutdown_handler(handler_context &hctx) {
- return new_handler(
- "Shutdown",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestShutdown(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncShutdown(&client_context, request, cq);
- },
- side_effect::shutdown);
-}
-
-static auto new_StepUarch_handler(handler_context &hctx) {
- return new_handler(
- "StepUarch",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestStepUarch(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncStepUarch(&client_context, request, cq);
- });
-}
-
-static auto new_ReadMemory_handler(handler_context &hctx) {
- return new_handler(
- "ReadMemory",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestReadMemory(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncReadMemory(&client_context, request, cq);
- });
-}
-
-static auto new_WriteMemory_handler(handler_context &hctx) {
- return new_handler(
- "WriteMemory",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestWriteMemory(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncWriteMemory(&client_context, request, cq);
- });
-}
-
-static auto new_ReadWord_handler(handler_context &hctx) {
- return new_handler(
- "ReadWord",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestReadWord(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncReadWord(&client_context, request, cq);
- });
-}
-
-static auto new_GetRootHash_handler(handler_context &hctx) {
- return new_handler(
- "GetRootHash",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestGetRootHash(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncGetRootHash(&client_context, request, cq);
- });
-}
-
-static auto new_GetProof_handler(handler_context &hctx) {
- return new_handler(
- "GetProof",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestGetProof(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncGetProof(&client_context, request, cq);
- });
-}
-
-static auto new_ReplaceMemoryRange_handler(handler_context &hctx) {
- return new_handler(
- "ReplaceMemoryRange",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestReplaceMemoryRange(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncReplaceMemoryRange(&client_context, request, cq);
- });
-}
-
-static auto new_GetXAddress_handler(handler_context &hctx) {
- return new_handler(
- "GetXAddress",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestGetXAddress(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncGetXAddress(&client_context, request, cq);
- });
-}
-
-static auto new_ReadX_handler(handler_context &hctx) {
- return new_handler(
- "ReadX",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestReadX(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncReadX(&client_context, request, cq);
- });
-}
-
-static auto new_WriteX_handler(handler_context &hctx) {
- return new_handler(
- "WriteX",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestWriteX(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncWriteX(&client_context, request, cq);
- });
-}
-
-static auto new_GetUarchXAddress_handler(handler_context &hctx) {
- return new_handler(
- "GetUarchXAddress",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestGetUarchXAddress(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncGetUarchXAddress(&client_context, request, cq);
- });
-}
-
-static auto new_ReadUarchX_handler(handler_context &hctx) {
- return new_handler(
- "ReadUarchX",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestReadUarchX(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncReadUarchX(&client_context, request, cq);
- });
-}
-
-static auto new_WriteUarchX_handler(handler_context &hctx) {
- return new_handler(
- "WriteUarchX",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestWriteUarchX(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncWriteUarchX(&client_context, request, cq);
- });
-}
-
-static auto new_ResetIflagsY_handler(handler_context &hctx) {
- return new_handler(
- "ResetIflagsY",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestResetIflagsY(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncResetIflagsY(&client_context, request, cq);
- });
-}
-
-static auto new_GetCsrAddress_handler(handler_context &hctx) {
- return new_handler(
- "GetCsrAddress",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestGetCsrAddress(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncGetCsrAddress(&client_context, request, cq);
- });
-}
-
-static auto new_ReadCsr_handler(handler_context &hctx) {
- return new_handler(
- "ReadCsr",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestReadCsr(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncReadCsr(&client_context, request, cq);
- });
-}
-
-static auto new_WriteCsr_handler(handler_context &hctx) {
- return new_handler(
- "WriteCsr",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestWriteCsr(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncWriteCsr(&client_context, request, cq);
- });
-}
-
-static auto new_GetInitialConfig_handler(handler_context &hctx) {
- return new_handler(
- "GetInitialConfig",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestGetInitialConfig(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncGetInitialConfig(&client_context, request, cq);
- });
-}
-
-static auto new_VerifyMerkleTree_handler(handler_context &hctx) {
- return new_handler(
- "VerifyMerkleTree",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestVerifyMerkleTree(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncVerifyMerkleTree(&client_context, request, cq);
- });
-}
-
-static auto new_VerifyDirtyPageMaps_handler(handler_context &hctx) {
- return new_handler(
- "VerifyDirtyPageMaps",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestVerifyDirtyPageMaps(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncVerifyDirtyPageMaps(&client_context, request, cq);
- });
-}
-
-static auto new_DumpPmas_handler(handler_context &hctx) {
- return new_handler(
- "DumpPmas",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestDumpPmas(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncDumpPmas(&client_context, request, cq);
- });
-}
-
-static auto new_GetDefaultConfig_handler(handler_context &hctx) {
- return new_handler(
- "GetDefaultConfig",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestGetDefaultConfig(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncGetDefaultConfig(&client_context, request, cq);
- });
-}
-
-static auto new_VerifyAccessLog_handler(handler_context &hctx) {
- return new_handler(
- "VerifyAccessLog",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestVerifyAccessLog(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncVerifyAccessLog(&client_context, request, cq);
- });
-}
-
-static auto new_VerifyStateTransition_handler(handler_context &hctx) {
- return new_handler(
- "VerifyStateTransition",
- [&hctx](auto &server_context, auto &request, auto &writer, auto self) {
- auto *cq = hctx.completion_queue.get();
- hctx.async_service.RequestVerifyStateTransition(&server_context, &request, &writer, cq, cq, self);
- },
- [&hctx](auto &client_context, auto &request) {
- auto *cq = hctx.completion_queue.get();
- return hctx.stub->AsyncVerifyStateTransition(&client_context, request, cq);
- });
-}
-
-static bool forward_checkin(handler_context &hctx) {
- if (hctx.checkin.has_value()) {
- auto stub = MachineCheckIn::NewStub(
- grpc::CreateChannel(hctx.checkin.value().checkin_address, grpc::InsecureChannelCredentials()));
- CheckInRequest request;
- request.set_session_id(hctx.checkin.value().session_id);
- request.set_address(hctx.proxy_address);
- Void response;
- grpc::ClientContext context;
- auto status = stub->CheckIn(&context, request, &response);
- if (!status.ok()) {
- std::cerr << "failed to forward checkin\n";
- return false;
- }
- }
- return true;
-}
-
-static bool build_client(handler_context &hctx, const CheckInRequest &request) {
- // Instantiate client connection
- hctx.stub = Machine::NewStub(grpc::CreateChannel(request.address(), grpc::InsecureChannelCredentials()));
- if (!hctx.stub) {
- std::cerr << "failed to connect to server\n";
- return false;
- }
- // Try to get version from client
- const Void version_request;
- GetVersionResponse version_response;
- grpc::ClientContext client_context;
- auto status = hctx.stub->GetVersion(&client_context, version_request, &version_response);
- if (!status.ok()) {
- std::cerr << "failed to obtain server version\n";
- return false;
- }
- std::cerr << "connected to server: version is " << version_response.version().major() << "."
- << version_response.version().minor() << "." << version_response.version().patch() << "\n";
- if (version_response.version().major() != proxy_version_major ||
- version_response.version().minor() != proxy_version_minor) {
- std::cerr << "proxy is incompatible with server\n";
- return false;
- }
- return true;
-}
-
-static handler::pull_type *new_CheckIn_handler(handler_context &hctx) {
- auto *self = static_cast(operator new(sizeof(handler::pull_type)));
- new (self) handler::pull_type{[self, &hctx](handler::push_type &yield) {
- using namespace grpc;
- ServerContext server_context;
- CheckInRequest request;
- ServerAsyncResponseWriter writer(&server_context);
- auto *cq = hctx.completion_queue.get();
- // Install handler for CheckIn and wait
- hctx.checkin_async_service.RequestCheckIn(&server_context, &request, &writer, cq, cq, self);
- yield(side_effect::none);
- // Acknowledge check-in
- const Void response;
- writer.Finish(response, grpc::Status::OK, self); // NOLINT: suppress warning caused by gRPC
- // If we succeeded building a compatible client connection
- // to the server, enable all handlers
- if (build_client(hctx, request) && forward_checkin(hctx)) {
- yield(side_effect::none);
- } else {
- yield(side_effect::shutdown);
- }
- // Create a new CheckIn handler
- new_CheckIn_handler(hctx);
- }};
- return self;
-}
-
-static handler::pull_type *new_SetCheckInTarget_handler(handler_context &hctx) {
- auto *self = static_cast(operator new(sizeof(handler::pull_type)));
- new (self) handler::pull_type{[self, &hctx](handler::push_type &yield) {
- using namespace grpc;
- ServerContext server_context;
- SetCheckInTargetRequest request;
- ServerAsyncResponseWriter writer(&server_context);
- auto *cq = hctx.completion_queue.get();
- // Install handler for SetCheckInTarget and wait
- hctx.async_service.RequestSetCheckInTarget(&server_context, &request, &writer, cq, cq, self);
- yield(side_effect::none);
- hctx.checkin = checkin_context{request.session_id(), request.address()};
- // Acknowledge SetCheckinTarget request
- const Void response;
- writer.Finish(response, grpc::Status::OK, self); // NOLINT: suppress warning caused by gRPC
- yield(side_effect::none);
- // Create a new SetCheckInTarget handler
- new_SetCheckInTarget_handler(hctx);
- }};
- return self;
-}
-
-static std::string replace_port(const std::string &address, int port) {
- // Unix address?
- if (address.find("unix:") == 0) {
- return address;
- }
- auto pos = address.find_last_of(':');
- // If already has a port, replace
- if (pos != std::string::npos) {
- return address.substr(0, pos) + ":" + std::to_string(port);
- // Otherwise, concatenate
- } else {
- return address + ":" + std::to_string(port);
- }
-}
-
-static auto build_proxy(const char *address, handler_context &hctx) {
- grpc::ServerBuilder builder;
- builder.AddChannelArgument(GRPC_ARG_ALLOW_REUSEPORT, 0);
- int proxy_port = 0;
- builder.AddListeningPort(address, grpc::InsecureServerCredentials(), &proxy_port);
- builder.RegisterService(&hctx.async_service);
- builder.RegisterService(&hctx.checkin_async_service);
- hctx.completion_queue = builder.AddCompletionQueue();
- auto server = builder.BuildAndStart();
- hctx.proxy_address = replace_port(address, proxy_port);
- return server;
-}
-
-static void enable_server_handlers(handler_context &hctx) {
- new_GetVersion_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_SetCheckInTarget_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_Machine_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_Run_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_RunUarch_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_ResetUarchState_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_Store_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_Destroy_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_Snapshot_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_Rollback_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_Shutdown_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_StepUarch_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_ReadMemory_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_WriteMemory_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_ReadWord_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_GetRootHash_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_GetProof_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_ReplaceMemoryRange_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_GetXAddress_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_ReadX_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_WriteX_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_GetUarchXAddress_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_ReadUarchX_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_WriteUarchX_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_ResetIflagsY_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_GetCsrAddress_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_ReadCsr_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_WriteCsr_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_GetInitialConfig_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_VerifyMerkleTree_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_VerifyDirtyPageMaps_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_DumpPmas_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_GetDefaultConfig_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_VerifyAccessLog_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_VerifyStateTransition_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
- new_CheckIn_handler(hctx); // NOLINT: cannot leak (pointer is in completion queue)
-} // NOLINT: cannot leak (pointer is in completion queue)
-
-static void drain_completion_queue(grpc::ServerCompletionQueue *completion_queue) {
- completion_queue->Shutdown();
- bool ok = false;
- handler::pull_type *h = nullptr;
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- while (completion_queue->Next(reinterpret_cast(&h), &ok)) {
- delete h;
- }
-}
-
-static bool finished(handler::pull_type *c) {
- return !(*c);
-}
-
-/// \brief Checks if string matches prefix and captures remaninder
-/// \param pre Prefix to match in str.
-/// \param str Input string
-/// \param val If string matches prefix, points to remaninder
-/// \returns True if string matches prefix, false otherwise
-static bool stringval(const char *pre, const char *str, const char **val) {
- const size_t len = strlen(pre);
- if (strncmp(pre, str, len) == 0) {
- *val = str + len;
- return true;
- }
- return false;
-}
-
-static void help(const char *name) {
- (void) fprintf(stderr, R"(Usage:
-
- %s --proxy-address= [options] []
-
-where options are
-
- --proxy-address=
- gives the address proxy will bind to, where can be
- :
- :
- unix:
-
- --server-address= or []
- passed to the spawned remote cartesi machine
- default: localhost:0
-
- --checkin-address=
- address to which a check-in message will be sent informing the
- new proxy is ready. The check-in message also informs the
- selected for the server and the session id
-
- --session-id=
- arbitrary string used when sending the check-in message
-
- --help
- prints this message and exits
-
-)",
- name);
-}
-
-int main(int argc, char *argv[]) try {
-
- const char *proxy_address = nullptr;
- const char *server_address = "localhost:0";
- const char *checkin_address = nullptr;
- const char *session_id = nullptr;
-
- if (argc < 1) { // NOLINT: of course it could be < 1...
- std::cerr << "missing argv[0]\n";
- exit(1);
- }
-
- for (int i = 1; i < argc; i++) { // NOLINT: Unknown. Maybe linter bug?
- if (stringval("--proxy-address=", argv[i], &proxy_address)) {
- ;
- } else if (stringval("--server-address=", argv[i], &server_address)) {
- ;
- } else if (stringval("--checkin-address=", argv[i], &checkin_address)) {
- ;
- } else if (stringval("--session-id=", argv[i], &session_id)) {
- ;
- } else if (strcmp(argv[i], "--help") == 0) {
- help(argv[0]);
- exit(0);
- } else {
- if (!server_address) {
- server_address = argv[i];
- } else {
- std::cerr << "repeated [] option";
- exit(1);
- }
- }
- }
-
- if (!proxy_address) {
- std::cerr << "missing proxy-address\n";
- exit(1);
- }
-
- if ((session_id == nullptr) != (checkin_address == nullptr)) {
- (void) fprintf(stderr, "session-id and checkin-address must be used together\n");
- exit(1);
- }
-
- handler_context hctx{};
-
- std::cerr << "proxy version is " << proxy_version_major << "." << proxy_version_minor << "." << proxy_version_patch
- << "\n";
-
- auto proxy = build_proxy(proxy_address, hctx);
- if (!proxy) {
- std::cerr << "proxy creation failed\n";
- exit(1);
- }
-
- struct sigaction sa {};
- sa.sa_handler = SIG_IGN; // NOLINT(cppcoreguidelines-pro-type-union-access)
- sa.sa_flags = SA_RESTART;
- sigaction(SIGCHLD, &sa, nullptr);
-
- // spawn server
- std::string remote_cartesi_machine_path = boost::dll::program_location().replace_filename("remote-cartesi-machine");
- boost::process::group server_group;
-
- auto cmdline = remote_cartesi_machine_path + " --server-address=" + server_address +
- " --checkin-address=" + hctx.proxy_address;
- if (session_id && checkin_address) {
- hctx.checkin = checkin_context{session_id, checkin_address};
- cmdline += " --session-id="s + session_id;
- } else {
- cmdline += " --session-id=proxy"s;
- }
-
- try {
- // NOLINTNEXTLINE: boost generated warnings
- auto server_process = boost::process::child(cmdline, server_group); // NOLINT: suppress warning caused by boost
- server_process.detach();
- } catch (boost::process::process_error &e) {
- std::cerr << "failed spawning remote-cartesi-machine with command-line '" + cmdline + "' (" + e.what() + ")\n";
- goto shutdown; // NOLINT(cppcoreguidelines-avoid-goto)
- }
-
- enable_server_handlers(hctx);
-
- for (;;) {
- // Obtain the next active handler coroutine
- handler::pull_type *h = nullptr; // NOLINT: cannot leak (drain_completion_queue kills remaining)
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- if (!hctx.completion_queue->Next(reinterpret_cast(&h), &hctx.ok)) {
- goto shutdown; // NOLINT(cppcoreguidelines-avoid-goto)
- }
- // If the coroutine is finished, simply delete it
- // This can't really happen here, because the coroutine ALWAYS yields
- // after arranging for the completion queue to return it, rather than
- // finishing.
- if (finished(h)) {
- delete h;
- } else {
- // Otherwise, resume it
- (*h)();
- // If it is now finished after being resumed, simply delete it
- if (finished(h)) {
- delete h;
- } else {
- // Otherwise, if requested a shutdown, delete this coroutine and
- // shutdown. The other pending coroutines will be deleted when
- // we drain the completion queue.
- if (h->get() == side_effect::shutdown) {
- delete h;
- goto shutdown; // NOLINT(cppcoreguidelines-avoid-goto)
- }
- }
- }
- }
-
-shutdown:
- // Shutdown proxy before completion queue
- proxy->Shutdown();
- drain_completion_queue(hctx.completion_queue.get());
- server_group.terminate();
- server_group.wait();
- return 0;
-} catch (std::exception &e) {
- std::cerr << "Caught exception: " << e.what() << '\n';
- return 1;
-} catch (...) {
- std::cerr << "Caught unknown exception\n";
- return 1;
-}
diff --git a/tools/template/control.template b/tools/template/control.template
index f3b06bf68..55bcbcb3e 100644
--- a/tools/template/control.template
+++ b/tools/template/control.template
@@ -5,7 +5,7 @@ Homepage: https://docs.cartesi.io/machine/host/cmdline/
Architecture: ARG_ARCH
Maintainer: Machine Reference Unit
Provides: machine-emulator
-Depends: libboost-coroutine1.81.0, libboost-context1.81.0, libboost-filesystem1.81.0, libreadline8, openssl, libc-ares2, zlib1g, ca-certificates, libgomp1, lua5.4, libb64-0d, libcrypto++8, libprotobuf32, libgrpc++1.51
+Depends: libboost-context1.81.0, libboost-filesystem1.81.0, libreadline8, openssl, libc-ares2, zlib1g, ca-certificates, libgomp1, lua5.4, libb64-0d, libcrypto++8, libprotobuf32, libgrpc++1.51
Section: devel
Priority: optional
Multi-Arch: foreign