1
0
Fork 0
forked from lthn/blockchain

adds POST block/template + POST block/submit

This commit is contained in:
snider 2025-10-17 21:13:46 +01:00
parent 0c76729d68
commit ef59026e39
11 changed files with 491 additions and 0 deletions

View file

@ -18,6 +18,8 @@
#include "controller/path/block.hpp"
#include "controller/path/block/identifier.hpp"
#include "controller/path/block/height.hpp"
#include "controller/path/block/template.hpp"
#include "controller/path/block/submit.hpp"
#include "controller/path/info/version.hpp"
#include "oatpp/network/Server.hpp"
@ -82,6 +84,14 @@ void ApiServer::run() {
docEndpoints->append(blockController->getEndpoints());
router->addController(blockController);
auto blockTemplateController = std::make_shared<BlockTemplateController>();
docEndpoints->append(blockTemplateController->getEndpoints());
router->addController(blockTemplateController);
auto blockSubmitController = std::make_shared<BlockSubmitController>();
docEndpoints->append(blockSubmitController->getEndpoints());
router->addController(blockSubmitController);
auto blockHeightController = std::make_shared<BlockHeightController>();
docEndpoints->append(blockHeightController->getEndpoints());
router->addController(blockHeightController);

View file

@ -0,0 +1,75 @@
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; but maintains OSS status,
// where regional copyright law requires ownership to dictate licence terms.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#ifndef BlockSubmitController_hpp
#define BlockSubmitController_hpp
#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "controller/ApiCoreInfo.hpp"
#include "modal/block/submit_request.hpp"
#include "modal/block/submit_response.hpp"
#include "currency_core/currency_format_utils.h"
#include "currency_core/verification_context.h"
#include OATPP_CODEGEN_BEGIN(ApiController)
class BlockSubmitController : public oatpp::web::server::api::ApiController {
private:
OATPP_COMPONENT(std::shared_ptr<ApiCoreInfo>, m_core_info);
public:
explicit BlockSubmitController(OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper))
: oatpp::web::server::api::ApiController(objectMapper) {}
public:
ENDPOINT_INFO(submitBlock) {
info->summary = "Submit a new block to the network";
info->addTag("Block");
info->addConsumes<Object<SubmitBlockRequestModel>>("application/json");
info->addResponse<Object<SubmitBlockResponseModel>>(Status::CODE_200, "application/json");
info->addResponse(Status::CODE_400, "text/plain");
info->addResponse(Status::CODE_406, "text/plain");
}
ENDPOINT("POST", "/block/submit", submitBlock, BODY_DTO(Object<SubmitBlockRequestModel>, requestModel)) {
if (!requestModel->block_blob || requestModel->block_blob->empty()) {
return createResponse(Status::CODE_400, "Missing block_blob");
}
currency::blobdata blockblob;
if (!epee::string_tools::parse_hexstr_to_binbuff(*requestModel->block_blob, blockblob)) {
return createResponse(Status::CODE_400, "Wrong block blob");
}
currency::block b = AUTO_VAL_INIT(b);
if (!currency::parse_and_validate_block_from_blob(blockblob, b)) {
return createResponse(Status::CODE_400, "Wrong block blob");
}
currency::block_verification_context bvc = AUTO_VAL_INIT(bvc);
if (!m_core_info->getCore().handle_block_found(b, &bvc)) {
if (bvc.m_added_to_altchain) {
return createResponse(Status::CODE_406, "Block added as alternative");
}
return createResponse(Status::CODE_406, "Block not accepted");
}
auto responseModel = SubmitBlockResponseModel::createShared();
responseModel->status = "OK";
return createDtoResponse(Status::CODE_200, responseModel);
}
};
#include OATPP_CODEGEN_END(ApiController)
#endif /* BlockSubmitController_hpp */

View file

