fix: emit events via Logos Client (#6)

* fix: emit events via Logos Client

* chore(cleanup): Use class static instead of global (#7)

* Use class static instead of global

* Fix comments

---------

Co-authored-by: Daniel Sanchez <sanchez.quiros.daniel@gmail.com>
This commit is contained in:
Khushboo-dev-cpp 2026-02-12 15:25:56 +05:30 committed by GitHub
parent c1bc793ffa
commit 009ff9af36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 1277 additions and 230 deletions

View File

@ -147,7 +147,7 @@ set_target_properties(logos_core PROPERTIES
)
add_library(logos_cpp_sdk INTERFACE)
target_include_directories(logos_cpp_sdk INTERFACE "${SDK_INC}")
target_include_directories(logos_cpp_sdk INTERFACE "${SDK_INC}" "${SDK_INC}/cpp")
# ---- Plugin ----
set(PLUGIN_TARGET logos-blockchain-module)

1223
config/node_config.yaml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,203 +0,0 @@
tracing:
logger: !Stdout
tracing: None
filter: None
metrics: None
console: None
level: DEBUG
network:
backend:
swarm:
host: 0.0.0.0
port: 3010
node_key: ea1e1dcc31612bd20987f017f0ca435cd2a59a4bd9fd6e14883b4803ae3b803d
initial_peers:
# - /dns4/devnet.blockchain.logos.co/udp/3000/quic-v1
# - /dns4/devnet.blockchain.logos.co/udp/3001/quic-v1
# - /dns4/devnet.blockchain.logos.co/udp/3002/quic-v1
# - /dns4/devnet.blockchain.logos.co/udp/3003/quic-v1
- /ip4/127.0.0.1/udp/3000/quic-v1
- /ip4/127.0.0.1/udp/3001/quic-v1
- /ip4/127.0.0.1/udp/3002/quic-v1
- /ip4/127.0.0.1/udp/3003/quic-v1
blend:
non_ephemeral_signing_key_id: 32e4b52b78e0e8273f31e2ae0826d09b0348d4c66824af4f51ec4ef338082211
recovery_path_prefix: ./resources/recovery/blend
core:
backend:
listening_address: /ip4/127.0.0.1/udp/3001/quic-v1
core_peering_degree:
start: 4
end: 8
edge_node_connection_timeout:
secs: 1
nanos: 0
max_edge_node_incoming_connections: 300
max_dial_attempts_per_peer: 3
zk:
secret_key_kms_id: 32e4b52b78e0e8273f31e2ae0826d09b0348d4c66824af4f51ec4ef338082211
edge:
backend:
max_dial_attempts_per_peer_per_message: 1
replication_factor: 1
deployment: mainnet
da_network:
backend:
node_key: ea1e1dcc31612bd20987f017f0ca435cd2a59a4bd9fd6e14883b4803ae3b803d
listening_address: /ip4/127.0.0.1/udp/8716/quic-v1
policy_settings:
min_dispersal_peers: 1
min_replication_peers: 1
max_dispersal_failures: 3
max_sampling_failures: 3
max_replication_failures: 3
malicious_threshold: 5
monitor_settings:
failure_time_window: "10.0"
time_decay_factor: "0.8"
balancer_interval:
secs: 5
nanos: 0
redial_cooldown:
secs: 5
nanos: 0
replication_settings:
seen_message_cache_size: 1000
seen_message_ttl: "3600.0"
subnets_settings:
num_of_subnets: 20
shares_retry_limit: 5
commitments_retry_limit: 5
membership:
replication_factor: 2
subnetwork_size: 2
api_adapter_settings:
api_port: 8722
is_secure: false
subnet_refresh_interval:
secs: 30
nanos: 0
subnet_threshold: 2048
min_session_members: 2
da_verifier:
share_verifier_settings:
global_params_path: ./resources/tests/kzgrs/kzgrs_test_params
domain_size: 2
tx_verifier_settings: null
network_adapter_settings: null
storage_adapter_settings:
blob_storage_directory: ./resources
mempool_trigger_settings:
publish_threshold: 0.8
share_duration: [ 5, 0 ]
prune_duration: [ 30, 0 ]
prune_interval: [ 5, 0 ]
da_sampling:
share_verifier_settings:
global_params_path: ./resources/tests/kzgrs/kzgrs_test_params
domain_size: 2
sampling_settings:
num_samples: 1
num_subnets: 2
old_blobs_check_interval:
secs: 5
nanos: 0
blobs_validity_duration:
secs: 18446744073709551615
nanos: 0
commitments_wait_duration:
secs: 2
nanos: 0
sdp_blob_trigger_sampling_delay:
secs: 5
nanos: 0
http:
backend_settings:
address: 127.0.0.1:8722
cors_origins: [ ]
time:
chain_start_time: [ 2025, 41, 9, 38, 29, 993653000, 0, 0, 0 ]
backend:
update_interval: [ 16, 0 ]
ntp_server: pool.ntp.org
ntp_client_settings:
timeout: [ 5, 0 ]
listening_interface: 0.0.0.0
cryptarchia:
service:
starting_state: !Genesis
genesis_tx:
mantle_tx:
ops:
- opcode: 0
payload:
channel_id: "0000000000000000000000000000000000000000000000000000000000000000"
inscription: [ 103, 101, 110, 101, 115, 105, 115 ] # "genesis" in bytes
parent: "0000000000000000000000000000000000000000000000000000000000000000"
signer: "0000000000000000000000000000000000000000000000000000000000000000"
ledger_tx:
inputs: []
outputs:
- value: 1
pk: d204000000000000000000000000000000000000000000000000000000000000
execution_gas_price: 0
storage_gas_price: 0
ops_proofs: [NoProof]
ledger_tx_proof:
pi_a: [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
pi_b: [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
pi_c: [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
recovery_file: ./resources/recovery/cryptarchia.json
bootstrap:
prolonged_bootstrap_period: [ 86400, 0 ]
force_bootstrap: false
offline_grace_period:
grace_period: [ 1200, 0 ]
state_recording_interval: [ 60, 0 ]
network:
bootstrap:
ibd:
peers:
# - 12D3KooWEiByuYHNv8CpVLFCvKmnRqeExUrFavQfPy1Ch6ZBD4wn
# - 12D3KooWEAcvukmjQovaQiYHoRMiEC1rkHVqNtSdmnqNg5PX4ex1
# - 12D3KooWPWhnJBXR9VKNZBw5sbYtJxWANH9KUwP4JnQDYYvpkxsC
# - 12D3KooWM9oDwdgvN5RF7Xut97vJVMXSNRytoitQAeNSxjGWvTTc
- 12D3KooWRuCV6UDuQuYkmG9Y7x9uU6WV8whJTxQR3zwpEZnXAoFP
- 12D3KooWBztub2cRcTm4G1yir2Wv6ErFcJjiZi2ZBoJwQk9N77aJ
- 12D3KooWRoYTdyWdaxRv4Sr6JUcvwM1NKYqDrVmPRKRau9c5YqS1
- 12D3KooWELj9EaHym8Awaj2V9GgEb2KCNud8Y3Xz5SiiEt9vVw2b
sync:
orphan:
max_orphan_cache_size: 5
leader:
pk: "0000000000000000000000000000000000000000000000000000000000000000"
sk: 3cf3335017304dcfce45124a0633829f00000000000000000000000000000000
storage:
db_path: ./resources/tests/db
read_only: false
column_family: blocks
mempool:
recovery_path: ./resources/recovery/mempool.json
sdp:
declaration: null
wallet_config:
max_tx_fee: 18446744073709551615 # u64::MAX
# SDP funding public key - matches the genesis note pk used for SDP transaction fees
funding_pk: "89b7314f5184bae9eb7fa511098eb321b97b8fbbdec611dda591e0c01e18331d"
wallet:
known_keys:
- "0000000000000000000000000000000000000000000000000000000000000000"
key_management:
keys:
leader_key: !Zk 3cf3335017304dcfce45124a0633829f00000000000000000000000000000000

6
flake.lock generated
View File

@ -23,11 +23,11 @@
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1770805205,
"narHash": "sha256-iFbTm1SZba058R+l7ShuA9jH8zt9tVRxO4vBHc95KaI=",
"lastModified": 1770819486,
"narHash": "sha256-a9/K6yHODsg9vw9IUlhLAd10aDwsd8YPXjPA6GbPvl8=",
"owner": "logos-blockchain",
"repo": "logos-blockchain",
"rev": "90d266f02142d2211911529d0afadf0138308381",
"rev": "1a49d7cb0191c8b19ff9622cb7be041582f794b2",
"type": "github"
},
"original": {

View File

@ -1,8 +1,31 @@
#include "logos_blockchain_module.h"
#include "logos_api_client.h"
#include <QVariant>
LogosBlockchainModule::LogosBlockchainModule() = default;
// Define static member
LogosBlockchainModule* LogosBlockchainModule::s_instance = nullptr;
void LogosBlockchainModule::onNewBlockCallback(const char* block) {
if (s_instance) {
qInfo() << "Received new block: " << block;
QVariantList data;
data.append(QString::fromUtf8(block));
s_instance->emitEvent("newBlock", data);
free_cstring(const_cast<char*>(block)); // Free Rust-allocated memory
}
}
LogosBlockchainModule::LogosBlockchainModule() {
client = logosAPI->getClient("liblogos-blockchain-module");
node = nullptr;
if (!client) {
qWarning() << "LogosBlockchainModule: Failed to get liblogos-blockchain-module client for liblogos-blockchain-module";
return;
}
}
LogosBlockchainModule::~LogosBlockchainModule() {
s_instance = nullptr;
if (node) {
stop();
}
@ -64,11 +87,8 @@ int LogosBlockchainModule::start(const QString& config_path, const QString& depl
return 1;
}
subscribe_to_new_blocks(node, [](const char* block) {
std::cout << "Received new block: " << block << std::endl;
auto* event = new BlockEvent(block);
QCoreApplication::postEvent(qApp, event);
});
s_instance = this;
subscribe_to_new_blocks(node, onNewBlockCallback);
return 0;
}
@ -79,6 +99,8 @@ int LogosBlockchainModule::stop() {
return 1;
}
s_instance = nullptr; // Clear before stopping to prevent callbacks during shutdown
const OperationStatus status = stop_node(node);
if (is_ok(&status)) {
qInfo() << "The node was stopped successfully.";
@ -128,3 +150,15 @@ int LogosBlockchainModule::wallet_transfer_funds(
std::ranges::copy(value, *output_hash);
return 0;
}
void LogosBlockchainModule::emitEvent(const QString& eventName, const QVariantList& data) {
if (!logosAPI) {
qWarning() << "LogosBlockchainModule: LogosAPI not available, cannot emit" << eventName;
return;
}
if (!client) {
qWarning() << "LogosBlockchainModule: Failed to get liblogos-blockchain-module client for event" << eventName;
return;
}
client->onEventResponse(this, eventName, data);
}

View File

@ -1,25 +1,8 @@
#pragma once
#include <QtCore/QDebug>
#include <QtCore/QEvent>
#include <QtCore/QCoreApplication>
#include <iostream>
#include <memory>
#include "i_logos_blockchain_module.h"
class BlockEvent : public QEvent {
public:
static const QEvent::Type BlockEventType = static_cast<QEvent::Type>(QEvent::User + 111);
BlockEvent(const char* blockData) : QEvent(BlockEventType), block(blockData, &free_block) {}
~BlockEvent() = default;
std::shared_ptr<const char> block;
private:
static void free_block(const char* ptr) {
// SAFETY: Rust side expects a *mut char, so we can do the cast here.
if (ptr) free_cstring(const_cast<char*>(ptr));
}
};
class LogosBlockchainModule final : public QObject, public PluginInterface, public ILogosBlockchainModule {
Q_OBJECT
Q_PLUGIN_METADATA(IID ILogosBlockchainModule_iid FILE LOGOS_BLOCKCHAIN_MODULE_METADATA_FILE)
@ -45,4 +28,14 @@ signals:
private:
LogosBlockchainNode* node = nullptr;
LogosAPIClient* client = nullptr;
// Static instance for C callback (C API doesn't support user data)
static LogosBlockchainModule* s_instance;
// C-compatible callback function
static void onNewBlockCallback(const char* block);
// Helper method for emitting events
void emitEvent(const QString& eventName, const QVariantList& data);
};