kernel: Add kernel library context object

The context introduced here holds the objects that will be required for
running validation tasks, such as the chosen chain parameters, callbacks
for validation events, and interrupt handling. These will be used by the
chainstate manager introduced in subsequent commits.

This commit also introduces conventions for defining option objects. A
common pattern throughout the C header will be:
```
options = object_option_create();
object = object_create(options);
```
This allows for more consistent usage of a "builder pattern" for
objects where options can be configured independently from
instantiation.
This commit is contained in:
TheCharlatan
2024-06-03 14:35:47 +02:00
parent 28d679bad9
commit 337ea860df
4 changed files with 170 additions and 0 deletions

View File

@@ -7,8 +7,11 @@
#include <kernel/bitcoinkernel.h>
#include <consensus/amount.h>
#include <kernel/chainparams.h>
#include <kernel/checks.h>
#include <kernel/context.h>
#include <kernel/cs_main.h>
#include <kernel/notifications_interface.h>
#include <logging.h>
#include <primitives/transaction.h>
#include <script/interpreter.h>
@@ -16,6 +19,8 @@
#include <serialize.h>
#include <streams.h>
#include <tinyformat.h>
#include <util/result.h>
#include <util/signalinterrupt.h>
#include <util/translation.h>
#include <cassert>
@@ -24,6 +29,7 @@
#include <exception>
#include <functional>
#include <list>
#include <memory>
#include <span>
#include <string>
#include <utility>
@@ -212,12 +218,40 @@ struct LoggingConnection {
}
};
struct ContextOptions {
};
class Context
{
public:
std::unique_ptr<kernel::Context> m_context;
std::unique_ptr<kernel::Notifications> m_notifications;
std::unique_ptr<util::SignalInterrupt> m_interrupt;
std::unique_ptr<const CChainParams> m_chainparams;
Context(const ContextOptions* options, bool& sane)
: m_context{std::make_unique<kernel::Context>()},
m_notifications{std::make_unique<kernel::Notifications>()},
m_interrupt{std::make_unique<util::SignalInterrupt>()},
m_chainparams{CChainParams::Main()}
{
if (!kernel::SanityChecks(*m_context)) {
sane = false;
}
}
};
} // namespace
struct btck_Transaction : Handle<btck_Transaction, std::shared_ptr<const CTransaction>> {};
struct btck_TransactionOutput : Handle<btck_TransactionOutput, CTxOut> {};
struct btck_ScriptPubkey : Handle<btck_ScriptPubkey, CScript> {};
struct btck_LoggingConnection : Handle<btck_LoggingConnection, LoggingConnection> {};
struct btck_ContextOptions : Handle<btck_ContextOptions, ContextOptions> {};
struct btck_Context : Handle<btck_Context, std::shared_ptr<const Context>> {};
btck_Transaction* btck_transaction_create(const void* raw_transaction, size_t raw_transaction_len)
{
@@ -413,3 +447,35 @@ void btck_logging_connection_destroy(btck_LoggingConnection* connection)
{
delete connection;
}
btck_ContextOptions* btck_context_options_create()
{
return btck_ContextOptions::create();
}
void btck_context_options_destroy(btck_ContextOptions* options)
{
delete options;
}
btck_Context* btck_context_create(const btck_ContextOptions* options)
{
bool sane{true};
const ContextOptions* opts = options ? &btck_ContextOptions::get(options) : nullptr;
auto context{std::make_shared<const Context>(opts, sane)};
if (!sane) {
LogError("Kernel context sanity check failed.");
return nullptr;
}
return btck_Context::create(context);
}
btck_Context* btck_context_copy(const btck_Context* context)
{
return btck_Context::copy(context);
}
void btck_context_destroy(btck_Context* context)
{
delete context;
}