Skip to content

Commit

Permalink
Added PoC of TON HTTP API C++
Browse files Browse the repository at this point in the history
  • Loading branch information
kdimentionaltree committed Dec 16, 2024
1 parent 19c26e1 commit ea3f08d
Show file tree
Hide file tree
Showing 35 changed files with 295 additions and 36 deletions.
Binary file added .DS_Store
Binary file not shown.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,12 @@ cython_debug/
/sandbox
sandbox.ipynb
/trace*.txt

# build
[Bb][Uu][Ii][Ll][Dd]*
sandbox/

# vs code
.vscode/
.idea/
.DS_Store
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
[submodule "external/pybind11"]
path = external/pybind11
url = https://github.com/pybind/pybind11.git
[submodule "external/userver"]
path = external/userver
url = https://github.com/userver-framework/userver.git
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ set(CMAKE_CXX_EXTENSIONS FALSE)

set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
set(PY_TONLIB_MULTICLIENT FALSE CACHE BOOL "Build python bindings")
set(TON_HTTP_API_CPP TRUE CACHE BOOL "Build TON HTTP API")

add_subdirectory(external/ton EXCLUDE_FROM_ALL)

add_subdirectory(src)
add_subdirectory(tonlib-multiclient)
add_subdirectory(examples)

if (PY_TONLIB_MULTICLIENT)
add_subdirectory(external/pybind11 EXCLUDE_FROM_ALL)
add_subdirectory(py)
endif()

if (TON_HTTP_API_CPP)
add_subdirectory(external/userver EXCLUDE_FROM_ALL)
add_subdirectory(ton-http-api)
endif()
8 changes: 4 additions & 4 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

add_executable(tonlib_multiclient_promise_example_bin promise.cpp)
target_link_libraries(tonlib_multiclient_promise_example_bin PUBLIC tonlib::multiclient)
target_include_directories(tonlib_multiclient_promise_example_bin PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src)
target_include_directories(tonlib_multiclient_promise_example_bin PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..)

add_executable(tonlib_multiclient_promise_function_req_example_bin promise_function_req.cpp)
target_link_libraries(tonlib_multiclient_promise_function_req_example_bin PUBLIC tonlib::multiclient tl_tonlib_api)
target_include_directories(tonlib_multiclient_promise_function_req_example_bin PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src)
target_include_directories(tonlib_multiclient_promise_function_req_example_bin PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..)

add_executable(tonlib_multiclient_callback_example_bin callback.cpp)
target_link_libraries(tonlib_multiclient_callback_example_bin PUBLIC tonlib::multiclient tl_tonlib_api_json)
target_include_directories(tonlib_multiclient_callback_example_bin PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src)
target_include_directories(tonlib_multiclient_callback_example_bin PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..)

