Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ack/dev protocol handler #337

Open
wants to merge 3 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ compile_commands.json
*.ipch
*.bin
*.json
cmake-build*
cmake-build*

.cursorrules
11 changes: 11 additions & 0 deletions src/CryptoNoteConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include <cstdint>
#include <cstddef>
#include <initializer_list>

namespace cn
Expand Down Expand Up @@ -142,6 +143,16 @@ namespace cn
const char CRYPTONOTE_BLOCKCHAIN_INDICES_FILENAME[] = "blockchainindices.dat";
const char MINER_CONFIG_FILE_NAME[] = "miner_conf.json";

// Memory management constants
const uint32_t ABSOLUTE_MAX_OBJECTS = 1200; // can safely be handled memory wise, but a limiting factor to prevent DDOS attack
const uint32_t FALLBACK_MAX_OBJECTS = 800; // Default when memory check fails
const uint64_t MIN_MEMORY_MB = 150; // Minimum memory required for handling fallback max objects

// Memory management constants validation
static_assert(ABSOLUTE_MAX_OBJECTS > FALLBACK_MAX_OBJECTS,
"Maximum object count must be greater than Fallback");


} // namespace parameters

const uint64_t START_BLOCK_REWARD = (UINT64_C(5000) * parameters::POINT); // start reward (Consensus I)
Expand Down
69 changes: 61 additions & 8 deletions src/CryptoNoteProtocol/CryptoNoteProtocolHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
#include "CryptoNoteCore/VerificationContext.h"
#include "P2p/LevinProtocol.h"

#include "../CryptoNoteConfig.h"
#include <cstdint> // for UINT64_MAX
#ifdef __linux__
#include <sys/sysinfo.h>
#endif

using namespace logging;
using namespace common;

Expand All @@ -44,6 +50,7 @@ void relay_post_notify(IP2pEndpoint &p2p, typename t_parametr::request &arg, con

} // namespace


CryptoNoteProtocolHandler::CryptoNoteProtocolHandler(const Currency &currency, platform_system::Dispatcher &dispatcher, ICore &rcore, IP2pEndpoint *p_net_layout, logging::ILogger &log) :
m_currency(currency),
m_p2p(p_net_layout),
Expand All @@ -53,11 +60,14 @@ CryptoNoteProtocolHandler::CryptoNoteProtocolHandler(const Currency &currency, p
m_observedHeight(0),
m_peersCount(0),
logger(log, "protocol"),
m_dispatcher(dispatcher)
{
if (!m_p2p)
m_p2p = &m_p2p_stub;
}
m_dispatcher(dispatcher),
m_maxObjectCount(calculateMaxObjectCount())
{
logger(INFO) << "Max object count: " << m_maxObjectCount;

if (!m_p2p)
m_p2p = &m_p2p_stub;
}

size_t CryptoNoteProtocolHandler::getPeerCount() const
{
Expand Down Expand Up @@ -392,9 +402,18 @@ int CryptoNoteProtocolHandler::handle_notify_new_transactions(int command, NOTIF
int CryptoNoteProtocolHandler::handle_request_get_objects(int command, NOTIFY_REQUEST_GET_OBJECTS::request &arg, CryptoNoteConnectionContext &context)
{
logger(logging::TRACE) << context << "NOTIFY_REQUEST_GET_OBJECTS";
if(arg.blocks.size() > COMMAND_RPC_GET_OBJECTS_MAX_COUNT || arg.txs.size() > COMMAND_RPC_GET_OBJECTS_MAX_COUNT)

uint32_t maxObjects = m_maxObjectCount.load();
const size_t totalObjects = arg.blocks.size() + arg.txs.size();

logger(INFO) << "DEBUG: Request for " << totalObjects << " objects (limit: " << maxObjects << ")";


if (totalObjects > maxObjects)
{
logger(logging::ERROR) << context << "GET_OBJECTS_MAX_COUNT exceeded blocks: " << arg.blocks.size() << " txes: " << arg.txs.size();
logger(logging::ERROR) << context << "Requested objects count exceeds limit of "
<< maxObjects << ": blocks " << arg.blocks.size()
<< " + txs " << arg.txs.size() << " = " << totalObjects;
context.m_state = CryptoNoteConnectionContext::state_shutdown;
return 1;
}
Expand Down Expand Up @@ -594,14 +613,15 @@ int CryptoNoteProtocolHandler::processObjects(CryptoNoteConnectionContext& conte
}

return 0;

}


bool CryptoNoteProtocolHandler::on_idle()
{
return m_core.on_idle();
}


int CryptoNoteProtocolHandler::handle_request_chain(int command, NOTIFY_REQUEST_CHAIN::request &arg, CryptoNoteConnectionContext &context)
{
logger(logging::TRACE) << context << "NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << arg.block_ids.size();
Expand Down Expand Up @@ -1121,4 +1141,37 @@ int CryptoNoteProtocolHandler::doPushLiteBlock(NOTIFY_NEW_LITE_BLOCK::request ar
return 1;
}

uint64_t CryptoNoteProtocolHandler::getAvailableMemory() const {
#ifdef _WIN32
MEMORYSTATUSEX memInfo;
memInfo.dwLength = sizeof(MEMORYSTATUSEX);
if (GlobalMemoryStatusEx(&memInfo)) {
return memInfo.ullAvailPhys;
}
logger(ERROR) << "Failed to get Windows memory info: " << GetLastError();
return 0;
#else
struct sysinfo memInfo;
if (sysinfo(&memInfo) == 0) {
uint64_t available = memInfo.freeram;
available *= memInfo.mem_unit;
return available;
}
logger(ERROR) << "Failed to get system memory info: " << errno;
return 0;
#endif
}

uint32_t CryptoNoteProtocolHandler::calculateMaxObjectCount() const {
uint64_t availableMB = getAvailableMemory() / (1024 * 1024);

if (availableMB < cn::parameters::MIN_MEMORY_MB) {
logger(logging::WARNING) << "Memory check failed or small value, using fallback max objects";
return cn::parameters::FALLBACK_MAX_OBJECTS;
}

// If we have enough memory, use max objects which would be a key value to prevent DDOS attack
return cn::parameters::ABSOLUTE_MAX_OBJECTS;
}

}; // namespace cn
8 changes: 7 additions & 1 deletion src/CryptoNoteProtocol/CryptoNoteProtocolHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
#pragma once

#include <atomic>
#include <cstdint>

#include <Common/ObserverManager.h>

#include "../CryptoNoteConfig.h"
#include "CryptoNoteCore/ICore.h"

#include "CryptoNoteProtocol/CryptoNoteProtocolDefinitions.h"
Expand Down Expand Up @@ -118,5 +119,10 @@ namespace cn

std::atomic<size_t> m_peersCount;
tools::ObserverManager<ICryptoNoteProtocolObserver> m_observerManager;

std::atomic<uint32_t> m_maxObjectCount;
uint64_t getAvailableMemory() const;
uint32_t calculateMaxObjectCount() const;

};
}
Loading