Skip to content

Commit 2fb6c5e

Browse files
committed
What I've done so far
1 parent e89f6e6 commit 2fb6c5e

13 files changed

Lines changed: 244 additions & 98 deletions

src/account/GeniusAccount.cpp

Lines changed: 81 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <WalletCore/Hash.h>
1313
#include <WalletCore/PrivateKey.h>
1414
#include <ipfs_pubsub/gossip_pubsub.hpp>
15+
#include <string>
1516

1617
#include "base/hexutil.hpp"
1718
#include "local_secure_storage/impl/json/JSONSecureStorage.hpp"
@@ -195,6 +196,21 @@ namespace sgns
195196
return nullptr;
196197
}
197198

199+
std::shared_ptr<GeniusAccount> GeniusAccount::NewFromPublicKey( TokenID token_id,
200+
std::string_view public_key,
201+
bool full_node )
202+
{
203+
if ( auto response = LoadGeniusAccount( public_key ); response.has_value() )
204+
{
205+
genius_account_logger()->debug( "Loaded existing Genius address" );
206+
return CreateInstanceFromResponse( token_id, std::move( response.value() ), full_node );
207+
}
208+
209+
genius_account_logger()->error( "Could not load Genius address from storage" );
210+
211+
return nullptr;
212+
}
213+
198214
std::shared_ptr<GeniusAccount> GeniusAccount::New( TokenID token_id,
199215
const boost::filesystem::path &base_path,
200216
bool full_node )
@@ -213,6 +229,31 @@ namespace sgns
213229
return GeniusAccount::NewFromMnemonic( token_id, wallet.getMnemonic(), base_path, full_node );
214230
}
215231

232+
std::vector<std::string> GeniusAccount::GetAvailableAccounts( const boost::filesystem::path &base_path )
233+
{
234+
auto file_path = SetupStoragePath( base_path );
235+
genius_account_logger()->info( "Secure storage ID path: {}", file_path.string() );
236+
std::ifstream file( file_path.string() );
237+
238+
if ( !file.is_open() )
239+
{
240+
genius_account_logger()->debug( "Could not find ID file" );
241+
return {};
242+
}
243+
244+
std::vector<std::string> addresses;
245+
std::string line;
246+
247+
while ( std::getline( file, line ) )
248+
{
249+
addresses.push_back( std::move( line ) );
250+
}
251+
252+
genius_account_logger()->debug( "Found {} addresses in files", addresses.size() );
253+
254+
return addresses;
255+
}
256+
216257
outcome::result<GeniusAccount::StorageWithAddress> GeniusAccount::LoadGeniusAccount(
217258
const boost::filesystem::path &base_path )
218259
{
@@ -272,6 +313,37 @@ namespace sgns
272313
std::make_pair( KeyGenerator::ElGamal( std::move( key_seed ) ), std::move( eth_key ) ) );
273314
}
274315

