diff --git a/Cargo.lock b/Cargo.lock --- a/Cargo.lock +++ b/Cargo.lock @@ -211,6 +211,7 @@ name = "chronik-lib" version = "0.1.0" dependencies = [ + "abc-rust-error", "abc-rust-lint", "chronik-bridge", "chronik-util", diff --git a/chronik/CMakeLists.txt b/chronik/CMakeLists.txt --- a/chronik/CMakeLists.txt +++ b/chronik/CMakeLists.txt @@ -115,6 +115,7 @@ # chronik::Stop to run the indexer from C++. add_library(chronik chronik-cpp/chronik.cpp + chronik-cpp/chronik_validationinterface.cpp ${CHRONIK_LIB_GENERATED_CPP_FILES} ) target_link_libraries(chronik diff --git a/chronik/chronik-cpp/chronik.cpp b/chronik/chronik-cpp/chronik.cpp --- a/chronik/chronik-cpp/chronik.cpp +++ b/chronik/chronik-cpp/chronik.cpp @@ -7,17 +7,21 @@ #include #include +#include #include namespace chronik { void Start([[maybe_unused]] const Config &config, [[maybe_unused]] const NodeContext &node) { - chronik_bridge::setup_bridge(); + rust::Box chronik_box = + chronik_bridge::setup_bridge(); + StartChronikValidationInterface(std::move(chronik_box)); } void Stop() { LogPrintf("Stopping Chronik...\n"); + StopChronikValidationInterface(); } } // namespace chronik diff --git a/chronik/chronik-cpp/chronik_validationinterface.h b/chronik/chronik-cpp/chronik_validationinterface.h new file mode 100644 --- /dev/null +++ b/chronik/chronik-cpp/chronik_validationinterface.h @@ -0,0 +1,22 @@ +// Copyright (c) 2022 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#ifndef BITCOIN_CHRONIK_CPP_CHRONIK_VALIDATIONINTERFACE_H +#define BITCOIN_CHRONIK_CPP_CHRONIK_VALIDATIONINTERFACE_H + +namespace chronik_bridge { +struct Chronik; +} // namespace chronik_bridge + +namespace chronik { + +void StartChronikValidationInterface( + rust::Box chronik_box); + +void StopChronikValidationInterface(); +} // namespace chronik + +#endif // BITCOIN_CHRONIK_CPP_CHRONIK_VALIDATIONINTERFACE_H diff --git a/chronik/chronik-cpp/chronik_validationinterface.cpp b/chronik/chronik-cpp/chronik_validationinterface.cpp new file mode 100644 --- /dev/null +++ b/chronik/chronik-cpp/chronik_validationinterface.cpp @@ -0,0 +1,59 @@ +// Copyright (c) 2022 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +namespace chronik { + +class ChronikValidationInterface final : public CValidationInterface { +public: + ChronikValidationInterface(rust::Box chronik_box) + : m_chronik(std::move(chronik_box)) {} + + void Register() { RegisterValidationInterface(this); } + + void Unregister() { UnregisterValidationInterface(this); } + +private: + rust::Box m_chronik; + + void TransactionAddedToMempool(const CTransactionRef &ptx, + uint64_t mempool_sequence) override { + m_chronik->handle_tx_added_to_mempool(); + } + + void TransactionRemovedFromMempool(const CTransactionRef &ptx, + MemPoolRemovalReason reason, + uint64_t mempool_sequence) override { + m_chronik->handle_tx_removed_from_mempool(); + } + + void BlockConnected(const std::shared_ptr &block, + const CBlockIndex *pindex) override { + m_chronik->handle_block_connected(); + } + + void BlockDisconnected(const std::shared_ptr &block, + const CBlockIndex *pindex) override { + m_chronik->handle_block_disconnected(); + } +}; + +std::unique_ptr g_chronik_validation_interface; + +void StartChronikValidationInterface( + rust::Box chronik_box) { + g_chronik_validation_interface = + std::make_unique(std::move(chronik_box)); + g_chronik_validation_interface->Register(); +} + +void StopChronikValidationInterface() { + g_chronik_validation_interface->Unregister(); + // Reset so the Box is dropped and all handles are released. + g_chronik_validation_interface.reset(); +} + +} // namespace chronik diff --git a/chronik/chronik-lib/Cargo.toml b/chronik/chronik-lib/Cargo.toml --- a/chronik/chronik-lib/Cargo.toml +++ b/chronik/chronik-lib/Cargo.toml @@ -13,6 +13,7 @@ [dependencies] abc-rust-lint = { path = "../abc-rust-lint" } +abc-rust-error = { path = "../abc-rust-error" } chronik-bridge = { path = "../chronik-bridge" } chronik-util = { path = "../chronik-util" } diff --git a/chronik/chronik-lib/src/bridge.rs b/chronik/chronik-lib/src/bridge.rs --- a/chronik/chronik-lib/src/bridge.rs +++ b/chronik/chronik-lib/src/bridge.rs @@ -4,13 +4,39 @@ //! Rust side of the bridge; these structs and functions are exposed to C++. +use abc_rust_error::Result; use chronik_util::{log, log_chronik}; -/// Setup the Chronik bridge. Currently only logs to bitcoind. -pub fn setup_bridge() { +/// Setup the Chronik bridge. Returns a ChronikIndexer object. +pub fn setup_bridge() -> Result> { log!("Starting Chronik...\n"); - log_chronik!( - "Note: Chronik is not implemented yet. These logs are just for \ - testing.\n" - ); + Ok(Box::new(Chronik)) +} + +/// Contains all db, runtime, tpc, etc. handles needed by Chronik. +/// This makes it so when this struct is dropped, all handles are relased +/// cleanly. +#[derive(Debug)] +pub struct Chronik; + +impl Chronik { + /// Tx added to the bitcoind mempool + pub fn handle_tx_added_to_mempool(&self) { + log_chronik!("Chronik: transaction added to mempool\n"); + } + + /// Tx removed from the bitcoind mempool + pub fn handle_tx_removed_from_mempool(&self) { + log_chronik!("Chronik: transaction removed from mempool\n"); + } + + /// Block connected to the longest chain + pub fn handle_block_connected(&self) { + log_chronik!("Chronik: block connected\n"); + } + + /// Block disconnected from the longest chain + pub fn handle_block_disconnected(&self) { + log_chronik!("Chronik: block disconnected\n"); + } } diff --git a/chronik/chronik-lib/src/ffi.rs b/chronik/chronik-lib/src/ffi.rs --- a/chronik/chronik-lib/src/ffi.rs +++ b/chronik/chronik-lib/src/ffi.rs @@ -5,12 +5,18 @@ //! Module containing the cxx definitions for the bridge from Rust to C++. pub use self::ffi_inner::*; -use crate::bridge::setup_bridge; +use crate::bridge::{setup_bridge, Chronik}; #[allow(unsafe_code)] #[cxx::bridge(namespace = "chronik_bridge")] mod ffi_inner { extern "Rust" { - fn setup_bridge(); + type Chronik; + fn setup_bridge() -> Result>; + + fn handle_tx_added_to_mempool(&self); + fn handle_tx_removed_from_mempool(&self); + fn handle_block_connected(&self); + fn handle_block_disconnected(&self); } }