@ -0,0 +1,104 @@
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; but maintains OSS status,
// where regional copyright law requires ownership to dictate licence terms.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#ifndef BlockTemplateController_hpp
#define BlockTemplateController_hpp
#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "controller/ApiCoreInfo.hpp"
#include "modal/block/template_request.hpp"
#include "modal/block/template.hpp"
#include "currency_core/currency_format_utils.h"
#include OATPP_CODEGEN_BEGIN(ApiController)
class BlockTemplateController : public oatpp::web::server::api::ApiController {
private:
OATPP_COMPONENT(std::shared_ptr<ApiCoreInfo>, m_core_info);
public:
explicit BlockTemplateController(OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper))
: oatpp::web::server::api::ApiController(objectMapper) {}
public:
ENDPOINT_INFO(createBlockTemplate) {
info->summary = "Create a block template for mining";
info->addTag("Block");
info->addConsumes<Object<BlockTemplateRequestModel>>("application/json");
info->addResponse<Object<BlockTemplateModel>>(Status::CODE_200, "application/json");
info->addResponse(Status::CODE_400, "text/plain");
info->addResponse(Status::CODE_500, "text/plain");
}
ENDPOINT("POST", "/block/template", createBlockTemplate, BODY_DTO(Object<BlockTemplateRequestModel>, requestModel)) {
currency::create_block_template_params params = AUTO_VAL_INIT(params);
if (!currency::get_account_address_from_str(params.miner_address, *requestModel->miner_address)) {
return createResponse(Status::CODE_400, "Failed to parse miner_address");
}
if (requestModel->stakeholder_address && !currency::get_account_address_from_str(params.stakeholder_address, *requestModel->stakeholder_address)) {
return createResponse(Status::CODE_400, "Failed to parse stakeholder_address");
}
params.ex_nonce = requestModel->ex_nonce ? *requestModel->ex_nonce : "";
params.pos = requestModel->pos;
params.ignore_pow_ts_check = requestModel->ignore_pow_ts_check;
if (requestModel->pe) {
params.pe.amount = requestModel->pe->amount;
params.pe.g_index = requestModel->pe->g_index;
epee::string_tools::hex_to_pod(*requestModel->pe->keyimage, params.pe.keyimage);
params.pe.block_timestamp = requestModel->pe->block_timestamp;
params.pe.stake_unlock_time = requestModel->pe->stake_unlock_time;
epee::string_tools::hex_to_pod(*requestModel->pe->tx_id, params.pe.tx_id);
params.pe.tx_out_index = requestModel->pe->tx_out_index;
params.pe.wallet_index = requestModel->pe->wallet_index;
}
for (const auto& tx_hex : *requestModel->explicit_txs) {
currency::transaction tx;
currency::blobdata tx_blob;
if (!epee::string_tools::parse_hexstr_to_binbuff(*tx_hex, tx_blob) || !currency::parse_and_validate_tx_from_blob(tx_blob, tx)) {
return createResponse(Status::CODE_400, "Failed to parse explicit_txs");
}
params.explicit_txs.push_back(tx);
}
currency::create_block_template_response response = AUTO_VAL_INIT(response);
if (!m_core_info->getCore().get_block_template(params, response)) {
return createResponse(Status::CODE_500, "Internal error: failed to create block template");
}
auto model = BlockTemplateModel::createShared();
model->blocktemplate_blob = epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(response.b));
model->difficulty = response.diffic.convert_to<std::string>();
model->height = response.height;
model->block_reward_without_fee = response.block_reward_without_fee;
model->block_reward = response.block_reward;
model->txs_fee = response.txs_fee;
model->prev_hash = epee::string_tools::pod_to_hex(response.b.prev_id);
model->seed = epee::string_tools::pod_to_hex(currency::ethash_epoch_to_seed(currency::ethash_height_to_epoch(response.height)));
auto tgc_model = TxGenerationContextModel::createShared();
// This is a very complex object with many cryptographic details.
// For now, we will leave it empty as it's not essential for basic mining.
// A dedicated endpoint could be created later to expose this if needed.
model->miner_tx_tgc = tgc_model;
return createDtoResponse(Status::CODE_200, model);
}
};
#include OATPP_CODEGEN_END(ApiController)
#endif /* BlockTemplateController_hpp */

