66#include < common/args.h>
77#include < logging.h>
88#include < sv2/noise.h>
9+ #include < util/readwritefile.h>
910#include < util/strencodings.h>
1011#include < util/thread.h>
1112
1213Sv2TemplateProvider::Sv2TemplateProvider (interfaces::Mining& mining) : m_mining{mining}
1314{
1415 // TODO: persist static key
1516 CKey static_key;
16- static_key.MakeNewKey (true );
17-
18- auto authority_key{GenerateRandomKey ()};
19-
17+ try {
18+ AutoFile{fsbridge::fopen (GetStaticKeyFile (), " rb" )} >> static_key;
19+ LogPrintLevel (BCLog::SV2, BCLog::Level::Debug, " Reading cached static key from %s\n " , fs::PathToString (GetStaticKeyFile ()));
20+ } catch (const std::ios_base::failure&) {
21+ // File is not expected to exist the first time.
22+ // In the unlikely event that loading an existing key fails, create a new one.
23+ }
24+ if (!static_key.IsValid ()) {
25+ static_key = GenerateRandomKey ();
26+ try {
27+ AutoFile{fsbridge::fopen (GetStaticKeyFile (), " wb" )} << static_key;
28+ } catch (const std::ios_base::failure&) {
29+ LogPrintLevel (BCLog::SV2, BCLog::Level::Error, " Error writing static key to %s\n " , fs::PathToString (GetStaticKeyFile ()));
30+ // Continue, because this is not a critical failure.
31+ }
32+ LogPrintLevel (BCLog::SV2, BCLog::Level::Debug, " Generated static key, saved to %s\n " , fs::PathToString (GetStaticKeyFile ()));
33+ }
34+ LogPrintLevel (BCLog::SV2, BCLog::Level::Info, " Static key: %s\n " , HexStr (static_key.GetPubKey ()));
35+
36+ // Generate self signed certificate using (cached) authority key
37+ // TODO: skip loading authoritity key if -sv2cert is used
38+
39+ // Load authority key if cached
40+ CKey authority_key;
41+ try {
42+ AutoFile{fsbridge::fopen (GetAuthorityKeyFile (), " rb" )} >> authority_key;
43+ } catch (const std::ios_base::failure&) {
44+ // File is not expected to exist the first time.
45+ // In the unlikely event that loading an existing key fails, create a new one.
46+ }
47+ if (!authority_key.IsValid ()) {
48+ authority_key = GenerateRandomKey ();
49+ try {
50+ AutoFile{fsbridge::fopen (GetAuthorityKeyFile (), " wb" )} << authority_key;
51+ } catch (const std::ios_base::failure&) {
52+ LogPrintLevel (BCLog::SV2, BCLog::Level::Error, " Error writing authority key to %s\n " , fs::PathToString (GetAuthorityKeyFile ()));
53+ // Continue, because this is not a critical failure.
54+ }
55+ LogPrintLevel (BCLog::SV2, BCLog::Level::Debug, " Generated authority key, saved to %s\n " , fs::PathToString (GetAuthorityKeyFile ()));
56+ }
2057 // SRI uses base58 encoded x-only pubkeys in its configuration files
2158 std::array<unsigned char , 34 > version_pubkey_bytes;
2259 version_pubkey_bytes[0 ] = 1 ;
@@ -34,11 +71,19 @@ Sv2TemplateProvider::Sv2TemplateProvider(interfaces::Mining& mining) : m_mining{
3471 uint32_t valid_to = std::numeric_limits<unsigned int >::max (); // 2106
3572 Sv2SignatureNoiseMessage certificate = Sv2SignatureNoiseMessage (version, valid_from, valid_to, XOnlyPubKey (static_key.GetPubKey ()), authority_key);
3673
37- // TODO: persist certificate
38-
3974 m_connman = std::make_unique<Sv2Connman>(TP_SUBPROTOCOL, static_key, m_authority_pubkey, certificate);
4075}
4176
77+ fs::path Sv2TemplateProvider::GetStaticKeyFile ()
78+ {
79+ return gArgs .GetDataDirNet () / " sv2_static_key" ;
80+ }
81+
82+ fs::path Sv2TemplateProvider::GetAuthorityKeyFile ()
83+ {
84+ return gArgs .GetDataDirNet () / " sv2_authority_key" ;
85+ }
86+
4287bool Sv2TemplateProvider::Start (const Sv2TemplateProviderOptions& options)
4388{
4489 m_options = options;
0 commit comments