316+
outcome::result<GeniusAccount::StorageWithAddress> GeniusAccount::LoadGeniusAccount( std::string_view public_key )
317+
{
318+
OUTCOME_TRY( std::vector<uint8_t> vec, base::unhex( public_key ) );
319+
320+
std::shared_ptr<ISecureStorage> storage = std::make_shared<SecureStorageImpl>(
321+
std::string( SECURE_STORAGE_PREFIX ) + libp2p::multi::detail::encodeBase58( vec ) );
322+
323+
auto load_res = storage->Load( "sgns_key" );
324+
if ( !load_res )
325+
{
326+
genius_account_logger()->warn( "Could not load sgns_key from secure storage" );
327+
return std::errc::no_such_file_or_directory;
328+
}
329+
330+
auto key_seed = nil::crypto3::multiprecision::uint256_t( load_res.value() );
331+
genius_account_logger()->info( "Successfully loaded key_seed from storage" );
332+
333+
// Validate loaded key_seed matches stored public key
334+
if ( ethereum::EthereumKeyGenerator( key_seed ).GetEntirePubValue() != public_key )
335+
{
336+
genius_account_logger()->error( "Validation failed: key_seed does not match stored public key" );
337+
return std::errc::bad_message;
338+
}
339+
genius_account_logger()->info( "Validation successful: key_seed matches stored public key" );
340+
341+
ethereum::EthereumKeyGenerator eth_key( key_seed );
342+
343+
return std::make_pair( std::move( storage ),
344+
std::make_pair( KeyGenerator::ElGamal( std::move( key_seed ) ), std::move( eth_key ) ) );
345+
}
346+
275347
outcome::result<GeniusAccount::StorageWithAddress> GeniusAccount::GenerateGeniusAddress(
276348
const char *eth_private_key,
277349
const boost::filesystem::path &base_path )
@@ -403,13 +475,16 @@ namespace sgns
403475
{
404476
if ( auto self = weakptr.lock() )
405477
{
406-
std::lock_guard lock( self->get_cids_mutex_ );
407-
if ( self->get_utxos_method_ )
478+
std::vector<std::string> results;
479+
auto utxos = self->GetUTXOManager().GetUTXOs( address );
480+
results.reserve( utxos.size() );
481+
482+
for ( const auto &utxo : utxos )
408483
{
409-
return self->get_utxos_method_( address );
484+
results.push_back( utxo.GetTxID().toReadableString() );
410485
}
411486

412-
return outcome::failure( AccountMessenger::Error::UTXO_REQUEST_ERROR );
487+
return results;
413488
}
414489

415490
return outcome::failure( std::errc::owner_dead );
@@ -541,9 +616,9 @@ namespace sgns
541616
TokenID token_id,
542617
std::shared_ptr<ISecureStorage> storage,
543618
bool full_node ) :
544-
eth_keypair_( std::move( eth_keypair ) ),
545619
token( token_id ),
546620
is_full_node_( full_node ),
621+
eth_keypair_( std::move( eth_keypair ) ),
547622
storage_( std::move( storage ) ),
548623
utxo_manager_(
549624
is_full_node_,
@@ -799,7 +874,7 @@ namespace sgns
799874
if ( cached_nonce_result_.has_value() )
800875
{
801876
auto now = std::chrono::steady_clock::now();
802-
auto cache_age_ms = std::chrono::duration_cast<std::chrono::milliseconds>( now - cached_nonce_timestamp_ )
877+
uint64_t cache_age_ms = std::chrono::duration_cast<std::chrono::milliseconds>( now - cached_nonce_timestamp_ )
803878
.count();
804879

805880
if ( cache_age_ms < NONCE_CACHE_DURATION_MS )
@@ -984,19 +1059,6 @@ namespace sgns
9841059
has_cid_method_ = nullptr;
9851060
}
9861061

987-
void GeniusAccount::SetGetUTXOsMethod(
988-
std::function<outcome::result<std::vector<std::string>>( const std::string & )> method )
989-
{
990-
std::lock_guard lock( get_cids_mutex_ );
991-
get_utxos_method_ = std::move( method );
992-
}
993-
994-
void GeniusAccount::ClearGetUTXOsMethod()
995-
{
996-
std::lock_guard lock( get_cids_mutex_ );
997-
get_utxos_method_ = nullptr;
998-
}
999-
10001062
void GeniusAccount::SetGetValidatorWeightMethod(
10011063
std::function<outcome::result<std::optional<uint64_t>>( const std::string & )> method )
10021064
{

src/account/GeniusAccount.hpp

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include <functional>
1818
#include <optional>
1919
#include <set>
20-
#include <storage/rocksdb/rocksdb.hpp>
2120
#include <string_view>
2221

2322
#include <boost/multiprecision/cpp_int.hpp>
@@ -28,6 +27,7 @@
2827
#include <ProofSystem/EthereumKeyGenerator.hpp>
2928

3029
#include "account/TokenID.hpp"
30+
#include "storage/rocksdb/rocksdb.hpp"
3131
#include "local_secure_storage/ISecureStorage.hpp"
3232
#include "outcome/outcome.hpp"
3333
#include "UTXOManager.hpp"
@@ -38,15 +38,6 @@ namespace sgns
3838
{
3939
using namespace boost::multiprecision;
4040

41-
namespace ipfs_pubsub
42-
{
43-
class GossipPubSub;
44-
}
45-
46-
namespace crdt
47-
{
48-
class GlobalDB;
49-
}
5041
class AccountMessenger;
5142
class TransactionManager;
5243

@@ -56,12 +47,6 @@ namespace sgns
5647
using StorageWithAddress = std::pair<std::shared_ptr<ISecureStorage>,
5748
std::pair<KeyGenerator::ElGamal, ethereum::EthereumKeyGenerator>>;
5849

59-
struct Credentials
60-
{
61-
std::string email;
62-
std::string password;
63-
};
64-
6550
static const std::array<uint8_t, 32> ELGAMAL_PUBKEY_PREDEFINED; ///< Predefined ElGamal public key
6651
static constexpr uint64_t NONCE_CACHE_DURATION_MS = 5000; ///< Cache nonce results for 5 seconds
6752

@@ -83,6 +68,10 @@ namespace sgns
8368
const boost::filesystem::path &base_path,
8469
bool full_node = false );
8570

71+
static std::shared_ptr<GeniusAccount> NewFromPublicKey( TokenID token_id,
72+
std::string_view public_key,
73+
bool full_node = false );
74+
8675
/**
8776
* @brief Factory constructor of new GeniusAccount
8877
* @param[in] token_id Token ID of the account
@@ -91,6 +80,8 @@ namespace sgns
9180
const boost::filesystem::path &base_path,
9281
bool full_node = false );
9382

83+
static std::vector<std::string> GetAvailableAccounts( const boost::filesystem::path &base_path );
84+
9485
/**
9586
* @brief Initialize the messenger for the account
9687
* @param[in] pubsub pubsub instance
@@ -274,9 +265,6 @@ namespace sgns
274265
void ClearGetBlockChainCIDMethod();
275266
void SetHasBlockCidMethod( std::function<outcome::result<bool>( const std::string & )> method );
276267
void ClearHasBlockCidMethod();
277-
void SetGetUTXOsMethod(
278-
std::function<outcome::result<std::vector<std::string>>( const std::string & )> method );
279-
void ClearGetUTXOsMethod();
280268
void SetGetValidatorWeightMethod(
281269
std::function<outcome::result<std::optional<uint64_t>>( const std::string & )> method );
282270
void ClearGetValidatorWeightMethod();
@@ -289,6 +277,8 @@ namespace sgns
289277

290278
static outcome::result<StorageWithAddress> LoadGeniusAccount( const boost::filesystem::path &base_path );
291279

280+
static outcome::result<StorageWithAddress> LoadGeniusAccount( std::string_view public_key );
281+
292282
static std::shared_ptr<GeniusAccount> CreateInstanceFromResponse( TokenID token_id,
293283
StorageWithAddress response_value,
294284
bool full_node );

0 commit comments

Comments
 (0)