View file

@ -0,0 +1,32 @@
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; but maintains OSS status,
// where regional copyright law requires ownership to dictate licence terms.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#ifndef SubmitBlockRequestModel_hpp
#define SubmitBlockRequestModel_hpp
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include OATPP_CODEGEN_BEGIN(DTO)
class SubmitBlockRequestModel final : public oatpp::DTO
{
DTO_INIT(SubmitBlockRequestModel, DTO);
DTO_FIELD(String, block_blob);
};
#include OATPP_CODEGEN_END(DTO)
#endif /* SubmitBlockRequestModel_hpp */

View file

@ -0,0 +1,32 @@
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; but maintains OSS status,
// where regional copyright law requires ownership to dictate licence terms.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#ifndef SubmitBlockResponseModel_hpp
#define SubmitBlockResponseModel_hpp
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include OATPP_CODEGEN_BEGIN(DTO)
class SubmitBlockResponseModel final : public oatpp::DTO
{
DTO_INIT(SubmitBlockResponseModel, DTO);
DTO_FIELD(String, status);
};
#include OATPP_CODEGEN_END(DTO)
#endif /* SubmitBlockResponseModel_hpp */

View file

@ -0,0 +1,41 @@
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; but maintains OSS status,
// where regional copyright law requires ownership to dictate licence terms.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#ifndef BlockTemplateModel_hpp
#define BlockTemplateModel_hpp
#include "../meta/tx_generation_context.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include OATPP_CODEGEN_BEGIN(DTO)
class BlockTemplateModel final : public oatpp::DTO
{
DTO_INIT(BlockTemplateModel, DTO);
DTO_FIELD(String, blocktemplate_blob);
DTO_FIELD(String, difficulty);
DTO_FIELD(UInt64, height);
DTO_FIELD(Object<TxGenerationContextModel>, miner_tx_tgc);
DTO_FIELD(UInt64, block_reward_without_fee);
DTO_FIELD(UInt64, block_reward);
DTO_FIELD(UInt64, txs_fee);
DTO_FIELD(String, prev_hash);
DTO_FIELD(String, seed);
};
#include OATPP_CODEGEN_END(DTO)
#endif /* BlockTemplateModel_hpp */

View file

@ -0,0 +1,39 @@
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; but maintains OSS status,
// where regional copyright law requires ownership to dictate licence terms.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#ifndef BlockTemplateRequestModel_hpp
#define BlockTemplateRequestModel_hpp
#include "../meta/pos_entry.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include OATPP_CODEGEN_BEGIN(DTO)
class BlockTemplateRequestModel final : public oatpp::DTO
{
DTO_INIT(BlockTemplateRequestModel, DTO);
DTO_FIELD(String, miner_address);
DTO_FIELD(String, stakeholder_address);
DTO_FIELD(String, ex_nonce);
DTO_FIELD(Boolean, pos, "pos_block");
DTO_FIELD(Boolean, ignore_pow_ts_check);
DTO_FIELD(Object<PosEntryModel>, pe);
DTO_FIELD(List<String>, explicit_txs);
};
#include OATPP_CODEGEN_END(DTO)
#endif /* BlockTemplateRequestModel_hpp */

View file

@ -0,0 +1,39 @@
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; but maintains OSS status,
// where regional copyright law requires ownership to dictate licence terms.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#ifndef PosEntryModel_hpp
#define PosEntryModel_hpp
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include OATPP_CODEGEN_BEGIN(DTO)
class PosEntryModel final : public oatpp::DTO
{
DTO_INIT(PosEntryModel, DTO);
DTO_FIELD(UInt64, amount);
DTO_FIELD(UInt64, g_index);
DTO_FIELD(String, keyimage);
DTO_FIELD(UInt64, block_timestamp);
DTO_FIELD(UInt64, stake_unlock_time);
DTO_FIELD(String, tx_id);
DTO_FIELD(UInt64, tx_out_index);
DTO_FIELD(UInt64, wallet_index);
};
#include OATPP_CODEGEN_END(DTO)
#endif /* PosEntryModel_hpp */

