diff --git a/src/sv2/template_provider.cpp b/src/sv2/template_provider.cpp index 6572782d2ef4d..b6145c3041593 100644 --- a/src/sv2/template_provider.cpp +++ b/src/sv2/template_provider.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -13,10 +14,46 @@ Sv2TemplateProvider::Sv2TemplateProvider(interfaces::Mining& mining) : m_mining{ { // TODO: persist static key CKey static_key; - static_key.MakeNewKey(true); - - auto authority_key{GenerateRandomKey()}; - + try { + AutoFile{fsbridge::fopen(GetStaticKeyFile(), "rb")} >> static_key; + LogPrintLevel(BCLog::SV2, BCLog::Level::Debug, "Reading cached static key from %s\n", fs::PathToString(GetStaticKeyFile())); + } catch (const std::ios_base::failure&) { + // File is not expected to exist the first time. + // In the unlikely event that loading an existing key fails, create a new one. + } + if (!static_key.IsValid()) { + static_key = GenerateRandomKey(); + try { + AutoFile{fsbridge::fopen(GetStaticKeyFile(), "wb")} << static_key; + } catch (const std::ios_base::failure&) { + LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Error writing static key to %s\n", fs::PathToString(GetStaticKeyFile())); + // Continue, because this is not a critical failure. + } + LogPrintLevel(BCLog::SV2, BCLog::Level::Debug, "Generated static key, saved to %s\n", fs::PathToString(GetStaticKeyFile())); + } + LogPrintLevel(BCLog::SV2, BCLog::Level::Info, "Static key: %s\n", HexStr(static_key.GetPubKey())); + + // Generate self signed certificate using (cached) authority key + // TODO: skip loading authoritity key if -sv2cert is used + + // Load authority key if cached + CKey authority_key; + try { + AutoFile{fsbridge::fopen(GetAuthorityKeyFile(), "rb")} >> authority_key; + } catch (const std::ios_base::failure&) { + // File is not expected to exist the first time. + // In the unlikely event that loading an existing key fails, create a new one. + } + if (!authority_key.IsValid()) { + authority_key = GenerateRandomKey(); + try { + AutoFile{fsbridge::fopen(GetAuthorityKeyFile(), "wb")} << authority_key; + } catch (const std::ios_base::failure&) { + LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Error writing authority key to %s\n", fs::PathToString(GetAuthorityKeyFile())); + // Continue, because this is not a critical failure. + } + LogPrintLevel(BCLog::SV2, BCLog::Level::Debug, "Generated authority key, saved to %s\n", fs::PathToString(GetAuthorityKeyFile())); + } // SRI uses base58 encoded x-only pubkeys in its configuration files std::array version_pubkey_bytes; version_pubkey_bytes[0] = 1; @@ -34,11 +71,19 @@ Sv2TemplateProvider::Sv2TemplateProvider(interfaces::Mining& mining) : m_mining{ uint32_t valid_to = std::numeric_limits::max(); // 2106 Sv2SignatureNoiseMessage certificate = Sv2SignatureNoiseMessage(version, valid_from, valid_to, XOnlyPubKey(static_key.GetPubKey()), authority_key); - // TODO: persist certificate - m_connman = std::make_unique(TP_SUBPROTOCOL, static_key, m_authority_pubkey, certificate); } +fs::path Sv2TemplateProvider::GetStaticKeyFile() +{ + return gArgs.GetDataDirNet() / "sv2_static_key"; +} + +fs::path Sv2TemplateProvider::GetAuthorityKeyFile() +{ + return gArgs.GetDataDirNet() / "sv2_authority_key"; +} + bool Sv2TemplateProvider::Start(const Sv2TemplateProviderOptions& options) { m_options = options; diff --git a/src/sv2/template_provider.h b/src/sv2/template_provider.h index 34bc5cea4d5a1..48ec4677b49fa 100644 --- a/src/sv2/template_provider.h +++ b/src/sv2/template_provider.h @@ -57,6 +57,12 @@ class Sv2TemplateProvider : public Sv2EventsInterface std::unique_ptr m_connman; + /** Get name of file to store static key */ + fs::path GetStaticKeyFile(); + + /** Get name of file to store authority key */ + fs::path GetAuthorityKeyFile(); + /** * Configuration */