add_executable(tonlib_multiclient_json_example_bin json.cpp)
target_link_libraries(tonlib_multiclient_json_example_bin PUBLIC tonlib::multiclient)
target_include_directories(tonlib_multiclient_json_example_bin PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src)
target_include_directories(tonlib_multiclient_json_example_bin PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..)
12 changes: 6 additions & 6 deletions examples/callback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#include "auto/tl/tonlib_api.h"
#include "auto/tl/tonlib_api.hpp"
#include "auto/tl/tonlib_api_json.h"
#include "multiclient/multi_client.h"
#include "multiclient/request.h"
#include "multiclient/response_callback.h"
#include "tonlib-multiclient/multi_client.h"
#include "tonlib-multiclient/request.h"
#include "tonlib-multiclient/response_callback.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/logging.h"
#include "tl/tl_json.h"
Expand Down Expand Up @@ -45,9 +45,9 @@ int main(int argc, char* argv[]) {
std::unordered_set<uint64_t> requests{};

multiclient::MultiClient client(
multiclient::MultiClientConfig{
.global_config_path = std::filesystem::path("/code/ton/ton-multiclient/global-config.json"),
.key_store_root = std::filesystem::path("/code/ton/ton-multiclient/keystore"),
multiclient::MultiClientConfig{
.global_config_path = std::filesystem::path("/tmp/global-config.json"),
.key_store_root = std::filesystem::path("/tmp/keystore"),
.scheduler_threads = 6,
},
std::make_unique<Cb>(requests)
Expand Down
8 changes: 4 additions & 4 deletions examples/json.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#include <unistd.h>
#include "multiclient/multi_client.h"
#include "multiclient/request.h"
#include "tonlib-multiclient/multi_client.h"
#include "tonlib-multiclient/request.h"
#include "td/utils/logging.h"
#include "tonlib/Logging.h"

int main(int argc, char* argv[]) {
tonlib::Logging::set_verbosity_level(3);

multiclient::MultiClient client(multiclient::MultiClientConfig{
.global_config_path = std::filesystem::path("/code/ton/ton-multiclient/global-config.json"),
.key_store_root = std::filesystem::path("/code/ton/ton-multiclient/keystore"),
.global_config_path = std::filesystem::path("/tmp/global-config.json"),
.key_store_root = std::filesystem::path("/tmp/keystore"),
.scheduler_threads = 6,
});

Expand Down
8 changes: 4 additions & 4 deletions examples/promise.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#include <unistd.h>
#include "auto/tl/tonlib_api.h"
#include "multiclient/multi_client.h"
#include "multiclient/request.h"
#include "tonlib-multiclient/multi_client.h"
#include "tonlib-multiclient/request.h"
#include "td/utils/logging.h"


int main(int argc, char* argv[]) {
multiclient::MultiClient client(multiclient::MultiClientConfig{
.global_config_path = std::filesystem::path("/code/ton/ton-multiclient/global-config.json"),
.key_store_root = std::filesystem::path("/code/ton/ton-multiclient/keystore"),
.global_config_path = std::filesystem::path("/tmp/global-config.json"),
.key_store_root = std::filesystem::path("/tmp/keystore"),
.scheduler_threads = 6,
});

Expand Down
8 changes: 4 additions & 4 deletions examples/promise_function_req.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <unistd.h>
#include "auto/tl/tonlib_api.h"
#include "multiclient/multi_client.h"
#include "multiclient/request.h"
#include "tonlib-multiclient/multi_client.h"
#include "tonlib-multiclient/request.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
#include "tonlib/Logging.h"
Expand All @@ -10,8 +10,8 @@ int main(int argc, char* argv[]) {
tonlib::Logging::set_verbosity_level(3);

multiclient::MultiClient client(multiclient::MultiClientConfig{
.global_config_path = std::filesystem::path("/code/ton/ton-multiclient/global-config.json"),
.key_store_root = std::filesystem::path("/code/ton/ton-multiclient/keystore"),
.global_config_path = std::filesystem::path("/tmp/global-config.json"),
.key_store_root = std::filesystem::path("/tmp/keystore"),
.scheduler_threads = 6,
});

Expand Down
1 change: 1 addition & 0 deletions external/userver
Submodule userver added at 097ed1
2 changes: 1 addition & 1 deletion py/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ find_package(Python COMPONENTS Interpreter Development)

add_library(${PROJECT_NAME} MODULE tonlib_multiclient.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE pybind11::module pybind11::lto tonlib::multiclient)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..)
set_target_properties(${PROJECT_NAME} PROPERTIES
PREFIX ""
OUTPUT_NAME "tonlib_multiclient"
Expand Down
4 changes: 2 additions & 2 deletions py/tonlib_multiclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include <memory>
#include <utility>
#include <vector>
#include "multiclient/multi_client.h"
#include "multiclient/request.h"
#include "tonlib_multiclient/multi_client.h"
#include "tonlib_multiclient/request.h"
#include "td/utils/Status.h"
#include "tonlib/Logging.h"

Expand Down
3 changes: 0 additions & 3 deletions src/CMakeLists.txt

This file was deleted.

Binary file added ton-http-api/.DS_Store
Binary file not shown.
37 changes: 37 additions & 0 deletions ton-http-api/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
cmake_minimum_required(VERSION 3.16)
project(ton-http-api-cpp CXX)

set(USERVER_FEATURE_REDIS TRUE)
set(USERVER_FEATURE_UBOOST_CORO TRUE)
userver_setup_environment()

set(TON_HTTP_API_CPP_SOURCE
main.cpp
handlers.hpp
handlers.cpp
tonlib_component.cpp
tonlib_component.h
tonlib_worker.cpp
tonlib_worker.h
handler_api_v2.cpp
handler_api_v2.h
)

add_executable(${PROJECT_NAME} ${TON_HTTP_API_CPP_SOURCE})
target_include_directories(${PROJECT_NAME}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../external/userver
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../external/ton
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..
)
#target_link_directories(ton-http-api-cpp
# PRIVATE external/userver
# PRIVATE external/ton
#)

target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
target_link_libraries(${PROJECT_NAME} userver::core tonlib::multiclient)
# target_link_options(ton-http-api-cpp PUBLIC -rdynamic)

install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)


50 changes: 50 additions & 0 deletions ton-http-api/handler_api_v2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "handler_api_v2.h"

#include "tl/tl_json.h"
#include "auto/tl/tonlib_api.h"
#include "auto/tl/tonlib_api_json.h"
#include "td/utils/JsonBuilder.h"
#include "tonlib-multiclient/request.h"
#include "userver/components/component_context.hpp"

namespace ton_http::handlers {
std::string ApiV2Handler::HandleRequestThrow(
const userver::server::http::HttpRequest& request, userver::server::request::RequestContext& context
) const {
request.GetHttpResponse().SetContentType(userver::http::content_type::kApplicationJson);
auto& ton_api_method = request.GetPathArg("ton_api_method");
LOG_WARNING() << "Got request " << ton_api_method;

// call method
td::StringBuilder result_sb;
bool is_ok = false;
if (ton_api_method == "getMasterchainInfo") {
auto resp = tonlib_component_.DoRequest(multiclient::Request<ton::tonlib_api::blocks_getMasterchainInfo>{
.parameters = {.mode = multiclient::RequestMode::Multiple, .clients_number = 1},
.request_creator = [] {
return ton::tonlib_api::blocks_getMasterchainInfo();
},
});
if (resp.is_error()) {
result_sb << resp.move_as_error();
} else {
const auto res = resp.move_as_ok();
auto str = td::json_encode<td::string>(td::ToJson(res));
result_sb << str;
is_ok = true;
}
}
else {
result_sb << "not implemented";
}

auto result = userver::formats::json::ValueBuilder();
result["ok"] = is_ok;
result[(is_ok? "result" : "error")] = userver::formats::json::FromString(result_sb.as_cslice().str());
return userver::formats::json::ToString(result.ExtractValue());
}
ApiV2Handler::ApiV2Handler(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context)
: HttpHandlerBase(config, context), tonlib_component_(context.FindComponent<ton_http::core::TonlibComponent>())
{}

}
15 changes: 15 additions & 0 deletions ton-http-api/handler_api_v2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once
#include "tonlib_component.h"
#include "userver/server/handlers/http_handler_base.hpp"

namespace ton_http::handlers {
class ApiV2Handler final : public userver::server::handlers::HttpHandlerBase {
public:
static constexpr std::string_view kName = "handler-api-v2";
using HttpHandlerBase::HttpHandlerBase;
std::string HandleRequestThrow(const userver::server::http::HttpRequest& request, userver::server::request::RequestContext& context) const override;
ApiV2Handler(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context);
private:
ton_http::core::TonlibComponent& tonlib_component_;
};
}
15 changes: 15 additions & 0 deletions ton-http-api/handlers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "handlers.hpp"
#include "userver/formats/json.hpp"

namespace ton_http::handlers {

std::string HelloHandler::HandleRequestThrow(const userver::server::http::HttpRequest &request, userver::server::request::RequestContext &context) const {
request.GetHttpResponse().SetContentType(userver::http::content_type::kApplicationJson);
auto &name = request.GetArg("name");

auto result = userver::formats::json::ValueBuilder();
result["ok"] = true;
result["result"] = "Hello!";
return userver::formats::json::ToString(result.ExtractValue());
}
}
19 changes: 19 additions & 0 deletions ton-http-api/handlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include "userver/components/component_list.hpp"
#include "userver/server/handlers/http_handler_base.hpp"
#include "userver/server/handlers/http_handler_base.hpp"

// #include "userver/utest/using_namespace_userver.hpp"

namespace ton_http::handlers {

class HelloHandler final : public userver::server::handlers::HttpHandlerBase {
public:
static constexpr std::string_view kName = "handler-hello-sample";

using HttpHandlerBase::HttpHandlerBase;
std::string HandleRequestThrow(const userver::server::http::HttpRequest &request, userver::server::request::RequestContext &context) const override;
};

}
18 changes: 18 additions & 0 deletions ton-http-api/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "handler_api_v2.h"
#include "userver/components/minimal_server_component_list.hpp"
#include "userver/server/handlers/server_monitor.hpp"
#include "userver/utils/daemon_run.hpp"

#include "handlers.hpp"
#include "tonlib/Logging.h"
#include "tonlib_component.h"

int main(int argc, char* argv[]) {
tonlib::Logging::set_verbosity_level(3);

auto component_list = userver::components::MinimalServerComponentList();
component_list.Append<userver::server::handlers::ServerMonitor>();
component_list.Append<ton_http::core::TonlibComponent>();
component_list.Append<ton_http::handlers::ApiV2Handler>();
return userver::utils::DaemonMain(argc, argv, component_list);
}
50 changes: 50 additions & 0 deletions ton-http-api/tonlib_component.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "tonlib_component.h"
#include "userver/components/component.hpp"
#include "userver/components/component_context.hpp"
#include "userver/dynamic_config/storage/component.hpp"
#include "userver/dynamic_config/value.hpp"
#include "userver/logging/log.hpp"
#include "userver/yaml_config/merge_schemas.hpp"


namespace ton_http::core {

TonlibComponent::TonlibComponent(
const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context
) :
userver::components::ComponentBase(config, context),
config_(context.FindComponent<userver::components::DynamicConfig>().GetSource()),
tonlib_(multiclient::MultiClientConfig{
.global_config_path = config["global_config"].As<std::string>(),
.key_store_root = config["keystore"].As<std::string>(),
.scheduler_threads = config["threads"].As<std::size_t>()
}),
task_processor_(context.GetTaskProcessor(config["task_processor"].As<std::string>())) {
}
const multiclient::MultiClient& TonlibComponent::GetTonlib() const {
return tonlib_;
}

userver::yaml_config::Schema TonlibComponent::GetStaticConfigSchema() {
return userver::yaml_config::MergeSchemas<userver::components::ComponentBase>(R"(
type: object
description: tonlib component config
additionalProperties: false
properties:
global_config:
type: string
description: path to TON network config
keystore:
type: string
description: path to Tonlib keystore
threads:
type: integer
description: number of Tonlib threads
task_processor:
type: string
description: task processor name
)");
}


}
Loading

0 comments on commit ea3f08d

Please sign in to comment.