View file

@ -0,0 +1,55 @@
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; but maintains OSS status,
// where regional copyright law requires ownership to dictate licence terms.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#ifndef TxGenerationContextModel_hpp
#define TxGenerationContextModel_hpp
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include OATPP_CODEGEN_BEGIN(DTO)
class TxGenerationContextModel final : public oatpp::DTO
{
DTO_INIT(TxGenerationContextModel, DTO);
DTO_FIELD(List<String>, asset_ids);
DTO_FIELD(List<String>, blinded_asset_ids);
DTO_FIELD(List<String>, amount_commitments);
DTO_FIELD(List<String>, asset_id_blinding_masks);
DTO_FIELD(List<String>, amounts);
DTO_FIELD(List<String>, amount_blinding_masks);
DTO_FIELD(List<String>, pseudo_outs_blinded_asset_ids);
DTO_FIELD(List<String>, pseudo_outs_plus_real_out_blinding_masks);
DTO_FIELD(List<String>, real_zc_ins_asset_ids);
DTO_FIELD(List<UInt64>, zc_input_amounts);
DTO_FIELD(String, pseudo_out_amount_commitments_sum);
DTO_FIELD(String, pseudo_out_amount_blinding_masks_sum);
DTO_FIELD(String, real_in_asset_id_blinding_mask_x_amount_sum);
DTO_FIELD(String, amount_commitments_sum);
DTO_FIELD(String, amount_blinding_masks_sum);
DTO_FIELD(String, asset_id_blinding_mask_x_amount_sum);
DTO_FIELD(String, ao_asset_id);
DTO_FIELD(String, ao_asset_id_pt);
DTO_FIELD(String, ao_amount_commitment);
DTO_FIELD(String, ao_amount_blinding_mask);
DTO_FIELD(Boolean, ao_commitment_in_outputs);
DTO_FIELD(String, tx_key_pub);
DTO_FIELD(String, tx_key_sec);
DTO_FIELD(String, tx_pub_key_p);
};
#include OATPP_CODEGEN_END(DTO)
#endif /* TxGenerationContextModel_hpp */

View file

@ -0,0 +1,32 @@
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; but maintains OSS status,
// where regional copyright law requires ownership to dictate licence terms.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#ifndef SendTransactionRequestModel_hpp
#define SendTransactionRequestModel_hpp
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include OATPP_CODEGEN_BEGIN(DTO)
class SendTransactionRequestModel final : public oatpp::DTO
{
DTO_INIT(SendTransactionRequestModel, DTO);
DTO_FIELD(String, tx_as_hex);
};
#include OATPP_CODEGEN_END(DTO)
#endif /* SendTransactionRequestModel_hpp */

View file

@ -0,0 +1,32 @@
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// You may obtain a copy of the licence at:
//
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
//
// The EUPL is a copyleft licence that is compatible with the MIT/X11
// licence used by the original projects; but maintains OSS status,
// where regional copyright law requires ownership to dictate licence terms.
//
// SPDXLicenseIdentifier: EUPL-1.2
//
#ifndef SendTransactionResponseModel_hpp
#define SendTransactionResponseModel_hpp
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include OATPP_CODEGEN_BEGIN(DTO)
class SendTransactionResponseModel final : public oatpp::DTO
{
DTO_INIT(SendTransactionResponseModel, DTO);
DTO_FIELD(String, status);
};
#include OATPP_CODEGEN_END(DTO)
#endif /* SendTransactionResponseModel_hpp */