From 8a13c047dca962d2cb6418e357cf8a9d30e50d86 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 21 May 2024 12:14:09 +0100 Subject: [PATCH 01/47] IS 968 add historic data to archive node snapshot --- libethereum/Client.cpp | 12 ++-- libethereum/Client.h | 4 +- libethereum/SnapshotAgent.cpp | 4 +- libethereum/SnapshotAgent.h | 2 +- libskale/SnapshotHashAgent.cpp | 56 +++++++-------- libskale/SnapshotHashAgent.h | 4 +- libskale/SnapshotManager.cpp | 88 +++++++++++++++++++----- libskale/SnapshotManager.h | 11 +-- libweb3jsonrpc/Skale.cpp | 2 +- skaled/main.cpp | 16 ++--- test/unittests/libskale/HashSnapshot.cpp | 4 +- 11 files changed, 126 insertions(+), 77 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index faf04ec7d..1898da6dd 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -825,9 +825,9 @@ void Client::rejigSealing() { // TODO Deduplicate code! dev::h256 stateRootToSet; if ( m_snapshotAgent->getLatestSnapshotBlockNumer() > 0 ) { - dev::h256 state_root_hash = this->m_snapshotAgent->getSnapshotHash( - m_snapshotAgent->getLatestSnapshotBlockNumer() ); - stateRootToSet = state_root_hash; + dev::h256 stateRootHash = this->m_snapshotAgent->getSnapshotHash( + m_snapshotAgent->getLatestSnapshotBlockNumer(), false ); + stateRootToSet = stateRootHash; } // propagate current! else if ( this->number() > 0 ) { @@ -881,9 +881,9 @@ void Client::sealUnconditionally( bool submitToBlockChain ) { // TODO Deduplicate code! dev::h256 stateRootToSet; if ( m_snapshotAgent->getLatestSnapshotBlockNumer() > 0 ) { - dev::h256 state_root_hash = this->m_snapshotAgent->getSnapshotHash( - m_snapshotAgent->getLatestSnapshotBlockNumer() ); - stateRootToSet = state_root_hash; + dev::h256 stateRootHash = this->m_snapshotAgent->getSnapshotHash( + m_snapshotAgent->getLatestSnapshotBlockNumer(), false ); + stateRootToSet = stateRootHash; } // propagate current! else if ( this->number() > 0 ) { diff --git a/libethereum/Client.h b/libethereum/Client.h index 468aec177..dd5045285 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -300,8 +300,8 @@ class Client : public ClientBase, protected Worker { // set exiting time for node rotation void setSchainExitTime( uint64_t _timestamp ) const; - dev::h256 getSnapshotHash( unsigned _blockNumber ) const { - return m_snapshotAgent->getSnapshotHash( _blockNumber ); + dev::h256 getSnapshotHash( unsigned _blockNumber, bool _forArchiveNode = false ) const { + return m_snapshotAgent->getSnapshotHash( _blockNumber, _forArchiveNode ); } uint64_t getBlockTimestampFromSnapshot( unsigned _blockNumber ) const { diff --git a/libethereum/SnapshotAgent.cpp b/libethereum/SnapshotAgent.cpp index 68e055147..4998208b6 100644 --- a/libethereum/SnapshotAgent.cpp +++ b/libethereum/SnapshotAgent.cpp @@ -156,12 +156,12 @@ void SnapshotAgent::terminate() { } } -dev::h256 SnapshotAgent::getSnapshotHash( unsigned _blockNumber ) const { +dev::h256 SnapshotAgent::getSnapshotHash( unsigned _blockNumber, bool _forArchiveNode ) const { if ( _blockNumber > this->last_snapshoted_block_with_hash && _blockNumber != 0 ) return dev::h256(); try { - dev::h256 res = this->m_snapshotManager->getSnapshotHash( _blockNumber ); + dev::h256 res = this->m_snapshotManager->getSnapshotHash( _blockNumber, _forArchiveNode ); return res; } catch ( const SnapshotManager::SnapshotAbsent& ) { return dev::h256(); diff --git a/libethereum/SnapshotAgent.h b/libethereum/SnapshotAgent.h index 140e0c4cd..79e46b6e4 100644 --- a/libethereum/SnapshotAgent.h +++ b/libethereum/SnapshotAgent.h @@ -30,7 +30,7 @@ class SnapshotAgent { void terminate(); - dev::h256 getSnapshotHash( unsigned _blockNumber ) const; + dev::h256 getSnapshotHash( unsigned _blockNumber, bool _forArchiveNode ) const; uint64_t getBlockTimestampFromSnapshot( unsigned _blockNumber ) const; int64_t getLatestSnapshotBlockNumer() const { return this->last_snapshoted_block_with_hash; } uint64_t getSnapshotCalculationTime() const { return this->snapshot_calculation_time_ms; } diff --git a/libskale/SnapshotHashAgent.cpp b/libskale/SnapshotHashAgent.cpp index 83797bce8..c8c84d4e1 100644 --- a/libskale/SnapshotHashAgent.cpp +++ b/libskale/SnapshotHashAgent.cpp @@ -33,11 +33,11 @@ #include #include -SnapshotHashAgent::SnapshotHashAgent( const dev::eth::ChainParams& chain_params, +SnapshotHashAgent::SnapshotHashAgent( const dev::eth::ChainParams& chainParams, const std::array< std::string, 4 >& common_public_key, const std::string& ipToDownloadSnapshotFrom ) - : chain_params_( chain_params ), - n_( chain_params.sChain.nodes.size() ), + : chainParams_( chainParams ), + n_( chainParams.sChain.nodes.size() ), ipToDownloadSnapshotFrom_( ipToDownloadSnapshotFrom ) { this->hashes_.resize( n_ ); this->signatures_.resize( n_ ); @@ -63,20 +63,20 @@ SnapshotHashAgent::SnapshotHashAgent( const dev::eth::ChainParams& chain_params, void SnapshotHashAgent::readPublicKeyFromConfig() { this->common_public_key_.X.c0 = - libff::alt_bn128_Fq( chain_params_.nodeInfo.commonBLSPublicKeys[0].c_str() ); + libff::alt_bn128_Fq( chainParams_.nodeInfo.commonBLSPublicKeys[0].c_str() ); this->common_public_key_.X.c1 = - libff::alt_bn128_Fq( chain_params_.nodeInfo.commonBLSPublicKeys[1].c_str() ); + libff::alt_bn128_Fq( chainParams_.nodeInfo.commonBLSPublicKeys[1].c_str() ); this->common_public_key_.Y.c0 = - libff::alt_bn128_Fq( chain_params_.nodeInfo.commonBLSPublicKeys[2].c_str() ); + libff::alt_bn128_Fq( chainParams_.nodeInfo.commonBLSPublicKeys[2].c_str() ); this->common_public_key_.Y.c1 = - libff::alt_bn128_Fq( chain_params_.nodeInfo.commonBLSPublicKeys[3].c_str() ); + libff::alt_bn128_Fq( chainParams_.nodeInfo.commonBLSPublicKeys[3].c_str() ); this->common_public_key_.Z = libff::alt_bn128_Fq2::one(); } size_t SnapshotHashAgent::verifyAllData() const { size_t verified = 0; for ( size_t i = 0; i < this->n_; ++i ) { - if ( this->chain_params_.nodeInfo.id == this->chain_params_.sChain.nodes[i].id ) { + if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { continue; } @@ -114,7 +114,7 @@ bool SnapshotHashAgent::voteForHash() { const std::lock_guard< std::mutex > lock( this->hashes_mutex ); for ( size_t i = 0; i < this->n_; ++i ) { - if ( this->chain_params_.nodeInfo.id == this->chain_params_.sChain.nodes[i].id ) { + if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { continue; } @@ -136,7 +136,7 @@ bool SnapshotHashAgent::voteForHash() { std::vector< size_t > idx; std::vector< libff::alt_bn128_G1 > signatures; for ( size_t i = 0; i < this->n_; ++i ) { - if ( this->chain_params_.nodeInfo.id == this->chain_params_.sChain.nodes[i].id ) { + if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { continue; } @@ -185,13 +185,13 @@ bool SnapshotHashAgent::voteForHash() { libff::alt_bn128_G2 common_public_key_from_config; common_public_key_from_config.X.c0 = libff::alt_bn128_Fq( - this->chain_params_.nodeInfo.commonBLSPublicKeys[0].c_str() ); + this->chainParams_.nodeInfo.commonBLSPublicKeys[0].c_str() ); common_public_key_from_config.X.c1 = libff::alt_bn128_Fq( - this->chain_params_.nodeInfo.commonBLSPublicKeys[1].c_str() ); + this->chainParams_.nodeInfo.commonBLSPublicKeys[1].c_str() ); common_public_key_from_config.Y.c0 = libff::alt_bn128_Fq( - this->chain_params_.nodeInfo.commonBLSPublicKeys[2].c_str() ); + this->chainParams_.nodeInfo.commonBLSPublicKeys[2].c_str() ); common_public_key_from_config.Y.c1 = libff::alt_bn128_Fq( - this->chain_params_.nodeInfo.commonBLSPublicKeys[3].c_str() ); + this->chainParams_.nodeInfo.commonBLSPublicKeys[3].c_str() ); common_public_key_from_config.Z = libff::alt_bn128_Fq2::one(); std::cout << "NEW BLS COMMON PUBLIC KEY:\n"; common_public_key_from_config.print_coordinates(); @@ -227,9 +227,9 @@ bool SnapshotHashAgent::voteForHash() { return true; } } else { - size_t nodeIdx = std::distance( this->chain_params_.sChain.nodes.begin(), - std::find_if( this->chain_params_.sChain.nodes.begin(), - this->chain_params_.sChain.nodes.end(), [this]( const dev::eth::sChainNode& node ) { + size_t nodeIdx = std::distance( this->chainParams_.sChain.nodes.begin(), + std::find_if( this->chainParams_.sChain.nodes.begin(), + this->chainParams_.sChain.nodes.end(), [this]( const dev::eth::sChainNode& node ) { return node.ip == ipToDownloadSnapshotFrom_; } ) ); @@ -255,15 +255,15 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( std::vector< std::thread > threads; for ( size_t i = 0; i < this->n_; ++i ) { - if ( this->chain_params_.nodeInfo.id == this->chain_params_.sChain.nodes[i].id ) { + if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { continue; } threads.push_back( std::thread( [this, i, block_number]() { try { jsonrpc::HttpClient* jsonRpcClient = new jsonrpc::HttpClient( - "http://" + this->chain_params_.sChain.nodes[i].ip + ':' + - ( this->chain_params_.sChain.nodes[i].port + 3 ).convert_to< std::string >() ); + "http://" + this->chainParams_.sChain.nodes[i].ip + ':' + + ( this->chainParams_.sChain.nodes[i].port + 3 ).convert_to< std::string >() ); SkaleClient skaleClient( *jsonRpcClient ); Json::Value joSignatureResponse; @@ -272,7 +272,7 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( } catch ( jsonrpc::JsonRpcException& ex ) { cerror << "WARNING " << "Error while trying to get snapshot signature from " - << this->chain_params_.sChain.nodes[i].ip << " : " << ex.what(); + << this->chainParams_.sChain.nodes[i].ip << " : " << ex.what(); delete jsonRpcClient; return; } @@ -291,8 +291,8 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( std::string str_hash = joSignatureResponse["hash"].asString(); cnote << "Received snapshot hash from " - << "http://" + this->chain_params_.sChain.nodes[i].ip + ':' + - ( this->chain_params_.sChain.nodes[i].port + 3 ) + << "http://" + this->chainParams_.sChain.nodes[i].ip + ':' + + ( this->chainParams_.sChain.nodes[i].port + 3 ) .convert_to< std::string >() << " : " << str_hash << '\n'; @@ -335,7 +335,7 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( bool result = false; - if ( !AmsterdamFixPatch::snapshotHashCheckingEnabled( this->chain_params_ ) ) { + if ( !AmsterdamFixPatch::snapshotHashCheckingEnabled( this->chainParams_ ) ) { // keep only nodes from majorityNodesIds auto majorityNodesIds = AmsterdamFixPatch::majorityNodesIds(); dev::h256 common_hash; // should be same everywhere! @@ -343,7 +343,7 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( if ( !this->is_received_[pos] ) continue; - u256 id = this->chain_params_.sChain.nodes[pos].id; + u256 id = this->chainParams_.sChain.nodes[pos].id; bool good = majorityNodesIds.end() != std::find( majorityNodesIds.begin(), majorityNodesIds.end(), id ); if ( !good ) @@ -382,9 +382,9 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( std::vector< std::string > ret; for ( const size_t idx : this->nodes_to_download_snapshot_from_ ) { std::string ret_value = - std::string( "http://" ) + std::string( this->chain_params_.sChain.nodes[idx].ip ) + + std::string( "http://" ) + std::string( this->chainParams_.sChain.nodes[idx].ip ) + std::string( ":" ) + - ( this->chain_params_.sChain.nodes[idx].port + 3 ).convert_to< std::string >(); + ( this->chainParams_.sChain.nodes[idx].port + 3 ).convert_to< std::string >(); ret.push_back( ret_value ); } @@ -396,7 +396,7 @@ std::pair< dev::h256, libff::alt_bn128_G1 > SnapshotHashAgent::getVotedHash() co throw std::invalid_argument( "Hash is empty" ); } - if ( AmsterdamFixPatch::snapshotHashCheckingEnabled( this->chain_params_ ) ) { + if ( AmsterdamFixPatch::snapshotHashCheckingEnabled( this->chainParams_ ) ) { if ( this->voted_hash_.second == libff::alt_bn128_G1::zero() || !this->voted_hash_.second.is_well_formed() ) { throw std::invalid_argument( "Signature is not well formed" ); diff --git a/libskale/SnapshotHashAgent.h b/libskale/SnapshotHashAgent.h index 87d71a659..7cfa0d452 100644 --- a/libskale/SnapshotHashAgent.h +++ b/libskale/SnapshotHashAgent.h @@ -65,7 +65,7 @@ class IsNotVerified : public SnapshotHashAgentException { class SnapshotHashAgent { public: - SnapshotHashAgent( const dev::eth::ChainParams& chain_params, + SnapshotHashAgent( const dev::eth::ChainParams& chainParams, const std::array< std::string, 4 >& common_public_key, const std::string& ipToDownloadSnapshotFrom ); @@ -76,7 +76,7 @@ class SnapshotHashAgent { friend class dev::test::SnapshotHashAgentTest; private: - dev::eth::ChainParams chain_params_; + dev::eth::ChainParams chainParams_; unsigned n_; std::string ipToDownloadSnapshotFrom_; std::shared_ptr< libBLS::Bls > bls_; diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 8729d2a74..d36eadad0 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -48,16 +48,17 @@ namespace fs = boost::filesystem; // Can manage snapshots as non-prvivileged user // For send/receive needs root! -const std::string SnapshotManager::snapshot_hash_file_name = "snapshot_hash.txt"; +const std::string SnapshotManager::snapshotHashFileName = "snapshot_hash.txt"; +const std::string SnapshotManager::partialSnapshotHashFileName = "partial_snapshot_hash.txt"; // exceptions: // - bad data dir // - not btrfs // - volumes don't exist -SnapshotManager::SnapshotManager( const dev::eth::ChainParams& _chain_params, +SnapshotManager::SnapshotManager( const dev::eth::ChainParams& _chainParams, const fs::path& _dataDir, const std::vector< std::string >& _volumes, const std::string& _diffsDir ) - : chain_params( _chain_params ) { + : chainParams( _chainParams ) { assert( _volumes.size() > 0 ); data_dir = _dataDir; @@ -389,7 +390,7 @@ void SnapshotManager::leaveNLastDiffs( unsigned n ) { } // for } -dev::h256 SnapshotManager::getSnapshotHash( unsigned block_number ) const { +dev::h256 SnapshotManager::getSnapshotHash( unsigned block_number, bool _forArchiveNode ) const { fs::path snapshot_dir = snapshots_dir / to_string( block_number ); try { @@ -399,22 +400,28 @@ dev::h256 SnapshotManager::getSnapshotHash( unsigned block_number ) const { std::throw_with_nested( CannotRead( snapshot_dir ) ); } // catch - std::string hash_file = - ( this->snapshots_dir / std::to_string( block_number ) / this->snapshot_hash_file_name ) - .string(); + std::string hashFile; + if ( !_forArchiveNode && chainParams.nodeInfo.archiveMode ) + hashFile = ( this->snapshots_dir / std::to_string( block_number ) / + this->partialSnapshotHashFileName ) + .string(); + else + hashFile = + ( this->snapshots_dir / std::to_string( block_number ) / this->snapshotHashFileName ) + .string(); if ( !isSnapshotHashPresent( block_number ) ) { - BOOST_THROW_EXCEPTION( SnapshotManager::CannotRead( hash_file ) ); + BOOST_THROW_EXCEPTION( SnapshotManager::CannotRead( hashFile ) ); } dev::h256 hash; try { - std::lock_guard< std::mutex > lock( hash_file_mutex ); - std::ifstream in( hash_file ); + std::lock_guard< std::mutex > lock( hashFileMutex ); + std::ifstream in( hashFile ); in >> hash; } catch ( const std::exception& ex ) { - std::throw_with_nested( SnapshotManager::CannotRead( hash_file ) ); + std::throw_with_nested( SnapshotManager::CannotRead( hashFile ) ); } return hash; } @@ -429,13 +436,21 @@ bool SnapshotManager::isSnapshotHashPresent( unsigned _blockNumber ) const { std::throw_with_nested( CannotRead( snapshot_dir ) ); } // catch - boost::filesystem::path hash_file = - this->snapshots_dir / std::to_string( _blockNumber ) / this->snapshot_hash_file_name; + boost::filesystem::path hashFile = + this->snapshots_dir / std::to_string( _blockNumber ) / this->snapshotHashFileName; try { - std::lock_guard< std::mutex > lock( hash_file_mutex ); - return boost::filesystem::exists( hash_file ); + std::lock_guard< std::mutex > lock( hashFileMutex ); + if ( !chainParams.nodeInfo.archiveMode ) + return boost::filesystem::exists( hashFile ); + else { + boost::filesystem::path partialHashFile = this->snapshots_dir / + std::to_string( _blockNumber ) / + this->partialSnapshotHashFileName; + return boost::filesystem::exists( hashFile ) && + boost::filesystem::exists( partialHashFile ); + } } catch ( const fs::filesystem_error& ) { - std::throw_with_nested( CannotRead( hash_file ) ); + std::throw_with_nested( CannotRead( hashFile ) ); } } @@ -657,6 +672,41 @@ void SnapshotManager::computeAllVolumesHash( if ( _blockNumber && this->volumes.size() > 3 ) { this->addLastPriceToHash( _blockNumber, ctx ); } + + if ( chainParams.nodeInfo.archiveMode ) { + // save partial snapshot hash + secp256k1_sha256_t partialCtx = *ctx; + + dev::h256 partialHash; + secp256k1_sha256_finalize( &partialCtx, partialHash.data() ); + + string hashFile = ( this->snapshots_dir / std::to_string( _blockNumber ) ).string() + '/' + + this->partialSnapshotHashFileName; + + try { + std::lock_guard< std::mutex > lock( hashFileMutex ); + std::ofstream out( hashFile ); + out.clear(); + out << partialHash; + } catch ( const std::exception& ex ) { + std::throw_with_nested( SnapshotManager::CannotCreate( hashFile ) ); + } + + // archive blocks + for ( auto& content : contents ) { + if ( content.leaf().string().find( "archive" ) == std::string::npos ) + continue; + this->computeDatabaseHash( content, ctx ); + } + + // historic dbs + this->computeDatabaseHash( this->snapshots_dir / std::to_string( _blockNumber ) / + this->volumes[4] / this->volumes[0] / "state", + ctx ); + this->computeDatabaseHash( this->snapshots_dir / std::to_string( _blockNumber ) / + this->volumes[5] / this->volumes[0] / "state", + ctx ); + } } void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checking ) { @@ -701,10 +751,10 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki secp256k1_sha256_finalize( &ctx, hash.data() ); string hash_file = ( this->snapshots_dir / std::to_string( _blockNumber ) ).string() + '/' + - this->snapshot_hash_file_name; + this->snapshotHashFileName; try { - std::lock_guard< std::mutex > lock( hash_file_mutex ); + std::lock_guard< std::mutex > lock( hashFileMutex ); std::ofstream out( hash_file ); out.clear(); out << hash; @@ -732,7 +782,7 @@ uint64_t SnapshotManager::getBlockTimestamp( unsigned _blockNumber ) const { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); } - dev::eth::BlockChain bc( chain_params, db_dir, false ); + dev::eth::BlockChain bc( chainParams, db_dir, false ); dev::h256 hash = bc.numberHash( _blockNumber ); uint64_t timestamp = dev::eth::BlockHeader( bc.block( hash ) ).timestamp(); diff --git a/libskale/SnapshotManager.h b/libskale/SnapshotManager.h index 26aa1d411..2bae44766 100644 --- a/libskale/SnapshotManager.h +++ b/libskale/SnapshotManager.h @@ -152,7 +152,7 @@ class SnapshotManager { /////////////// MORE INTERESTING STUFF //////////////// public: - SnapshotManager( const dev::eth::ChainParams& _chain_params, + SnapshotManager( const dev::eth::ChainParams& _chainParams, const boost::filesystem::path& _dataDir, const std::vector< std::string >& _volumes, const std::string& diffs_dir = std::string() ); void doSnapshot( unsigned _blockNumber ); @@ -167,7 +167,7 @@ class SnapshotManager { void leaveNLastSnapshots( unsigned n ); void leaveNLastDiffs( unsigned n ); - dev::h256 getSnapshotHash( unsigned _blockNumber ) const; + dev::h256 getSnapshotHash( unsigned _blockNumber, bool _forArchiveNode = false ) const; std::pair< int, int > getLatestSnapshots() const; bool isSnapshotHashPresent( unsigned _blockNumber ) const; void computeSnapshotHash( unsigned _blockNumber, bool is_checking = false ); @@ -183,10 +183,11 @@ class SnapshotManager { boost::filesystem::path snapshots_dir; boost::filesystem::path diffs_dir; - static const std::string snapshot_hash_file_name; - mutable std::mutex hash_file_mutex; + static const std::string snapshotHashFileName; + static const std::string partialSnapshotHashFileName; + mutable std::mutex hashFileMutex; - dev::eth::ChainParams chain_params; + dev::eth::ChainParams chainParams; void cleanupDirectory( const boost::filesystem::path& p, const boost::filesystem::path& _keepDirectory = "" ); diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index 27b71b1cb..9cb807327 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -376,7 +376,7 @@ Json::Value Skale::skale_getSnapshotSignature( unsigned blockNumber ) { } try { - dev::h256 snapshot_hash = this->m_client.getSnapshotHash( blockNumber ); + dev::h256 snapshot_hash = this->m_client.getSnapshotHash( blockNumber, false ); if ( !snapshot_hash ) throw std::runtime_error( "Requested hash of block " + to_string( blockNumber ) + " is absent" ); diff --git a/skaled/main.cpp b/skaled/main.cpp index 9382c6dda..efc64f682 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1588,15 +1588,13 @@ int main( int argc, char** argv ) try { } if ( chainParams.sChain.snapshotIntervalSec > 0 || downloadSnapshotFlag ) { - // auto mostRecentBlocksDBPath = (getDataDir() / ( "blocks_" + chainParams.nodeInfo.id.str() - // + ".db" )) / "1.db"; - - snapshotManager.reset( new SnapshotManager( chainParams, getDataDir(), - { BlockChain::getChainDirName( chainParams ), "filestorage", - "prices_" + chainParams.nodeInfo.id.str() + ".db", - "blocks_" + chainParams.nodeInfo.id.str() + ".db"/*, - mostRecentBlocksDBPath.string()*/ }, - sharedSpace ? sharedSpace->getPath() : "" ) ); + std::vector< std::string > volumes = { BlockChain::getChainDirName( chainParams ), + "filestorage", "prices_" + chainParams.nodeInfo.id.str() + ".db", + "blocks_" + chainParams.nodeInfo.id.str() + ".db" }; + if ( chainParams.nodeInfo.archiveMode ) + volumes.insert( volumes.end(), { "historic_roots", "historic_state" } ); + snapshotManager.reset( new SnapshotManager( + chainParams, getDataDir(), volumes, sharedSpace ? sharedSpace->getPath() : "" ) ); } bool downloadGenesisForSyncNode = false; diff --git a/test/unittests/libskale/HashSnapshot.cpp b/test/unittests/libskale/HashSnapshot.cpp index 77ca9f4fe..79bb20d7d 100644 --- a/test/unittests/libskale/HashSnapshot.cpp +++ b/test/unittests/libskale/HashSnapshot.cpp @@ -119,8 +119,8 @@ class SnapshotHashAgentTest { std::vector< size_t > ret; for ( size_t i = 0; i < this->hashAgent_->n_; ++i ) { - if ( this->hashAgent_->chain_params_.nodeInfo.id == - this->hashAgent_->chain_params_.sChain.nodes[i].id ) { + if ( this->hashAgent_->chainParams_.nodeInfo.id == + this->hashAgent_->chainParams_.sChain.nodes[i].id ) { continue; } From fe94fa444db30bf8bdd35fb040f05b80958da11c Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 21 May 2024 15:34:58 +0100 Subject: [PATCH 02/47] IS 968 download snapshot from archive node --- skaled/main.cpp | 137 ++++++++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 69 deletions(-) diff --git a/skaled/main.cpp b/skaled/main.cpp index efc64f682..a08fd77a7 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -342,19 +342,14 @@ std::array< std::string, 4 > getBLSPublicKeyToVerifySnapshot( const ChainParams& return arrayCommonPublicKey; } -unsigned getBlockToDownladSnapshot( const dev::eth::sChainNode& nodeInfo ) { - std::string blockNumber_url = std::string( "http://" ) + std::string( nodeInfo.ip ) + - std::string( ":" ) + - ( nodeInfo.port + 3 ).convert_to< std::string >(); - +unsigned getBlockToDownladSnapshot( const std::string& nodeUrl ) { clog( VerbosityInfo, "getBlockToDownladSnapshot" ) - << cc::notice( "Asking node " ) << cc::p( nodeInfo.sChainIndex.str() ) << ' ' - << cc::notice( blockNumber_url ) << cc::notice( " for latest snapshot block number." ); + << "Asking node " << ' ' << nodeUrl << " for latest snapshot block number."; - unsigned blockNumber = getLatestSnapshotBlockNumber( blockNumber_url ); + unsigned blockNumber = getLatestSnapshotBlockNumber( nodeUrl ); clog( VerbosityInfo, "getBlockToDownladSnapshot" ) - << cc::notice( "Latest Snapshot Block Number" ) + cc::debug( " is: " ) - << cc::p( std::to_string( blockNumber ) ) << " (from " << blockNumber_url << ")"; + << std::string( "Latest Snapshot Block Number is: " ) << std::to_string( blockNumber ) + << " (from " << nodeUrl << ")"; return blockNumber; } @@ -471,56 +466,70 @@ bool tryDownloadSnapshot( std::shared_ptr< SnapshotManager >& snapshotManager, return false; } -void downloadAndProccessSnapshot( std::shared_ptr< SnapshotManager >& snapshotManager, - const ChainParams& chainParams, bool requireSnapshotMajority, - const std::string& ipToDownloadSnapshotFrom, bool isRegularSnapshot ) { - std::array< std::string, 4 > arrayCommonPublicKey = - getBLSPublicKeyToVerifySnapshot( chainParams ); +bool downloadSnapshotFromUrl( std::shared_ptr< SnapshotManager >& snapshotManager, + const ChainParams& chainParams, const std::array< std::string, 4 >& arrayCommonPublicKey, + const std::string& urlToDownloadSnapshotFrom, bool isRegularSnapshot ) { + unsigned blockNumber = 0; + if ( isRegularSnapshot ) + blockNumber = getBlockToDownladSnapshot( urlToDownloadSnapshotFrom ); - bool successfullDownload = false; + std::unique_ptr< SnapshotHashAgent > snapshotHashAgent( + new SnapshotHashAgent( chainParams, arrayCommonPublicKey, urlToDownloadSnapshotFrom ) ); - for ( size_t idx = 0; idx < chainParams.sChain.nodes.size() && !successfullDownload; ++idx ) - try { - if ( !requireSnapshotMajority && - std::string( chainParams.sChain.nodes[idx].ip ) != ipToDownloadSnapshotFrom ) - continue; + libff::init_alt_bn128_params(); + std::pair< dev::h256, libff::alt_bn128_G1 > votedHash; + std::vector< std::string > listUrlsToDownload; + std::tie( listUrlsToDownload, votedHash ) = + voteForSnapshotHash( snapshotHashAgent, blockNumber ); - if ( chainParams.nodeInfo.id == chainParams.sChain.nodes[idx].id ) - continue; + if ( listUrlsToDownload.empty() ) { + if ( !isRegularSnapshot ) + return true; + clog( VerbosityWarning, "downloadAndProccessSnapshot" ) + << std::string( "No nodes to download from - will skip " ) << urlToDownloadSnapshotFrom; + return false; + } - unsigned blockNumber = 0; - if ( isRegularSnapshot ) - blockNumber = getBlockToDownladSnapshot( chainParams.sChain.nodes[idx] ); + bool successfullDownload = checkLocalSnapshot( snapshotManager, blockNumber, votedHash.first ); + if ( successfullDownload ) + return successfullDownload; - std::unique_ptr< SnapshotHashAgent > snapshotHashAgent( new SnapshotHashAgent( - chainParams, arrayCommonPublicKey, ipToDownloadSnapshotFrom ) ); + successfullDownload = tryDownloadSnapshot( snapshotManager, chainParams, listUrlsToDownload, + votedHash, blockNumber, isRegularSnapshot ); - libff::init_alt_bn128_params(); - std::pair< dev::h256, libff::alt_bn128_G1 > votedHash; - std::vector< std::string > listUrlsToDownload; - std::tie( listUrlsToDownload, votedHash ) = - voteForSnapshotHash( snapshotHashAgent, blockNumber ); + return successfullDownload; +} - if ( listUrlsToDownload.empty() ) { - if ( !isRegularSnapshot ) - return; - clog( VerbosityWarning, "downloadAndProccessSnapshot" ) - << cc::warn( "No nodes to download from - will skip " + std::to_string( idx ) ); - continue; - } +void downloadAndProccessSnapshot( std::shared_ptr< SnapshotManager >& snapshotManager, + const ChainParams& chainParams, const std::string& urlToDownloadSnapshotFrom, + bool isRegularSnapshot ) { + std::array< std::string, 4 > arrayCommonPublicKey = + getBLSPublicKeyToVerifySnapshot( chainParams ); - successfullDownload = - checkLocalSnapshot( snapshotManager, blockNumber, votedHash.first ); - if ( successfullDownload ) - break; + bool successfullDownload = false; - successfullDownload = tryDownloadSnapshot( snapshotManager, chainParams, - listUrlsToDownload, votedHash, blockNumber, isRegularSnapshot ); - } catch ( std::exception& ex ) { - clog( VerbosityWarning, "downloadAndProccessSnapshot" ) - << cc::warn( "Exception while trying to set up snapshot: " ) - << cc::warn( dev::nested_exception_what( ex ) ); - } // for blockNumber_url + if ( !urlToDownloadSnapshotFrom.empty() ) + successfullDownload = downloadSnapshotFromUrl( snapshotManager, chainParams, + arrayCommonPublicKey, urlToDownloadSnapshotFrom, isRegularSnapshot ); + else { + for ( size_t idx = 0; idx < chainParams.sChain.nodes.size() && !successfullDownload; ++idx ) + try { + if ( chainParams.nodeInfo.id == chainParams.sChain.nodes[idx].id ) + continue; + + std::string nodeUrl = + std::string( "http://" ) + std::string( chainParams.sChain.nodes[idx].ip ) + + std::string( ":" ) + + ( chainParams.sChain.nodes[idx].port + 3 ).convert_to< std::string >(); + + successfullDownload = downloadSnapshotFromUrl( snapshotManager, chainParams, + arrayCommonPublicKey, nodeUrl, isRegularSnapshot ); + } catch ( std::exception& ex ) { + clog( VerbosityWarning, "downloadAndProccessSnapshot" ) + << cc::warn( "Exception while trying to set up snapshot: " ) + << cc::warn( dev::nested_exception_what( ex ) ); + } // for blockNumber_url + } if ( !successfullDownload ) { throw std::runtime_error( "FATAL: tried to download snapshot from everywhere!" ); @@ -1580,11 +1589,9 @@ int main( int argc, char** argv ) try { downloadSnapshotFlag = true; } - bool requireSnapshotMajority = true; - std::string ipToDownloadSnapshotFrom = ""; + std::string urlToDownloadSnapshotFrom = ""; if ( vm.count( "no-snapshot-majority" ) ) { - requireSnapshotMajority = false; - ipToDownloadSnapshotFrom = vm["no-snapshot-majority"].as< string >(); + urlToDownloadSnapshotFrom = vm["no-snapshot-majority"].as< string >(); } if ( chainParams.sChain.snapshotIntervalSec > 0 || downloadSnapshotFlag ) { @@ -1613,26 +1620,18 @@ int main( int argc, char** argv ) try { statusAndControl->setExitState( StatusAndControl::StartFromSnapshot, true ); statusAndControl->setSubsystemRunning( StatusAndControl::SnapshotDownloader, true ); - if ( !ipToDownloadSnapshotFrom.empty() && - std::find_if( chainParams.sChain.nodes.begin(), chainParams.sChain.nodes.end(), - [&ipToDownloadSnapshotFrom]( const dev::eth::sChainNode& node ) { - return node.ip == ipToDownloadSnapshotFrom; - } ) == chainParams.sChain.nodes.end() ) - throw std::runtime_error( - "ipToDownloadSnapshotFrom provided is incorrect - no such node in schain" ); - std::unique_ptr< std::lock_guard< SharedSpace > > sharedSpace_lock; if ( sharedSpace ) sharedSpace_lock.reset( new std::lock_guard< SharedSpace >( *sharedSpace ) ); try { if ( !downloadGenesisForSyncNode ) - downloadAndProccessSnapshot( snapshotManager, chainParams, requireSnapshotMajority, - ipToDownloadSnapshotFrom, true ); + downloadAndProccessSnapshot( + snapshotManager, chainParams, urlToDownloadSnapshotFrom, true ); else { try { - downloadAndProccessSnapshot( snapshotManager, chainParams, - requireSnapshotMajority, ipToDownloadSnapshotFrom, false ); + downloadAndProccessSnapshot( + snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); snapshotManager->restoreSnapshot( 0 ); } catch ( SnapshotManager::SnapshotAbsent& ) { clog( VerbosityWarning, "main" ) @@ -1649,8 +1648,8 @@ int main( int argc, char** argv ) try { << cc::warn( "Will sleep for 60 seconds before downloading 0 snapshot" ); sleep( 60 ); - downloadAndProccessSnapshot( snapshotManager, chainParams, requireSnapshotMajority, - ipToDownloadSnapshotFrom, false ); + downloadAndProccessSnapshot( + snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); } } catch ( std::exception& ) { From 5b0a97f707f0dcdd89bc4b5e60df6dd683745cfc Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 21 May 2024 15:43:35 +0100 Subject: [PATCH 03/47] IS 968 remove cc logs --- skaled/main.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/skaled/main.cpp b/skaled/main.cpp index a08fd77a7..1a52b70e0 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -362,8 +362,7 @@ voteForSnapshotHash( try { listUrlsToDownload = snapshotHashAgent->getNodesToDownloadSnapshotFrom( blockNumber ); clog( VerbosityInfo, "voteForSnapshotHash" ) - << cc::notice( "Got urls to download snapshot from " ) - << cc::p( std::to_string( listUrlsToDownload.size() ) ) << cc::notice( " nodes " ); + << "Got urls to download snapshot from " << listUrlsToDownload.size() << " nodes "; if ( listUrlsToDownload.size() == 0 ) return { listUrlsToDownload, votedHash }; @@ -387,16 +386,17 @@ bool checkLocalSnapshot( std::shared_ptr< SnapshotManager >& snapshotManager, un dev::h256 calculated_hash = snapshotManager->getSnapshotHash( blockNumber ); if ( calculated_hash == votedHash ) { - clog( VerbosityInfo, "checkLocalSnapshot" ) << cc::notice( - "Will delete all snapshots except" + std::to_string( blockNumber ) ); + clog( VerbosityInfo, "checkLocalSnapshot" ) + << std::string( "Will delete all snapshots except " ) + << std::to_string( blockNumber ); snapshotManager->cleanupButKeepSnapshot( blockNumber ); snapshotManager->restoreSnapshot( blockNumber ); - std::cout << cc::success( "Snapshot restore success for block " ) - << cc::u( to_string( blockNumber ) ) << std::endl; + clog( VerbosityInfo, "checkLocalSnapshot" ) + << "Snapshot restore success for block " << std::to_string( blockNumber ); return true; } else { clog( VerbosityWarning, "checkLocalSnapshot" ) - << cc::warn( "Snapshot is present locally but its hash is different" ); + << "Snapshot is present locally but its hash is different"; } } // if present } catch ( const std::exception& ex ) { @@ -412,7 +412,7 @@ bool tryDownloadSnapshot( std::shared_ptr< SnapshotManager >& snapshotManager, const std::pair< dev::h256, libff::alt_bn128_G1 >& votedHash, unsigned blockNumber, bool isRegularSnapshot ) { clog( VerbosityInfo, "tryDownloadSnapshot" ) - << cc::notice( "Will cleanup data dir and snapshots dir if needed" ); + << "Will cleanup data dir and snapshots dir if needed"; if ( isRegularSnapshot ) snapshotManager->cleanup(); @@ -445,8 +445,8 @@ bool tryDownloadSnapshot( std::shared_ptr< SnapshotManager >& snapshotManager, successfullDownload = true; if ( isRegularSnapshot ) { snapshotManager->restoreSnapshot( blockNumber ); - std::cout << "Snapshot restore success for block " << to_string( blockNumber ) - << std::endl; + clog( VerbosityInfo, "tryDownloadSnapshot" ) + << "Snapshot restore success for block " << to_string( blockNumber ); } return successfullDownload; } else { @@ -486,7 +486,7 @@ bool downloadSnapshotFromUrl( std::shared_ptr< SnapshotManager >& snapshotManage if ( !isRegularSnapshot ) return true; clog( VerbosityWarning, "downloadAndProccessSnapshot" ) - << std::string( "No nodes to download from - will skip " ) << urlToDownloadSnapshotFrom; + << "No nodes to download from - will skip " << urlToDownloadSnapshotFrom; return false; } @@ -526,8 +526,8 @@ void downloadAndProccessSnapshot( std::shared_ptr< SnapshotManager >& snapshotMa arrayCommonPublicKey, nodeUrl, isRegularSnapshot ); } catch ( std::exception& ex ) { clog( VerbosityWarning, "downloadAndProccessSnapshot" ) - << cc::warn( "Exception while trying to set up snapshot: " ) - << cc::warn( dev::nested_exception_what( ex ) ); + << "Exception while trying to set up snapshot: " + << dev::nested_exception_what( ex ); } // for blockNumber_url } @@ -1645,7 +1645,7 @@ int main( int argc, char** argv ) try { } catch ( SnapshotManager::SnapshotAbsent& ex ) { // sleep before send skale_getSnapshot again - will receive error clog( VerbosityInfo, "main" ) - << cc::warn( "Will sleep for 60 seconds before downloading 0 snapshot" ); + << std::string( "Will sleep for 60 seconds before downloading 0 snapshot" ); sleep( 60 ); downloadAndProccessSnapshot( @@ -1654,7 +1654,7 @@ int main( int argc, char** argv ) try { } catch ( std::exception& ) { std::throw_with_nested( std::runtime_error( - cc::error( " Fatal error in downloadAndProccessSnapshot! Will exit " ) ) ); + std::string( " Fatal error in downloadAndProccessSnapshot! Will exit " ) ) ); } } // if --download-snapshot From 88e6ef32cc0691bf9eca46b9def783b6a776accb Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 21 May 2024 15:56:30 +0100 Subject: [PATCH 04/47] IS 968 change ipToDownloadSnapshotFrom to url --- libskale/SnapshotHashAgent.cpp | 63 +++++++++++++--------------------- libskale/SnapshotHashAgent.h | 4 +-- 2 files changed, 26 insertions(+), 41 deletions(-) diff --git a/libskale/SnapshotHashAgent.cpp b/libskale/SnapshotHashAgent.cpp index c8c84d4e1..e9d116e89 100644 --- a/libskale/SnapshotHashAgent.cpp +++ b/libskale/SnapshotHashAgent.cpp @@ -35,10 +35,10 @@ SnapshotHashAgent::SnapshotHashAgent( const dev::eth::ChainParams& chainParams, const std::array< std::string, 4 >& common_public_key, - const std::string& ipToDownloadSnapshotFrom ) + const std::string& urlToDownloadSnapshotFrom ) : chainParams_( chainParams ), n_( chainParams.sChain.nodes.size() ), - ipToDownloadSnapshotFrom_( ipToDownloadSnapshotFrom ) { + urlToDownloadSnapshotFrom_( urlToDownloadSnapshotFrom ) { this->hashes_.resize( n_ ); this->signatures_.resize( n_ ); this->public_keys_.resize( n_ ); @@ -107,7 +107,7 @@ size_t SnapshotHashAgent::verifyAllData() const { bool SnapshotHashAgent::voteForHash() { std::map< dev::h256, size_t > map_hash; - if ( 3 * this->verifyAllData() < 2 * this->n_ + 1 && ipToDownloadSnapshotFrom_.empty() ) { + if ( 3 * this->verifyAllData() < 2 * this->n_ + 1 && urlToDownloadSnapshotFrom_.empty() ) { return false; } @@ -122,7 +122,7 @@ bool SnapshotHashAgent::voteForHash() { } std::map< dev::h256, size_t >::iterator it; - if ( ipToDownloadSnapshotFrom_.empty() ) { + if ( urlToDownloadSnapshotFrom_.empty() ) { it = std::find_if( map_hash.begin(), map_hash.end(), [this]( const std::pair< dev::h256, size_t > p ) { return 3 * p.second > 2 * this->n_; @@ -154,13 +154,11 @@ bool SnapshotHashAgent::voteForHash() { libBLS::ThresholdUtils::LagrangeCoeffs( idx, ( 2 * this->n_ + 1 ) / 3 ); common_signature = this->bls_->SignatureRecover( signatures, lagrange_coeffs ); } catch ( libBLS::ThresholdUtils::IncorrectInput& ex ) { - cerror << cc::error( - "Exception while recovering common signature from other skaleds: " ) - << cc::warn( ex.what() ) << std::endl; + cerror << "Exception while recovering common signature from other skaleds: " + << ex.what(); } catch ( libBLS::ThresholdUtils::IsNotWellFormed& ex ) { - cerror << cc::error( - "Exception while recovering common signature from other skaleds: " ) - << cc::warn( ex.what() ) << std::endl; + cerror << "Exception while recovering common signature from other skaleds: " + << ex.what(); } bool is_verified = false; @@ -171,17 +169,14 @@ bool SnapshotHashAgent::voteForHash() { std::make_shared< std::array< uint8_t, 32 > >( ( *it ).first.asArray() ), common_signature, this->common_public_key_ ); } catch ( libBLS::ThresholdUtils::IsNotWellFormed& ex ) { - cerror << cc::error( - "Exception while verifying common signature from other skaleds: " ) - << cc::warn( ex.what() ) << std::endl; + cerror << "Exception while verifying common signature from other skaleds: " + << ex.what(); } if ( !is_verified ) { - cerror << cc::error( - "Common BLS signature wasn't verified, probably using incorrect " - "common public key specified in command line. Trying again with " - "common public key from config" ) - << std::endl; + cerror << "Common BLS signature wasn't verified, probably using incorrect " + "common public key specified in command line. Trying again with " + "common public key from config"; libff::alt_bn128_G2 common_public_key_from_config; common_public_key_from_config.X.c0 = libff::alt_bn128_Fq( @@ -200,23 +195,17 @@ bool SnapshotHashAgent::voteForHash() { std::make_shared< std::array< uint8_t, 32 > >( ( *it ).first.asArray() ), common_signature, common_public_key_from_config ); } catch ( libBLS::ThresholdUtils::IsNotWellFormed& ex ) { - cerror - << cc::error( - "Exception while verifying common signature from other skaleds: " ) - << cc::warn( ex.what() ) << std::endl; + cerror << "Exception while verifying common signature from other skaleds: " + << ex.what(); } if ( !is_verified ) { - cerror << cc::error( - "Common BLS signature wasn't verified, snapshot will not be " - "downloaded. Try to backup node manually using skale-node-cli." ) - << std::endl; + cerror << "Common BLS signature wasn't verified, snapshot will not be " + "downloaded. Try to backup node manually using skale-node-cli."; return false; } else { - cnote << cc::info( - "Common BLS signature was verified with common public key " - "from config." ) - << std::endl; + cnote << "Common BLS signature was verified with common public key " + "from config."; this->common_public_key_ = common_public_key_from_config; } } @@ -230,7 +219,7 @@ bool SnapshotHashAgent::voteForHash() { size_t nodeIdx = std::distance( this->chainParams_.sChain.nodes.begin(), std::find_if( this->chainParams_.sChain.nodes.begin(), this->chainParams_.sChain.nodes.end(), [this]( const dev::eth::sChainNode& node ) { - return node.ip == ipToDownloadSnapshotFrom_; + return node.ip.find( urlToDownloadSnapshotFrom_ ) != std::string::npos; } ) ); dev::h256 requiredHashValue = this->hashes_[nodeIdx]; @@ -321,10 +310,8 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( delete jsonRpcClient; } } catch ( std::exception& ex ) { - cerror - << cc::error( - "Exception while collecting snapshot signatures from other skaleds: " ) - << cc::warn( ex.what() ) << std::endl; + cerror << "Exception while collecting snapshot signatures from other skaleds: " + << ex.what(); } } ) ); } @@ -366,11 +353,9 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( try { result = this->voteForHash(); } catch ( SnapshotHashAgentException& ex ) { - cerror << cc::error( "Exception while voting for snapshot hash from other skaleds: " ) - << cc::warn( ex.what() ) << std::endl; + cerror << "Exception while voting for snapshot hash from other skaleds: " << ex.what(); } catch ( std::exception& ex ) { - cerror << cc::error( "Exception while voting for snapshot hash from other skaleds: " ) - << cc::warn( ex.what() ) << std::endl; + cerror << "Exception while voting for snapshot hash from other skaleds: " << ex.what(); } // catch if ( !result ) { diff --git a/libskale/SnapshotHashAgent.h b/libskale/SnapshotHashAgent.h index 7cfa0d452..f7437d8c2 100644 --- a/libskale/SnapshotHashAgent.h +++ b/libskale/SnapshotHashAgent.h @@ -67,7 +67,7 @@ class SnapshotHashAgent { public: SnapshotHashAgent( const dev::eth::ChainParams& chainParams, const std::array< std::string, 4 >& common_public_key, - const std::string& ipToDownloadSnapshotFrom ); + const std::string& urlToDownloadSnapshotFrom ); std::vector< std::string > getNodesToDownloadSnapshotFrom( unsigned block_number ); @@ -78,7 +78,7 @@ class SnapshotHashAgent { private: dev::eth::ChainParams chainParams_; unsigned n_; - std::string ipToDownloadSnapshotFrom_; + std::string urlToDownloadSnapshotFrom_; std::shared_ptr< libBLS::Bls > bls_; std::vector< dev::h256 > hashes_; From a56e073b8f678b08a872b3f591619c0e20a866a8 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 21 May 2024 18:02:50 +0100 Subject: [PATCH 05/47] IS 968 add core and archive volumes for snapshots --- libskale/SnapshotManager.cpp | 67 +++++++++++++++++++++--------------- libskale/SnapshotManager.h | 9 +++-- skaled/main.cpp | 9 ++--- 3 files changed, 50 insertions(+), 35 deletions(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index d36eadad0..b5f412e43 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -56,13 +56,19 @@ const std::string SnapshotManager::partialSnapshotHashFileName = "partial_snapsh // - not btrfs // - volumes don't exist SnapshotManager::SnapshotManager( const dev::eth::ChainParams& _chainParams, - const fs::path& _dataDir, const std::vector< std::string >& _volumes, - const std::string& _diffsDir ) + const fs::path& _dataDir, const std::vector< std::string >& _coreVolumes, + const std::vector< std::string >& _archiveVolumes, const std::string& _diffsDir ) : chainParams( _chainParams ) { - assert( _volumes.size() > 0 ); + assert( _coreVolumes.size() > 0 ); data_dir = _dataDir; - volumes = _volumes; + coreVolumes = _coreVolumes; + archiveVolumes = _archiveVolumes; + + allVolumes.resize( coreVolumes.size() + archiveVolumes.size() ); + allVolumes.insert( allVolumes.end(), coreVolumes.begin(), coreVolumes.end() ); + allVolumes.insert( allVolumes.end(), archiveVolumes.begin(), archiveVolumes.end() ); + snapshots_dir = data_dir / "snapshots"; if ( _diffsDir.empty() ) diffs_dir = data_dir / "diffs"; @@ -91,7 +97,7 @@ SnapshotManager::SnapshotManager( const dev::eth::ChainParams& _chainParams, std::throw_with_nested( CannotWrite( ex.path1() ) ); } // catch - for ( const auto& vol : _volumes ) + for ( const auto& vol : allVolumes ) try { // throw if it is present but is NOT btrfs if ( fs::exists( _dataDir / vol ) && 0 != btrfs.present( ( _dataDir / vol ).c_str() ) ) @@ -128,7 +134,7 @@ void SnapshotManager::doSnapshot( unsigned _blockNumber ) { } // catch int dummy_counter = 0; - for ( const string& vol : volumes ) { + for ( const string& vol : allVolumes ) { int res = btrfs.subvolume.snapshot_r( ( data_dir / vol ).c_str(), snapshot_dir.c_str() ); if ( res ) throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); @@ -150,7 +156,7 @@ void SnapshotManager::restoreSnapshot( unsigned _blockNumber ) { UnsafeRegion::lock ur_lock; int dummy_counter = 0; - for ( const string& vol : volumes ) { + for ( const string& vol : allVolumes ) { if ( fs::exists( data_dir / vol ) ) { if ( btrfs.subvolume._delete( ( data_dir / vol ).c_str() ) ) throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); @@ -169,7 +175,8 @@ void SnapshotManager::restoreSnapshot( unsigned _blockNumber ) { // - no such snapshots // - cannot read // - cannot create tmp file -boost::filesystem::path SnapshotManager::makeOrGetDiff( unsigned _toBlock ) { +// - archive/core node +boost::filesystem::path SnapshotManager::makeOrGetDiff( unsigned _toBlock, bool _forArchiveNode ) { fs::path path = getDiffPath( _toBlock ); try { @@ -185,8 +192,12 @@ boost::filesystem::path SnapshotManager::makeOrGetDiff( unsigned _toBlock ) { std::throw_with_nested( CannotRead( ex.path1() ) ); } + if ( _forArchiveNode && !chainParams.nodeInfo.archiveMode ) + throw std::runtime_error( "Cannot create diff for an archvie node from the core node." ); + stringstream volumes_cat; + std::vector< std::string > volumes = _forArchiveNode ? allVolumes : coreVolumes; for ( auto it = volumes.begin(); it != volumes.end(); ++it ) { const string& vol = *it; if ( it + 1 != volumes.end() ) @@ -257,7 +268,7 @@ void SnapshotManager::removeSnapshot( unsigned _blockNumber ) { int dummy_counter = 0; - for ( const auto& volume : this->volumes ) { + for ( const auto& volume : allVolumes ) { int res = btrfs.subvolume._delete( ( this->snapshots_dir / std::to_string( _blockNumber ) / volume ).string().c_str() ); @@ -335,7 +346,7 @@ void SnapshotManager::leaveNLastSnapshots( unsigned n ) { for ( const auto& p : numbers ) { if ( i++ > n ) { const fs::path& path = p.second; - for ( const string& v : this->volumes ) { + for ( const string& v : allVolumes ) { if ( btrfs.subvolume._delete( ( path / v ).c_str() ) ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); } @@ -487,7 +498,7 @@ void SnapshotManager::addLastPriceToHash( unsigned _blockNumber, secp256k1_sha25 dev::u256 last_price = 0; // manually open DB boost::filesystem::path prices_path = - this->snapshots_dir / std::to_string( _blockNumber ) / this->volumes[2]; + this->snapshots_dir / std::to_string( _blockNumber ) / coreVolumes[2]; if ( boost::filesystem::exists( prices_path ) ) { boost::filesystem::directory_iterator it( prices_path ), end; std::string last_price_str; @@ -630,17 +641,16 @@ void SnapshotManager::computeFileStorageHash( const boost::filesystem::path& _fi void SnapshotManager::computeAllVolumesHash( unsigned _blockNumber, secp256k1_sha256_t* ctx, bool is_checking ) const { - assert( this->volumes.size() != 0 ); + assert( allVolumes.size() != 0 ); // TODO XXX Remove volumes structure knowledge from here!! this->computeDatabaseHash( - this->snapshots_dir / std::to_string( _blockNumber ) / this->volumes[0] / "12041" / "state", + this->snapshots_dir / std::to_string( _blockNumber ) / coreVolumes[0] / "12041" / "state", ctx ); - boost::filesystem::path blocks_extras_path = this->snapshots_dir / - std::to_string( _blockNumber ) / this->volumes[0] / - "blocks_and_extras"; + boost::filesystem::path blocks_extras_path = + this->snapshots_dir / std::to_string( _blockNumber ) / coreVolumes[0] / "blocks_and_extras"; // few dbs boost::filesystem::directory_iterator directory_it( blocks_extras_path ), end; @@ -669,7 +679,7 @@ void SnapshotManager::computeAllVolumesHash( this->snapshots_dir / std::to_string( _blockNumber ) / "filestorage", ctx, is_checking ); // if have prices and blocks - if ( _blockNumber && this->volumes.size() > 3 ) { + if ( _blockNumber && allVolumes.size() > 3 ) { this->addLastPriceToHash( _blockNumber, ctx ); } @@ -700,11 +710,13 @@ void SnapshotManager::computeAllVolumesHash( } // historic dbs - this->computeDatabaseHash( this->snapshots_dir / std::to_string( _blockNumber ) / - this->volumes[4] / this->volumes[0] / "state", + this->computeDatabaseHash( + this->snapshots_dir / std::to_string( _blockNumber ) / archiveVolumes[0] / + dev::eth::BlockChain::getChainDirName( chainParams ) / "state", ctx ); - this->computeDatabaseHash( this->snapshots_dir / std::to_string( _blockNumber ) / - this->volumes[5] / this->volumes[0] / "state", + this->computeDatabaseHash( + this->snapshots_dir / std::to_string( _blockNumber ) / archiveVolumes[1] / + dev::eth::BlockChain::getChainDirName( chainParams ) / "state", ctx ); } } @@ -722,7 +734,7 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki int dummy_counter = 0; - for ( const auto& volume : this->volumes ) { + for ( const auto& volume : allVolumes ) { int res = btrfs.subvolume.property_set( ( this->snapshots_dir / std::to_string( _blockNumber ) / volume ).string().c_str(), "ro", "false" ); @@ -737,7 +749,7 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki this->computeAllVolumesHash( _blockNumber, &ctx, is_checking ); - for ( const auto& volume : this->volumes ) { + for ( const auto& volume : allVolumes ) { int res = btrfs.subvolume.property_set( ( this->snapshots_dir / std::to_string( _blockNumber ) / volume ).string().c_str(), "ro", "true" ); @@ -775,8 +787,8 @@ uint64_t SnapshotManager::getBlockTimestamp( unsigned _blockNumber ) const { fs::path db_dir = this->snapshots_dir / std::to_string( _blockNumber ); - int res = btrfs.subvolume.property_set( - ( db_dir / this->volumes[0] ).string().c_str(), "ro", "false" ); + int res = + btrfs.subvolume.property_set( ( db_dir / coreVolumes[0] ).string().c_str(), "ro", "false" ); if ( res != 0 ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); @@ -786,9 +798,8 @@ uint64_t SnapshotManager::getBlockTimestamp( unsigned _blockNumber ) const { dev::h256 hash = bc.numberHash( _blockNumber ); uint64_t timestamp = dev::eth::BlockHeader( bc.block( hash ) ).timestamp(); - - res = btrfs.subvolume.property_set( - ( db_dir / this->volumes[0] ).string().c_str(), "ro", "true" ); + res = + btrfs.subvolume.property_set( ( db_dir / coreVolumes[0] ).string().c_str(), "ro", "true" ); if ( res != 0 ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); diff --git a/libskale/SnapshotManager.h b/libskale/SnapshotManager.h index 2bae44766..02af00353 100644 --- a/libskale/SnapshotManager.h +++ b/libskale/SnapshotManager.h @@ -153,11 +153,12 @@ class SnapshotManager { public: SnapshotManager( const dev::eth::ChainParams& _chainParams, - const boost::filesystem::path& _dataDir, const std::vector< std::string >& _volumes, + const boost::filesystem::path& _dataDir, const std::vector< std::string >& _coreVolumes, + const std::vector< std::string >& _archiveVolumes = {}, const std::string& diffs_dir = std::string() ); void doSnapshot( unsigned _blockNumber ); void restoreSnapshot( unsigned _blockNumber ); - boost::filesystem::path makeOrGetDiff( unsigned _toBlock ); + boost::filesystem::path makeOrGetDiff( unsigned _toBlock, bool _forArchiveNode = false ); void importDiff( unsigned _toBlock ); boost::filesystem::path getDiffPath( unsigned _toBlock ); void removeSnapshot( unsigned _blockNumber ); @@ -179,7 +180,9 @@ class SnapshotManager { private: boost::filesystem::path data_dir; - std::vector< std::string > volumes; + std::vector< std::string > coreVolumes; + std::vector< std::string > archiveVolumes; + std::vector< std::string > allVolumes; boost::filesystem::path snapshots_dir; boost::filesystem::path diffs_dir; diff --git a/skaled/main.cpp b/skaled/main.cpp index 1a52b70e0..5308ed429 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1595,13 +1595,14 @@ int main( int argc, char** argv ) try { } if ( chainParams.sChain.snapshotIntervalSec > 0 || downloadSnapshotFlag ) { - std::vector< std::string > volumes = { BlockChain::getChainDirName( chainParams ), + std::vector< std::string > coreVolumes = { BlockChain::getChainDirName( chainParams ), "filestorage", "prices_" + chainParams.nodeInfo.id.str() + ".db", "blocks_" + chainParams.nodeInfo.id.str() + ".db" }; + std::vector< std::string > archiveVolumes = {}; if ( chainParams.nodeInfo.archiveMode ) - volumes.insert( volumes.end(), { "historic_roots", "historic_state" } ); - snapshotManager.reset( new SnapshotManager( - chainParams, getDataDir(), volumes, sharedSpace ? sharedSpace->getPath() : "" ) ); + archiveVolumes.insert( archiveVolumes.end(), { "historic_roots", "historic_state" } ); + snapshotManager.reset( new SnapshotManager( chainParams, getDataDir(), coreVolumes, + archiveVolumes, sharedSpace ? sharedSpace->getPath() : "" ) ); } bool downloadGenesisForSyncNode = false; From ce791125275a50ba3d1e969d2bfa811e1bf64695 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 22 May 2024 13:44:22 +0100 Subject: [PATCH 06/47] IS 968 add archiveNodeSnapshotsPatch and tests --- libethereum/Client.h | 5 ++- libethereum/SchainPatch.cpp | 4 ++ libethereum/SchainPatch.h | 6 +++ libethereum/SchainPatchEnum.h | 1 + libethereum/SnapshotAgent.cpp | 6 ++- libethereum/SnapshotAgent.h | 3 +- libweb3jsonrpc/Skale.cpp | 17 ++++---- test/unittests/libskale/SnapshotManager.cpp | 43 +++++++++++++++++++++ 8 files changed, 70 insertions(+), 15 deletions(-) diff --git a/libethereum/Client.h b/libethereum/Client.h index dd5045285..83264c93f 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -293,8 +293,9 @@ class Client : public ClientBase, protected Worker { size_t importTransactionsAsBlock( const Transactions& _transactions, u256 _gasPrice, uint64_t _timestamp = ( uint64_t ) utcTime() ); - boost::filesystem::path createSnapshotFile( unsigned _blockNumber ) { - return m_snapshotAgent->createSnapshotFile( _blockNumber ); + boost::filesystem::path createSnapshotFile( + unsigned _blockNumber, bool _forArchiveNode = false ) { + return m_snapshotAgent->createSnapshotFile( _blockNumber, _forArchiveNode ); } // set exiting time for node rotation diff --git a/libethereum/SchainPatch.cpp b/libethereum/SchainPatch.cpp index f3a5f8daa..7f4a9037c 100644 --- a/libethereum/SchainPatch.cpp +++ b/libethereum/SchainPatch.cpp @@ -36,6 +36,8 @@ SchainPatchEnum getEnumForPatchName( const std::string& _patchName ) { return SchainPatchEnum::VerifyBlsSyncPatch; else if ( _patchName == "FlexibleDeploymentPatch" ) return SchainPatchEnum::FlexibleDeploymentPatch; + else if ( _patchName == "ArchiveNodeSnapshotsPatch" ) + return SchainPatchEnum::ArchiveNodeSnapshotsPatch; else throw std::out_of_range( _patchName ); } @@ -72,6 +74,8 @@ std::string getPatchNameForEnum( SchainPatchEnum _enumValue ) { return "VerifyBlsSyncPatch"; case SchainPatchEnum::FlexibleDeploymentPatch: return "FlexibleDeploymentPatch"; + case SchainPatchEnum::ArchiveNodeSnapshotsPatch: + return "ArchiveNodeSnapshotsPatch"; default: throw std::out_of_range( "UnknownPatch #" + std::to_string( static_cast< size_t >( _enumValue ) ) ); diff --git a/libethereum/SchainPatch.h b/libethereum/SchainPatch.h index 9af149fb9..476a21aed 100644 --- a/libethereum/SchainPatch.h +++ b/libethereum/SchainPatch.h @@ -146,4 +146,10 @@ DEFINE_AMNESIC_PATCH( VerifyBlsSyncPatch ); */ DEFINE_SIMPLE_PATCH( FlexibleDeploymentPatch ); +/* + * Purpose: introduce snapshot downloading for archive nodes + * Version introduced: 3.20.0 + */ +DEFINE_AMNESIC_PATCH( ArchiveNodeSnapshotsPatch ); + #endif // SCHAINPATCH_H diff --git a/libethereum/SchainPatchEnum.h b/libethereum/SchainPatchEnum.h index ac0b1c19a..e708fdc23 100644 --- a/libethereum/SchainPatchEnum.h +++ b/libethereum/SchainPatchEnum.h @@ -20,6 +20,7 @@ enum class SchainPatchEnum { EIP1559TransactionsPatch, VerifyBlsSyncPatch, FlexibleDeploymentPatch, + ArchiveNodeSnapshotsPatch, PatchesCount }; diff --git a/libethereum/SnapshotAgent.cpp b/libethereum/SnapshotAgent.cpp index 4998208b6..19bd43ccc 100644 --- a/libethereum/SnapshotAgent.cpp +++ b/libethereum/SnapshotAgent.cpp @@ -137,10 +137,12 @@ void SnapshotAgent::doSnapshotIfNeeded( unsigned _currentBlockNumber, int64_t _t } // if thread } -boost::filesystem::path SnapshotAgent::createSnapshotFile( unsigned _blockNumber ) { +boost::filesystem::path SnapshotAgent::createSnapshotFile( + unsigned _blockNumber, bool _forArchiveNode ) { if ( _blockNumber > this->getLatestSnapshotBlockNumer() && _blockNumber != 0 ) throw std::invalid_argument( "Too new snapshot requested" ); - boost::filesystem::path path = m_snapshotManager->makeOrGetDiff( _blockNumber ); + boost::filesystem::path path = + m_snapshotManager->makeOrGetDiff( _blockNumber, _forArchiveNode ); // TODO Make constant 2 configurable m_snapshotManager->leaveNLastDiffs( 2 ); return path; diff --git a/libethereum/SnapshotAgent.h b/libethereum/SnapshotAgent.h index 79e46b6e4..e9914cb3f 100644 --- a/libethereum/SnapshotAgent.h +++ b/libethereum/SnapshotAgent.h @@ -26,7 +26,8 @@ class SnapshotAgent { void finishHashComputingAndUpdateHashesIfNeeded( int64_t _timestamp ); void doSnapshotIfNeeded( unsigned _currentBlockNumber, int64_t _timestamp ); - boost::filesystem::path createSnapshotFile( unsigned _blockNumber ); + boost::filesystem::path createSnapshotFile( + unsigned _blockNumber, bool _forArchiveNode = false ); void terminate(); diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index 9cb807327..f47eb17bc 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -40,10 +41,8 @@ #include -//#include #include -//#include #include #include @@ -150,9 +149,6 @@ size_t g_nMaxChunckSize = 100 * 1024 * 1024; // '{"jsonrpc":"2.0","method":"skale_getSnapshot","params":{ "blockNumber": "latest" },"id":73}' // nlohmann::json Skale::impl_skale_getSnapshot( const nlohmann::json& joRequest, Client& client ) { - // std::cout << cc::attention( "------------ " ) << cc::info( "skale_getSnapshot" ) << - // cc::normal( " call with " ) << cc::j( joRequest ) << "\n"; - std::lock_guard< std::mutex > lock( m_snapshot_mutex ); nlohmann::json joResponse = nlohmann::json::object(); @@ -163,6 +159,10 @@ nlohmann::json Skale::impl_skale_getSnapshot( const nlohmann::json& joRequest, C return joResponse; } + bool forArchiveNode = false; + if ( ArchiveNodeSnapshotsPatch::isEnabledInWorkingBlock() ) + forArchiveNode = joRequest["forArchiveNode"].get< bool >(); + // exit if too early if ( currentSnapshotBlockNumber >= 0 ) { joResponse["error"] = @@ -194,7 +194,7 @@ nlohmann::json Skale::impl_skale_getSnapshot( const nlohmann::json& joRequest, C } try { - currentSnapshotPath = client.createSnapshotFile( blockNumber ); + currentSnapshotPath = client.createSnapshotFile( blockNumber, forArchiveNode ); } catch ( ... ) { if ( m_shared_space ) m_shared_space->unlock(); @@ -235,11 +235,8 @@ nlohmann::json Skale::impl_skale_getSnapshot( const nlohmann::json& joRequest, C } ) ); } - // - // size_t sizeOfFile = fs::file_size( currentSnapshotPath ); - // - // + joResponse["dataSize"] = sizeOfFile; joResponse["maxAllowedChunkSize"] = g_nMaxChunckSize; return joResponse; diff --git a/test/unittests/libskale/SnapshotManager.cpp b/test/unittests/libskale/SnapshotManager.cpp index a50951bf0..b0cfc046f 100644 --- a/test/unittests/libskale/SnapshotManager.cpp +++ b/test/unittests/libskale/SnapshotManager.cpp @@ -486,4 +486,47 @@ BOOST_FIXTURE_TEST_CASE( CleanupTest, BtrfsFixture, BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol2" ) ); } +BOOST_FIXTURE_TEST_CASE( ArchiveNodeTest, BtrfsFixture, + *boost::unit_test::precondition( dev::test::run_not_express ) ) { + auto chainParams = dev::eth::ChainParams(); + chainParams.nodeInfo.archiveMode = true; + SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"}, {"vol3", "vol4"} ); + + // add files to core volumes + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d11" ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol2" / "d21" ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol2" / "d21" ) ); + // archive part + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol3" / "d31" ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol4" / "d41" ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol3" / "d31" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol4" / "d41" ) ); + + // create snapshot 1 and check its presense + mgr.doSnapshot( 1 ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol1" / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol2" / "d21" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol3" / "d31" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol4" / "d41" ) ); + + // make diff for archive node + BOOST_REQUIRE_NO_THROW( mgr.makeOrGetDiff( 1, true ) ); + + // delete dest + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol1" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol2" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol3" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol4" ).c_str() ); + fs::remove_all( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" ); + + BOOST_REQUIRE_NO_THROW( mgr.importDiff( 1 ) ); +// mgr.importDiff( 1 ); + + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol1" / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol2" / "d21" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol3" / "d31" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol4" / "d41" ) ); +} + BOOST_AUTO_TEST_SUITE_END() From 879e3c583b1dd3ff77167f99765116b8b942cde7 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 22 May 2024 16:01:25 +0100 Subject: [PATCH 07/47] IS 968 add tests --- libskale/SnapshotHashAgent.cpp | 2 +- libskale/SnapshotManager.cpp | 2 +- test/unittests/libskale/HashSnapshot.cpp | 13 +++++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/libskale/SnapshotHashAgent.cpp b/libskale/SnapshotHashAgent.cpp index e9d116e89..9b7812287 100644 --- a/libskale/SnapshotHashAgent.cpp +++ b/libskale/SnapshotHashAgent.cpp @@ -219,7 +219,7 @@ bool SnapshotHashAgent::voteForHash() { size_t nodeIdx = std::distance( this->chainParams_.sChain.nodes.begin(), std::find_if( this->chainParams_.sChain.nodes.begin(), this->chainParams_.sChain.nodes.end(), [this]( const dev::eth::sChainNode& node ) { - return node.ip.find( urlToDownloadSnapshotFrom_ ) != std::string::npos; + return urlToDownloadSnapshotFrom_.find( node.ip ) != std::string::npos; } ) ); dev::h256 requiredHashValue = this->hashes_[nodeIdx]; diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index b5f412e43..3515c2789 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -65,7 +65,7 @@ SnapshotManager::SnapshotManager( const dev::eth::ChainParams& _chainParams, coreVolumes = _coreVolumes; archiveVolumes = _archiveVolumes; - allVolumes.resize( coreVolumes.size() + archiveVolumes.size() ); + allVolumes.reserve( coreVolumes.size() + archiveVolumes.size() ); allVolumes.insert( allVolumes.end(), coreVolumes.begin(), coreVolumes.end() ); allVolumes.insert( allVolumes.end(), archiveVolumes.begin(), archiveVolumes.end() ); diff --git a/test/unittests/libskale/HashSnapshot.cpp b/test/unittests/libskale/HashSnapshot.cpp index 79bb20d7d..2a4449185 100644 --- a/test/unittests/libskale/HashSnapshot.cpp +++ b/test/unittests/libskale/HashSnapshot.cpp @@ -40,7 +40,7 @@ namespace dev { namespace test { class SnapshotHashAgentTest { public: - SnapshotHashAgentTest( ChainParams& _chainParams, const std::string& ipToDownloadSnapshotFrom ) { + SnapshotHashAgentTest( ChainParams& _chainParams, const std::string& urlToDownloadSnapshotFrom ) { std::vector< libff::alt_bn128_Fr > coeffs( _chainParams.sChain.t ); for ( auto& elem : coeffs ) { @@ -84,9 +84,9 @@ class SnapshotHashAgentTest { this->secret_as_is = keys.first; - isSnapshotMajorityRequired = !ipToDownloadSnapshotFrom.empty(); + isSnapshotMajorityRequired = !urlToDownloadSnapshotFrom.empty(); - this->hashAgent_.reset( new SnapshotHashAgent( _chainParams, _chainParams.nodeInfo.commonBLSPublicKeys, ipToDownloadSnapshotFrom ) ); + this->hashAgent_.reset( new SnapshotHashAgent( _chainParams, _chainParams.nodeInfo.commonBLSPublicKeys, urlToDownloadSnapshotFrom ) ); } void fillData( const std::vector< dev::h256 >& snapshot_hashes ) { @@ -510,9 +510,14 @@ BOOST_AUTO_TEST_CASE( noSnapshotMajority ) { } chainParams.nodeInfo.id = 3; + chainParams.sChain.nodes[0].ip = "123.45.68.89"; + chainParams.sChain.nodes[1].ip = "123.45.87.89"; + chainParams.sChain.nodes[2].ip = "123.45.77.89"; + chainParams.sChain.nodes[3].ip = "123.45.67.89"; + std::string url = chainParams.sChain.nodes[3].ip + std::string( ":1234" ); - SnapshotHashAgentTest test_agent( chainParams, chainParams.sChain.nodes[3].ip ); + SnapshotHashAgentTest test_agent( chainParams, url ); dev::h256 hash = dev::h256::random(); std::vector< dev::h256 > snapshot_hashes( chainParams.sChain.nodes.size(), hash ); snapshot_hashes[2] = dev::h256::random(); From e6d78e5a7e89ae41a1839150985b1bce439a94c3 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 22 May 2024 17:18:08 +0100 Subject: [PATCH 08/47] fix tests --- .github/workflows/test.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ca1114248..b215b7526 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -169,8 +169,8 @@ jobs: sudo rm -rf /tmp/tests/* cd build/test export NO_NTP_CHECK=1 - export NO_ULIMIT_CHECK=1 - function run_test() { ./testeth --report_level=detailed -t "$1" -- --express && touch "/tmp/tests/${1}Passed"; } + export NO_ULIMIT_CHECK=1 + function run_test() { NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth --report_level=detailed -t "$1" -- --express && touch "/tmp/tests/${1}Passed"; } run_test TransitionTests run_test TransactionTests run_test VMTests @@ -211,9 +211,9 @@ jobs: run_test JsonRpcSuite run_test SingleConsensusTests run_test ConsensusTests - sudo ./testeth -t BtrfsTestSuite -- --all && touch /tmp/tests/BtrfsTestSuitePassed - sudo ./testeth -t HashSnapshotTestSuite -- --all && touch /tmp/tests/HashSnapshotTestSuitePassed - sudo ./testeth -t ClientSnapshotsSuite -- --all && touch /tmp/tests/ClientSnapshotsSuitePassed + sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t BtrfsTestSuite -- --all && touch /tmp/tests/BtrfsTestSuitePassed + sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t HashSnapshotTestSuite -- --all && touch /tmp/tests/HashSnapshotTestSuitePassed + sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all && touch /tmp/tests/ClientSnapshotsSuitePassed cd .. - name: Testeth verbosity 4 run : | @@ -221,7 +221,7 @@ jobs: cd build/test export NO_NTP_CHECK=1 export NO_ULIMIT_CHECK=1 - function rerun_test() { ls "/tmp/tests/${1}Passed" 2>/dev/null || ./testeth --report_level=detailed -t "$1" -- --express --verbosity 4; } + function rerun_test() { ls "/tmp/tests/${1}Passed" 2>/dev/null || NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth --report_level=detailed -t "$1" -- --express --verbosity 4; } rerun_test TransitionTests rerun_test TransactionTests rerun_test VMTests From e97a74b433e476a283546ac3242e793be7013ee5 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 22 May 2024 17:52:04 +0100 Subject: [PATCH 09/47] fix tests --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b215b7526..98f92a5ba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -170,7 +170,7 @@ jobs: cd build/test export NO_NTP_CHECK=1 export NO_ULIMIT_CHECK=1 - function run_test() { NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth --report_level=detailed -t "$1" -- --express && touch "/tmp/tests/${1}Passed"; } + function run_test() { ./testeth --report_level=detailed -t "$1" -- --express && touch "/tmp/tests/${1}Passed"; } run_test TransitionTests run_test TransactionTests run_test VMTests @@ -221,7 +221,7 @@ jobs: cd build/test export NO_NTP_CHECK=1 export NO_ULIMIT_CHECK=1 - function rerun_test() { ls "/tmp/tests/${1}Passed" 2>/dev/null || NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth --report_level=detailed -t "$1" -- --express --verbosity 4; } + function rerun_test() { ls "/tmp/tests/${1}Passed" 2>/dev/null || ./testeth --report_level=detailed -t "$1" -- --express --verbosity 4; } rerun_test TransitionTests rerun_test TransactionTests rerun_test VMTests From 9fd6db81118ee88ea53103641b7204ea2c4b40d4 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 22 May 2024 17:56:01 +0100 Subject: [PATCH 10/47] fix tests --- test/unittests/libethereum/ClientTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unittests/libethereum/ClientTest.cpp b/test/unittests/libethereum/ClientTest.cpp index ed9bdb878..9cc2e0b93 100644 --- a/test/unittests/libethereum/ClientTest.cpp +++ b/test/unittests/libethereum/ClientTest.cpp @@ -39,7 +39,7 @@ using namespace dev::test; using namespace dev::p2p; namespace fs = boost::filesystem; -static size_t rand_port = 1024 + rand() % 64000; +static size_t rand_port = ( srand(time(nullptr)), 1024 + rand() % 64000 ); struct FixtureCommon { const string BTRFS_FILE_PATH = "btrfs.file"; From 4a5b2f82967687ccb87a7e81c50bdfe767ac4e69 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Thu, 23 May 2024 17:43:37 +0100 Subject: [PATCH 11/47] IS 968 update functional tests --- .github/workflows/functional-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index f7356fc36..26229774f 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -24,7 +24,7 @@ with: token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} repository: skalenetwork/skale-ci-integration_tests - ref: master + ref: v3.20.0 submodules: recursive - name: Set up Node uses: actions/setup-node@v3.4.0 From 76136f15501f96abcced4c343c1436364afc09b6 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 29 May 2024 17:44:05 +0100 Subject: [PATCH 12/47] IS-968 fix downloading from archive to core --- libskale/SnapshotHashAgent.cpp | 230 ++++++++++++----------- libskale/SnapshotHashAgent.h | 14 +- libskale/SnapshotManager.cpp | 50 +++-- libweb3jsonrpc/Skale.cpp | 214 +++++++++++---------- skaled/main.cpp | 6 +- test/unittests/libskale/HashSnapshot.cpp | 4 +- 6 files changed, 282 insertions(+), 236 deletions(-) diff --git a/libskale/SnapshotHashAgent.cpp b/libskale/SnapshotHashAgent.cpp index 9b7812287..15d96bffe 100644 --- a/libskale/SnapshotHashAgent.cpp +++ b/libskale/SnapshotHashAgent.cpp @@ -42,35 +42,35 @@ SnapshotHashAgent::SnapshotHashAgent( const dev::eth::ChainParams& chainParams, this->hashes_.resize( n_ ); this->signatures_.resize( n_ ); this->public_keys_.resize( n_ ); - this->is_received_.resize( n_ ); + this->isReceived_.resize( n_ ); for ( size_t i = 0; i < n_; ++i ) { - this->is_received_[i] = false; + this->isReceived_[i] = false; } this->bls_.reset( new libBLS::Bls( ( 2 * this->n_ + 1 ) / 3, this->n_ ) ); - common_public_key_.X.c0 = libff::alt_bn128_Fq( common_public_key[0].c_str() ); - common_public_key_.X.c1 = libff::alt_bn128_Fq( common_public_key[1].c_str() ); - common_public_key_.Y.c0 = libff::alt_bn128_Fq( common_public_key[2].c_str() ); - common_public_key_.Y.c1 = libff::alt_bn128_Fq( common_public_key[3].c_str() ); - common_public_key_.Z = libff::alt_bn128_Fq2::one(); - if ( ( common_public_key_.X == libff::alt_bn128_Fq2::zero() && - common_public_key_.Y == libff::alt_bn128_Fq2::one() ) || - !common_public_key_.is_well_formed() ) { + commonPublicKey_.X.c0 = libff::alt_bn128_Fq( common_public_key[0].c_str() ); + commonPublicKey_.X.c1 = libff::alt_bn128_Fq( common_public_key[1].c_str() ); + commonPublicKey_.Y.c0 = libff::alt_bn128_Fq( common_public_key[2].c_str() ); + commonPublicKey_.Y.c1 = libff::alt_bn128_Fq( common_public_key[3].c_str() ); + commonPublicKey_.Z = libff::alt_bn128_Fq2::one(); + if ( ( commonPublicKey_.X == libff::alt_bn128_Fq2::zero() && + commonPublicKey_.Y == libff::alt_bn128_Fq2::one() ) || + !commonPublicKey_.is_well_formed() ) { // zero or corrupted public key was provided in command line this->readPublicKeyFromConfig(); } } void SnapshotHashAgent::readPublicKeyFromConfig() { - this->common_public_key_.X.c0 = + this->commonPublicKey_.X.c0 = libff::alt_bn128_Fq( chainParams_.nodeInfo.commonBLSPublicKeys[0].c_str() ); - this->common_public_key_.X.c1 = + this->commonPublicKey_.X.c1 = libff::alt_bn128_Fq( chainParams_.nodeInfo.commonBLSPublicKeys[1].c_str() ); - this->common_public_key_.Y.c0 = + this->commonPublicKey_.Y.c0 = libff::alt_bn128_Fq( chainParams_.nodeInfo.commonBLSPublicKeys[2].c_str() ); - this->common_public_key_.Y.c1 = + this->commonPublicKey_.Y.c1 = libff::alt_bn128_Fq( chainParams_.nodeInfo.commonBLSPublicKeys[3].c_str() ); - this->common_public_key_.Z = libff::alt_bn128_Fq2::one(); + this->commonPublicKey_.Z = libff::alt_bn128_Fq2::one(); } size_t SnapshotHashAgent::verifyAllData() const { @@ -80,7 +80,7 @@ size_t SnapshotHashAgent::verifyAllData() const { continue; } - if ( this->is_received_[i] ) { + if ( this->isReceived_[i] ) { bool is_verified = false; libff::inhibit_profiling_info = true; try { @@ -111,7 +111,7 @@ bool SnapshotHashAgent::voteForHash() { return false; } - const std::lock_guard< std::mutex > lock( this->hashes_mutex ); + const std::lock_guard< std::mutex > lock( this->hashesMutex ); for ( size_t i = 0; i < this->n_; ++i ) { if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { @@ -141,7 +141,7 @@ bool SnapshotHashAgent::voteForHash() { } if ( this->hashes_[i] == ( *it ).first ) { - this->nodes_to_download_snapshot_from_.push_back( i ); + this->nodesToDownloadSnapshotFrom_.push_back( i ); idx.push_back( i + 1 ); signatures.push_back( this->signatures_[i] ); } @@ -167,7 +167,7 @@ bool SnapshotHashAgent::voteForHash() { libff::inhibit_profiling_info = true; is_verified = this->bls_->Verification( std::make_shared< std::array< uint8_t, 32 > >( ( *it ).first.asArray() ), - common_signature, this->common_public_key_ ); + common_signature, this->commonPublicKey_ ); } catch ( libBLS::ThresholdUtils::IsNotWellFormed& ex ) { cerror << "Exception while verifying common signature from other skaleds: " << ex.what(); @@ -178,22 +178,22 @@ bool SnapshotHashAgent::voteForHash() { "common public key specified in command line. Trying again with " "common public key from config"; - libff::alt_bn128_G2 common_public_key_from_config; - common_public_key_from_config.X.c0 = libff::alt_bn128_Fq( + libff::alt_bn128_G2 commonPublicKey_from_config; + commonPublicKey_from_config.X.c0 = libff::alt_bn128_Fq( this->chainParams_.nodeInfo.commonBLSPublicKeys[0].c_str() ); - common_public_key_from_config.X.c1 = libff::alt_bn128_Fq( + commonPublicKey_from_config.X.c1 = libff::alt_bn128_Fq( this->chainParams_.nodeInfo.commonBLSPublicKeys[1].c_str() ); - common_public_key_from_config.Y.c0 = libff::alt_bn128_Fq( + commonPublicKey_from_config.Y.c0 = libff::alt_bn128_Fq( this->chainParams_.nodeInfo.commonBLSPublicKeys[2].c_str() ); - common_public_key_from_config.Y.c1 = libff::alt_bn128_Fq( + commonPublicKey_from_config.Y.c1 = libff::alt_bn128_Fq( this->chainParams_.nodeInfo.commonBLSPublicKeys[3].c_str() ); - common_public_key_from_config.Z = libff::alt_bn128_Fq2::one(); + commonPublicKey_from_config.Z = libff::alt_bn128_Fq2::one(); std::cout << "NEW BLS COMMON PUBLIC KEY:\n"; - common_public_key_from_config.print_coordinates(); + commonPublicKey_from_config.print_coordinates(); try { is_verified = this->bls_->Verification( std::make_shared< std::array< uint8_t, 32 > >( ( *it ).first.asArray() ), - common_signature, common_public_key_from_config ); + common_signature, commonPublicKey_from_config ); } catch ( libBLS::ThresholdUtils::IsNotWellFormed& ex ) { cerror << "Exception while verifying common signature from other skaleds: " << ex.what(); @@ -206,7 +206,7 @@ bool SnapshotHashAgent::voteForHash() { } else { cnote << "Common BLS signature was verified with common public key " "from config."; - this->common_public_key_ = common_public_key_from_config; + this->commonPublicKey_ = commonPublicKey_from_config; } } @@ -232,92 +232,109 @@ bool SnapshotHashAgent::voteForHash() { this->voted_hash_.first = ( *it ).first; this->voted_hash_.second = this->signatures_[nodeIdx]; - this->nodes_to_download_snapshot_from_.push_back( nodeIdx ); + this->nodesToDownloadSnapshotFrom_.push_back( nodeIdx ); } return true; } +std::tuple< dev::h256, libff::alt_bn128_G1, libff::alt_bn128_G2 > SnapshotHashAgent::askNodeForHash( + const std::string& url, unsigned blockNumber ) { + jsonrpc::HttpClient* jsonRpcClient = new jsonrpc::HttpClient( url ); + SkaleClient skaleClient( *jsonRpcClient ); + + Json::Value joSignatureResponse; + try { + joSignatureResponse = skaleClient.skale_getSnapshotSignature( blockNumber ); + } catch ( jsonrpc::JsonRpcException& ex ) { + cerror << "WARNING " + << "Error while trying to get snapshot signature from " << url << " : " << ex.what(); + delete jsonRpcClient; + return {}; + } + + if ( !joSignatureResponse.get( "hash", 0 ) || !joSignatureResponse.get( "X", 0 ) || + !joSignatureResponse.get( "Y", 0 ) ) { + cerror << "WARNING " + << " Signature from " + url + + "-th node was not received during " + "getNodesToDownloadSnapshotFrom "; + delete jsonRpcClient; + + return {}; + } else { + std::string strHash = joSignatureResponse["hash"].asString(); + cnote << "Received snapshot hash from " << url << " : " << strHash << '\n'; + + libff::alt_bn128_G1 signature = + libff::alt_bn128_G1( libff::alt_bn128_Fq( joSignatureResponse["X"].asCString() ), + libff::alt_bn128_Fq( joSignatureResponse["Y"].asCString() ), + libff::alt_bn128_Fq::one() ); + + libff::alt_bn128_G2 publicKey; + if ( urlToDownloadSnapshotFrom_.empty() ) { + Json::Value joPublicKeyResponse = skaleClient.skale_imaInfo(); + + + publicKey.X.c0 = + libff::alt_bn128_Fq( joPublicKeyResponse["BLSPublicKey0"].asCString() ); + publicKey.X.c1 = + libff::alt_bn128_Fq( joPublicKeyResponse["BLSPublicKey1"].asCString() ); + publicKey.Y.c0 = + libff::alt_bn128_Fq( joPublicKeyResponse["BLSPublicKey2"].asCString() ); + publicKey.Y.c1 = + libff::alt_bn128_Fq( joPublicKeyResponse["BLSPublicKey3"].asCString() ); + publicKey.Z = libff::alt_bn128_Fq2::one(); + } else { + publicKey = libff::alt_bn128_G2::one(); + publicKey.to_affine_coordinates(); + } + + delete jsonRpcClient; + + return { dev::h256( strHash ), signature, publicKey }; + } +} + std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( - unsigned block_number ) { + unsigned blockNumber ) { libff::init_alt_bn128_params(); std::vector< std::thread > threads; - for ( size_t i = 0; i < this->n_; ++i ) { - if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { - continue; - } - - threads.push_back( std::thread( [this, i, block_number]() { - try { - jsonrpc::HttpClient* jsonRpcClient = new jsonrpc::HttpClient( - "http://" + this->chainParams_.sChain.nodes[i].ip + ':' + - ( this->chainParams_.sChain.nodes[i].port + 3 ).convert_to< std::string >() ); - SkaleClient skaleClient( *jsonRpcClient ); + if ( urlToDownloadSnapshotFrom_.empty() ) { + for ( size_t i = 0; i < this->n_; ++i ) { + if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { + continue; + } - Json::Value joSignatureResponse; + threads.push_back( std::thread( [this, i, blockNumber]() { try { - joSignatureResponse = skaleClient.skale_getSnapshotSignature( block_number ); - } catch ( jsonrpc::JsonRpcException& ex ) { - cerror << "WARNING " - << "Error while trying to get snapshot signature from " - << this->chainParams_.sChain.nodes[i].ip << " : " << ex.what(); - delete jsonRpcClient; - return; - } - - if ( !joSignatureResponse.get( "hash", 0 ) || !joSignatureResponse.get( "X", 0 ) || - !joSignatureResponse.get( "Y", 0 ) ) { - cerror << "WARNING " - << " Signature from " + std::to_string( i ) + - "-th node was not received during " - "getNodesToDownloadSnapshotFrom "; - delete jsonRpcClient; - } else { - const std::lock_guard< std::mutex > lock( this->hashes_mutex ); - - this->is_received_[i] = true; - - std::string str_hash = joSignatureResponse["hash"].asString(); - cnote << "Received snapshot hash from " - << "http://" + this->chainParams_.sChain.nodes[i].ip + ':' + - ( this->chainParams_.sChain.nodes[i].port + 3 ) - .convert_to< std::string >() - << " : " << str_hash << '\n'; - - libff::alt_bn128_G1 signature = libff::alt_bn128_G1( - libff::alt_bn128_Fq( joSignatureResponse["X"].asCString() ), - libff::alt_bn128_Fq( joSignatureResponse["Y"].asCString() ), - libff::alt_bn128_Fq::one() ); - - Json::Value joPublicKeyResponse = skaleClient.skale_imaInfo(); - - libff::alt_bn128_G2 public_key; - public_key.X.c0 = - libff::alt_bn128_Fq( joPublicKeyResponse["BLSPublicKey0"].asCString() ); - public_key.X.c1 = - libff::alt_bn128_Fq( joPublicKeyResponse["BLSPublicKey1"].asCString() ); - public_key.Y.c0 = - libff::alt_bn128_Fq( joPublicKeyResponse["BLSPublicKey2"].asCString() ); - public_key.Y.c1 = - libff::alt_bn128_Fq( joPublicKeyResponse["BLSPublicKey3"].asCString() ); - public_key.Z = libff::alt_bn128_Fq2::one(); - - this->hashes_[i] = dev::h256( str_hash ); - this->signatures_[i] = signature; - this->public_keys_[i] = public_key; - - delete jsonRpcClient; + std::string nodeUrl = + "http://" + this->chainParams_.sChain.nodes[i].ip + ':' + + ( this->chainParams_.sChain.nodes[i].port + 3 ).convert_to< std::string >(); + auto snapshotData = askNodeForHash( nodeUrl, blockNumber ); + if ( std::get< 0 >( snapshotData ).size ) { + const std::lock_guard< std::mutex > lock( this->hashesMutex ); + + this->isReceived_[i] = true; + this->hashes_[i] = std::get< 0 >( snapshotData ); + this->signatures_[i] = std::get< 1 >( snapshotData ); + this->public_keys_[i] = std::get< 2 >( snapshotData ); + } + } catch ( std::exception& ex ) { + cerror << "Exception while collecting snapshot signatures from other skaleds: " + << ex.what(); } - } catch ( std::exception& ex ) { - cerror << "Exception while collecting snapshot signatures from other skaleds: " - << ex.what(); - } - } ) ); - } + } ) ); + } - for ( auto& thr : threads ) { - thr.join(); + for ( auto& thr : threads ) { + thr.join(); + } + } else { + auto snapshotData = askNodeForHash( urlToDownloadSnapshotFrom_, blockNumber ); + this->voted_hash_ = { std::get< 0 >( snapshotData ), std::get< 1 >( snapshotData ) }; + return { urlToDownloadSnapshotFrom_ }; } bool result = false; @@ -327,7 +344,7 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( auto majorityNodesIds = AmsterdamFixPatch::majorityNodesIds(); dev::h256 common_hash; // should be same everywhere! for ( size_t pos = 0; pos < this->n_; ++pos ) { - if ( !this->is_received_[pos] ) + if ( !this->isReceived_[pos] ) continue; u256 id = this->chainParams_.sChain.nodes[pos].id; @@ -345,10 +362,10 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( break; } - nodes_to_download_snapshot_from_.push_back( pos ); + nodesToDownloadSnapshotFrom_.push_back( pos ); } // for i - result = this->nodes_to_download_snapshot_from_.size() > 0; + result = this->nodesToDownloadSnapshotFrom_.size() > 0; } else try { result = this->voteForHash(); @@ -359,13 +376,12 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( } // catch if ( !result ) { - cnote << "Not enough nodes to choose snapshot hash for block " - << std::to_string( block_number ); + cnote << "Not enough nodes to choose snapshot hash for block " << blockNumber; return {}; } std::vector< std::string > ret; - for ( const size_t idx : this->nodes_to_download_snapshot_from_ ) { + for ( const size_t idx : this->nodesToDownloadSnapshotFrom_ ) { std::string ret_value = std::string( "http://" ) + std::string( this->chainParams_.sChain.nodes[idx].ip ) + std::string( ":" ) + diff --git a/libskale/SnapshotHashAgent.h b/libskale/SnapshotHashAgent.h index f7437d8c2..62d54a6c3 100644 --- a/libskale/SnapshotHashAgent.h +++ b/libskale/SnapshotHashAgent.h @@ -66,10 +66,10 @@ class IsNotVerified : public SnapshotHashAgentException { class SnapshotHashAgent { public: SnapshotHashAgent( const dev::eth::ChainParams& chainParams, - const std::array< std::string, 4 >& common_public_key, + const std::array< std::string, 4 >& commonPublicKey, const std::string& urlToDownloadSnapshotFrom ); - std::vector< std::string > getNodesToDownloadSnapshotFrom( unsigned block_number ); + std::vector< std::string > getNodesToDownloadSnapshotFrom( unsigned blockNumber ); std::pair< dev::h256, libff::alt_bn128_G1 > getVotedHash() const; @@ -84,13 +84,15 @@ class SnapshotHashAgent { std::vector< dev::h256 > hashes_; std::vector< libff::alt_bn128_G1 > signatures_; std::vector< libff::alt_bn128_G2 > public_keys_; - std::vector< size_t > nodes_to_download_snapshot_from_; - std::vector< bool > is_received_; - std::mutex hashes_mutex; - libff::alt_bn128_G2 common_public_key_; + std::vector< size_t > nodesToDownloadSnapshotFrom_; + std::vector< bool > isReceived_; + std::mutex hashesMutex; + libff::alt_bn128_G2 commonPublicKey_; bool voteForHash(); void readPublicKeyFromConfig(); + std::tuple< dev::h256, libff::alt_bn128_G1, libff::alt_bn128_G2 > askNodeForHash( + const std::string& url, unsigned blockNumber ); std::pair< dev::h256, libff::alt_bn128_G1 > voted_hash_; size_t verifyAllData() const; diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 3515c2789..588d61165 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -155,8 +155,14 @@ void SnapshotManager::restoreSnapshot( unsigned _blockNumber ) { UnsafeRegion::lock ur_lock; + std::vector< std::string > volumes; + if ( chainParams.nodeInfo.archiveMode && _blockNumber == 0 ) + volumes = coreVolumes; + else + volumes = allVolumes; + int dummy_counter = 0; - for ( const string& vol : allVolumes ) { + for ( const string& vol : volumes ) { if ( fs::exists( data_dir / vol ) ) { if ( btrfs.subvolume._delete( ( data_dir / vol ).c_str() ) ) throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); @@ -702,22 +708,24 @@ void SnapshotManager::computeAllVolumesHash( std::throw_with_nested( SnapshotManager::CannotCreate( hashFile ) ); } - // archive blocks - for ( auto& content : contents ) { - if ( content.leaf().string().find( "archive" ) == std::string::npos ) - continue; - this->computeDatabaseHash( content, ctx ); - } + if ( _blockNumber > 0 ) { + // archive blocks + for ( auto& content : contents ) { + if ( content.leaf().string().find( "archive" ) == std::string::npos ) + continue; + this->computeDatabaseHash( content, ctx ); + } - // historic dbs - this->computeDatabaseHash( - this->snapshots_dir / std::to_string( _blockNumber ) / archiveVolumes[0] / - dev::eth::BlockChain::getChainDirName( chainParams ) / "state", - ctx ); - this->computeDatabaseHash( - this->snapshots_dir / std::to_string( _blockNumber ) / archiveVolumes[1] / - dev::eth::BlockChain::getChainDirName( chainParams ) / "state", - ctx ); + // historic dbs + this->computeDatabaseHash( + this->snapshots_dir / std::to_string( _blockNumber ) / archiveVolumes[0] / + dev::eth::BlockChain::getChainDirName( chainParams ) / "state", + ctx ); + this->computeDatabaseHash( + this->snapshots_dir / std::to_string( _blockNumber ) / archiveVolumes[1] / + dev::eth::BlockChain::getChainDirName( chainParams ) / "state", + ctx ); + } } } @@ -734,7 +742,13 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki int dummy_counter = 0; - for ( const auto& volume : allVolumes ) { + std::vector< std::string > volumes; + if ( chainParams.nodeInfo.archiveMode && _blockNumber == 0 ) + volumes = coreVolumes; + else + volumes = allVolumes; + + for ( const auto& volume : volumes ) { int res = btrfs.subvolume.property_set( ( this->snapshots_dir / std::to_string( _blockNumber ) / volume ).string().c_str(), "ro", "false" ); @@ -749,7 +763,7 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki this->computeAllVolumesHash( _blockNumber, &ctx, is_checking ); - for ( const auto& volume : allVolumes ) { + for ( const auto& volume : volumes ) { int res = btrfs.subvolume.property_set( ( this->snapshots_dir / std::to_string( _blockNumber ) / volume ).string().c_str(), "ro", "true" ); diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index f47eb17bc..2a0adf0d3 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -364,7 +364,8 @@ std::string Skale::skale_getLatestSnapshotBlockNumber() { Json::Value Skale::skale_getSnapshotSignature( unsigned blockNumber ) { dev::eth::ChainParams chainParams = this->m_client.chainParams(); - if ( chainParams.nodeInfo.keyShareName.empty() || chainParams.nodeInfo.sgxServerUrl.empty() ) + if ( !chainParams.nodeInfo.syncNode && ( chainParams.nodeInfo.keyShareName.empty() || + chainParams.nodeInfo.sgxServerUrl.empty() ) ) throw jsonrpc::JsonRpcException( "Snapshot signing is not enabled" ); if ( blockNumber != 0 && blockNumber != this->m_client.getLatestSnapshotBlockNumer() ) { @@ -373,118 +374,129 @@ Json::Value Skale::skale_getSnapshotSignature( unsigned blockNumber ) { } try { - dev::h256 snapshot_hash = this->m_client.getSnapshotHash( blockNumber, false ); - if ( !snapshot_hash ) + dev::h256 snapshotHash = this->m_client.getSnapshotHash( blockNumber, false ); + if ( !snapshotHash ) throw std::runtime_error( "Requested hash of block " + to_string( blockNumber ) + " is absent" ); - std::string sgxServerURL = chainParams.nodeInfo.sgxServerUrl; - skutils::url u( sgxServerURL ); - - nlohmann::json joCall = nlohmann::json::object(); - joCall["jsonrpc"] = "2.0"; - joCall["method"] = "blsSignMessageHash"; - if ( u.scheme() == "zmq" ) - joCall["type"] = "BLSSignReq"; - nlohmann::json obj = nlohmann::json::object(); - - obj["keyShareName"] = chainParams.nodeInfo.keyShareName; - obj["messageHash"] = snapshot_hash.hex(); - obj["n"] = chainParams.sChain.nodes.size(); - obj["t"] = chainParams.sChain.t; - - auto it = std::find_if( chainParams.sChain.nodes.begin(), chainParams.sChain.nodes.end(), - [chainParams]( const dev::eth::sChainNode& schain_node ) { - return schain_node.id == chainParams.nodeInfo.id; - } ); - assert( it != chainParams.sChain.nodes.end() ); - dev::eth::sChainNode schain_node = *it; - - joCall["params"] = obj; - - // TODO deduplicate with SkaleHost! - std::string sgx_cert_path = getenv( "SGX_CERT_FOLDER" ) ? getenv( "SGX_CERT_FOLDER" ) : ""; - if ( sgx_cert_path.empty() ) - sgx_cert_path = "/skale_node_data/sgx_certs/"; - else if ( sgx_cert_path[sgx_cert_path.length() - 1] != '/' ) - sgx_cert_path += '/'; - - const char* sgx_cert_filename = getenv( "SGX_CERT_FILE" ); - if ( sgx_cert_filename == nullptr ) - sgx_cert_filename = "sgx.crt"; - - const char* sgx_key_filename = getenv( "SGX_KEY_FILE" ); - if ( sgx_key_filename == nullptr ) - sgx_key_filename = "sgx.key"; - - skutils::http::SSL_client_options ssl_options; - ssl_options.client_cert = sgx_cert_path + sgx_cert_filename; - ssl_options.client_key = sgx_cert_path + sgx_key_filename; + nlohmann::json joSignature = nlohmann::json::object(); + if ( !chainParams.nodeInfo.syncNode ) { + std::string sgxServerURL = chainParams.nodeInfo.sgxServerUrl; + skutils::url u( sgxServerURL ); + + nlohmann::json joCall = nlohmann::json::object(); + joCall["jsonrpc"] = "2.0"; + joCall["method"] = "blsSignMessageHash"; + if ( u.scheme() == "zmq" ) + joCall["type"] = "BLSSignReq"; + nlohmann::json obj = nlohmann::json::object(); + + obj["keyShareName"] = chainParams.nodeInfo.keyShareName; + obj["messageHash"] = snapshotHash.hex(); + obj["n"] = chainParams.sChain.nodes.size(); + obj["t"] = chainParams.sChain.t; + + auto it = + std::find_if( chainParams.sChain.nodes.begin(), chainParams.sChain.nodes.end(), + [chainParams]( const dev::eth::sChainNode& schain_node ) { + return schain_node.id == chainParams.nodeInfo.id; + } ); + assert( it != chainParams.sChain.nodes.end() ); + dev::eth::sChainNode schain_node = *it; + + joCall["params"] = obj; + + // TODO deduplicate with SkaleHost! + std::string sgx_cert_path = + getenv( "SGX_CERT_FOLDER" ) ? getenv( "SGX_CERT_FOLDER" ) : ""; + if ( sgx_cert_path.empty() ) + sgx_cert_path = "/skale_node_data/sgx_certs/"; + else if ( sgx_cert_path[sgx_cert_path.length() - 1] != '/' ) + sgx_cert_path += '/'; + + const char* sgx_cert_filename = getenv( "SGX_CERT_FILE" ); + if ( sgx_cert_filename == nullptr ) + sgx_cert_filename = "sgx.crt"; + + const char* sgx_key_filename = getenv( "SGX_KEY_FILE" ); + if ( sgx_key_filename == nullptr ) + sgx_key_filename = "sgx.key"; + + skutils::http::SSL_client_options ssl_options; + ssl_options.client_cert = sgx_cert_path + sgx_cert_filename; + ssl_options.client_key = sgx_cert_path + sgx_key_filename; - skutils::rest::client cli( skutils::rest::g_nClientConnectionTimeoutMS ); - cli.optsSSL_ = ssl_options; - bool fl = cli.open( sgxServerURL ); - if ( !fl ) { - clog( VerbosityError, "skale_getSnapshotSignature" ) - << cc::fatal( "FATAL:" ) - << cc::error( " Exception while trying to connect to sgx server: " ) - << cc::warn( "connection refused" ) << std::endl; - } + skutils::rest::client cli( skutils::rest::g_nClientConnectionTimeoutMS ); + cli.optsSSL_ = ssl_options; + bool fl = cli.open( sgxServerURL ); + if ( !fl ) { + clog( VerbosityError, "skale_getSnapshotSignature" ) + << cc::fatal( "FATAL:" ) + << cc::error( " Exception while trying to connect to sgx server: " ) + << cc::warn( "connection refused" ) << std::endl; + } - skutils::rest::data_t d; - while ( true ) { - clog( VerbosityInfo, "skale_getSnapshotSignature" ) - << cc::ws_tx( ">>> SGX call >>>" ) << " " << cc::j( joCall ) << std::endl; - d = cli.call( joCall ); - if ( d.ei_.et_ != skutils::http::common_network_exception::error_type::et_no_error ) { - if ( d.ei_.et_ == skutils::http::common_network_exception::error_type::et_unknown || - d.ei_.et_ == skutils::http::common_network_exception::error_type::et_fatal ) { - clog( VerbosityError, "skale_getSnapshotSignature" ) - << cc::error( "ERROR:" ) - << cc::error( " Exception while trying to connect to sgx server: " ) - << cc::error( " error with connection: " ) << cc::info( " retrying... " ) - << std::endl; + skutils::rest::data_t d; + while ( true ) { + clog( VerbosityInfo, "skale_getSnapshotSignature" ) + << cc::ws_tx( ">>> SGX call >>>" ) << " " << cc::j( joCall ) << std::endl; + d = cli.call( joCall ); + if ( d.ei_.et_ != + skutils::http::common_network_exception::error_type::et_no_error ) { + if ( d.ei_.et_ == + skutils::http::common_network_exception::error_type::et_unknown || + d.ei_.et_ == + skutils::http::common_network_exception::error_type::et_fatal ) { + clog( VerbosityError, "skale_getSnapshotSignature" ) + << cc::error( "ERROR:" ) + << cc::error( " Exception while trying to connect to sgx server: " ) + << cc::error( " error with connection: " ) + << cc::info( " retrying... " ) << std::endl; + } else { + clog( VerbosityError, "skale_getSnapshotSignature" ) + << cc::error( "ERROR:" ) + << cc::error( " Exception while trying to connect to sgx server: " ) + << cc::error( " error with ssl certificates " ) + << cc::error( d.ei_.strError_ ) << std::endl; + } } else { - clog( VerbosityError, "skale_getSnapshotSignature" ) - << cc::error( "ERROR:" ) - << cc::error( " Exception while trying to connect to sgx server: " ) - << cc::error( " error with ssl certificates " ) - << cc::error( d.ei_.strError_ ) << std::endl; + break; } - } else { - break; } - } - if ( d.empty() ) { - static const char g_strErrMsg[] = "SGX Server call to blsSignMessageHash failed"; - clog( VerbosityError, "skale_getSnapshotSignature" ) - << cc::error( "!!! SGX call error !!!" ) << " " << cc::error( g_strErrMsg ) - << std::endl; - throw std::runtime_error( g_strErrMsg ); - } + if ( d.empty() ) { + static const char g_strErrMsg[] = "SGX Server call to blsSignMessageHash failed"; + clog( VerbosityError, "skale_getSnapshotSignature" ) + << cc::error( "!!! SGX call error !!!" ) << " " << cc::error( g_strErrMsg ) + << std::endl; + throw std::runtime_error( g_strErrMsg ); + } - nlohmann::json joAnswer = nlohmann::json::parse( d.s_ ); - nlohmann::json joResponse = - ( joAnswer.count( "result" ) > 0 ) ? joAnswer["result"] : joAnswer; - clog( VerbosityInfo, "skale_getSnapshotSignature" ) - << cc::ws_rx( "<<< SGX call <<<" ) << " " << cc::j( joResponse ) << std::endl; - if ( joResponse["status"] != 0 ) { - throw std::runtime_error( - "SGX Server call to blsSignMessageHash returned non-zero status" ); + nlohmann::json joAnswer = nlohmann::json::parse( d.s_ ); + nlohmann::json joResponse = + ( joAnswer.count( "result" ) > 0 ) ? joAnswer["result"] : joAnswer; + clog( VerbosityInfo, "skale_getSnapshotSignature" ) + << cc::ws_rx( "<<< SGX call <<<" ) << " " << cc::j( joResponse ) << std::endl; + if ( joResponse["status"] != 0 ) { + throw std::runtime_error( + "SGX Server call to blsSignMessageHash returned non-zero status" ); + } + std::string signature_with_helper = joResponse["signatureShare"].get< std::string >(); + + std::vector< std::string > splidString; + splidString = boost::split( + splidString, signature_with_helper, []( char c ) { return c == ':'; } ); + + joSignature["X"] = splidString.at( 0 ); + joSignature["Y"] = splidString.at( 1 ); + joSignature["helper"] = splidString.at( 3 ); + } else { + joSignature["X"] = "1"; + joSignature["Y"] = "2"; + joSignature["helper"] = "1"; } - std::string signature_with_helper = joResponse["signatureShare"].get< std::string >(); - - std::vector< std::string > splited_string; - splited_string = boost::split( - splited_string, signature_with_helper, []( char c ) { return c == ':'; } ); - - nlohmann::json joSignature = nlohmann::json::object(); - joSignature["X"] = splited_string[0]; - joSignature["Y"] = splited_string[1]; - joSignature["helper"] = splited_string[3]; - joSignature["hash"] = snapshot_hash.hex(); + joSignature["hash"] = snapshotHash.hex(); std::string strSignature = joSignature.dump(); Json::Value response; diff --git a/skaled/main.cpp b/skaled/main.cpp index 5308ed429..8cf6ac064 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -348,8 +348,8 @@ unsigned getBlockToDownladSnapshot( const std::string& nodeUrl ) { unsigned blockNumber = getLatestSnapshotBlockNumber( nodeUrl ); clog( VerbosityInfo, "getBlockToDownladSnapshot" ) - << std::string( "Latest Snapshot Block Number is: " ) << std::to_string( blockNumber ) - << " (from " << nodeUrl << ")"; + << std::string( "Latest Snapshot Block Number is: " ) << blockNumber << " (from " << nodeUrl + << ")"; return blockNumber; } @@ -1592,6 +1592,8 @@ int main( int argc, char** argv ) try { std::string urlToDownloadSnapshotFrom = ""; if ( vm.count( "no-snapshot-majority" ) ) { urlToDownloadSnapshotFrom = vm["no-snapshot-majority"].as< string >(); + clog( VerbosityInfo, "main" ) + << "Manually set url to download snapshot from: " << urlToDownloadSnapshotFrom; } if ( chainParams.sChain.snapshotIntervalSec > 0 || downloadSnapshotFlag ) { diff --git a/test/unittests/libskale/HashSnapshot.cpp b/test/unittests/libskale/HashSnapshot.cpp index 2a4449185..8c61a5ea5 100644 --- a/test/unittests/libskale/HashSnapshot.cpp +++ b/test/unittests/libskale/HashSnapshot.cpp @@ -93,7 +93,7 @@ class SnapshotHashAgentTest { this->hashAgent_->hashes_ = snapshot_hashes; for ( size_t i = 0; i < this->hashAgent_->n_; ++i ) { - this->hashAgent_->is_received_[i] = true; + this->hashAgent_->isReceived_[i] = true; this->hashAgent_->public_keys_[i] = this->blsPrivateKeys_[i] * libff::alt_bn128_G2::one(); this->hashAgent_->signatures_[i] = libBLS::Bls::Signing( @@ -115,7 +115,7 @@ class SnapshotHashAgentTest { } if ( isSnapshotMajorityRequired ) - return this->hashAgent_->nodes_to_download_snapshot_from_; + return this->hashAgent_->nodesToDownloadSnapshotFrom_; std::vector< size_t > ret; for ( size_t i = 0; i < this->hashAgent_->n_; ++i ) { From 2943beef0e4aeb2f0a5c34ff43f01de51f367845 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 12 Jun 2024 13:23:25 +0100 Subject: [PATCH 13/47] IS 968 small improvements --- libweb3jsonrpc/Skale.cpp | 4 +++- libweb3jsonrpc/Skale.h | 2 +- skaled/main.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index 2a0adf0d3..1ec693a20 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -591,7 +591,8 @@ std::string Skale::oracle_checkResult( std::string& receipt ) { namespace snapshot { bool download( const std::string& strURLWeb3, unsigned& block_number, const fs::path& saveTo, - fn_progress_t onProgress, bool isBinaryDownload, std::string* pStrErrorDescription ) { + fn_progress_t onProgress, bool isBinaryDownload, std::string* pStrErrorDescription, + bool forArchiveNode ) { if ( pStrErrorDescription ) pStrErrorDescription->clear(); std::ofstream f; @@ -645,6 +646,7 @@ bool download( const std::string& strURLWeb3, unsigned& block_number, const fs:: joIn["method"] = "skale_getSnapshot"; nlohmann::json joParams = nlohmann::json::object(); joParams["blockNumber"] = block_number; + joParams["forArchiveNode"] = forArchiveNode; joIn["params"] = joParams; skutils::rest::data_t d = cli.call( joIn ); if ( !d.err_s_.empty() ) { diff --git a/libweb3jsonrpc/Skale.h b/libweb3jsonrpc/Skale.h index 3a39db3e7..93f3ded44 100644 --- a/libweb3jsonrpc/Skale.h +++ b/libweb3jsonrpc/Skale.h @@ -118,7 +118,7 @@ typedef std::function< bool( size_t idxChunck, size_t cntChunks ) > fn_progress_ extern bool download( const std::string& strURLWeb3, unsigned& block_number, const fs::path& saveTo, fn_progress_t onProgress, bool isBinaryDownload = true, - std::string* pStrErrorDescription = nullptr ); + std::string* pStrErrorDescription = nullptr, bool forArchiveNode = false ); }; // namespace snapshot diff --git a/skaled/main.cpp b/skaled/main.cpp index 8cf6ac064..a078f273c 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1649,7 +1649,7 @@ int main( int argc, char** argv ) try { // sleep before send skale_getSnapshot again - will receive error clog( VerbosityInfo, "main" ) << std::string( "Will sleep for 60 seconds before downloading 0 snapshot" ); - sleep( 60 ); + sleep( chainParams.sChain.snapshotDownloadTimeout ); downloadAndProccessSnapshot( snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); From ec72c81e131e4e828c98ea80790b34b466a76f7a Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 2 Jul 2024 15:51:07 +0100 Subject: [PATCH 14/47] IS 968 remove patch --- libethereum/SchainPatch.cpp | 4 ---- libethereum/SchainPatch.h | 6 ------ libethereum/SchainPatchEnum.h | 1 - libweb3jsonrpc/Skale.cpp | 2 +- 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/libethereum/SchainPatch.cpp b/libethereum/SchainPatch.cpp index 7f4a9037c..f3a5f8daa 100644 --- a/libethereum/SchainPatch.cpp +++ b/libethereum/SchainPatch.cpp @@ -36,8 +36,6 @@ SchainPatchEnum getEnumForPatchName( const std::string& _patchName ) { return SchainPatchEnum::VerifyBlsSyncPatch; else if ( _patchName == "FlexibleDeploymentPatch" ) return SchainPatchEnum::FlexibleDeploymentPatch; - else if ( _patchName == "ArchiveNodeSnapshotsPatch" ) - return SchainPatchEnum::ArchiveNodeSnapshotsPatch; else throw std::out_of_range( _patchName ); } @@ -74,8 +72,6 @@ std::string getPatchNameForEnum( SchainPatchEnum _enumValue ) { return "VerifyBlsSyncPatch"; case SchainPatchEnum::FlexibleDeploymentPatch: return "FlexibleDeploymentPatch"; - case SchainPatchEnum::ArchiveNodeSnapshotsPatch: - return "ArchiveNodeSnapshotsPatch"; default: throw std::out_of_range( "UnknownPatch #" + std::to_string( static_cast< size_t >( _enumValue ) ) ); diff --git a/libethereum/SchainPatch.h b/libethereum/SchainPatch.h index 476a21aed..9af149fb9 100644 --- a/libethereum/SchainPatch.h +++ b/libethereum/SchainPatch.h @@ -146,10 +146,4 @@ DEFINE_AMNESIC_PATCH( VerifyBlsSyncPatch ); */ DEFINE_SIMPLE_PATCH( FlexibleDeploymentPatch ); -/* - * Purpose: introduce snapshot downloading for archive nodes - * Version introduced: 3.20.0 - */ -DEFINE_AMNESIC_PATCH( ArchiveNodeSnapshotsPatch ); - #endif // SCHAINPATCH_H diff --git a/libethereum/SchainPatchEnum.h b/libethereum/SchainPatchEnum.h index e708fdc23..ac0b1c19a 100644 --- a/libethereum/SchainPatchEnum.h +++ b/libethereum/SchainPatchEnum.h @@ -20,7 +20,6 @@ enum class SchainPatchEnum { EIP1559TransactionsPatch, VerifyBlsSyncPatch, FlexibleDeploymentPatch, - ArchiveNodeSnapshotsPatch, PatchesCount }; diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index 1ec693a20..13881d73f 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -160,7 +160,7 @@ nlohmann::json Skale::impl_skale_getSnapshot( const nlohmann::json& joRequest, C } bool forArchiveNode = false; - if ( ArchiveNodeSnapshotsPatch::isEnabledInWorkingBlock() ) + if ( client.chainParams().nodeInfo.archiveMode ) forArchiveNode = joRequest["forArchiveNode"].get< bool >(); // exit if too early From 82e4b21b9044cd206226348e0565b758769a39ad Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 2 Jul 2024 18:58:26 +0100 Subject: [PATCH 15/47] IS 968 fix snapshot downloading to archive node --- skaled/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skaled/main.cpp b/skaled/main.cpp index a078f273c..593db24c0 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -265,7 +265,7 @@ void downloadSnapshot( unsigned block_number, std::shared_ptr< SnapshotManager > << cc::normal( " of " ) << cc::size10( cntChunks ) << "\r"; return true; // continue download }, - isBinaryDownload, &strErrorDescription ); + isBinaryDownload, &strErrorDescription, chainParams.nodeInfo.archiveMode ); std::cout << " \r"; // clear // progress // line From ae877bac294515b2aa7b72d5f685993ec52d902e Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 3 Jul 2024 11:52:13 +0100 Subject: [PATCH 16/47] IS 968 fix sleep --- skaled/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skaled/main.cpp b/skaled/main.cpp index 593db24c0..2492efd07 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1649,7 +1649,7 @@ int main( int argc, char** argv ) try { // sleep before send skale_getSnapshot again - will receive error clog( VerbosityInfo, "main" ) << std::string( "Will sleep for 60 seconds before downloading 0 snapshot" ); - sleep( chainParams.sChain.snapshotDownloadTimeout ); + sleep( 60 ); downloadAndProccessSnapshot( snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); From 1c61fca27b561850adbb623eaf777dd5bc99ac53 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 3 Jul 2024 13:30:16 +0100 Subject: [PATCH 17/47] IS 968 fix sleep --- skaled/main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/skaled/main.cpp b/skaled/main.cpp index 2492efd07..e10397642 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1648,8 +1648,10 @@ int main( int argc, char** argv ) try { } catch ( SnapshotManager::SnapshotAbsent& ex ) { // sleep before send skale_getSnapshot again - will receive error clog( VerbosityInfo, "main" ) - << std::string( "Will sleep for 60 seconds before downloading 0 snapshot" ); - sleep( 60 ); + << std::string( "Will sleep for " ) + << chainParams.sChain.snapshotDownloadTimeout + << std::string( " seconds before downloading 0 snapshot" ); + sleep( chainParams.sChain.snapshotDownloadTimeout ); downloadAndProccessSnapshot( snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); From 7b31cd661418687e28811342f3f29f6994b89a50 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Thu, 4 Jul 2024 16:23:02 +0100 Subject: [PATCH 18/47] IS 968 indexer node --- libskale/SnapshotManager.cpp | 5 ++++- skaled/main.cpp | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 588d61165..14435ca17 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -203,7 +203,8 @@ boost::filesystem::path SnapshotManager::makeOrGetDiff( unsigned _toBlock, bool stringstream volumes_cat; - std::vector< std::string > volumes = _forArchiveNode ? allVolumes : coreVolumes; + std::vector< std::string > volumes = + ( _forArchiveNode && _toBlock > 0 ) ? allVolumes : coreVolumes; for ( auto it = volumes.begin(); it != volumes.end(); ++it ) { const string& vol = *it; if ( it + 1 != volumes.end() ) @@ -716,6 +717,7 @@ void SnapshotManager::computeAllVolumesHash( this->computeDatabaseHash( content, ctx ); } +#ifdef HISTORIC_STATE // historic dbs this->computeDatabaseHash( this->snapshots_dir / std::to_string( _blockNumber ) / archiveVolumes[0] / @@ -725,6 +727,7 @@ void SnapshotManager::computeAllVolumesHash( this->snapshots_dir / std::to_string( _blockNumber ) / archiveVolumes[1] / dev::eth::BlockChain::getChainDirName( chainParams ) / "state", ctx ); +#endif } } } diff --git a/skaled/main.cpp b/skaled/main.cpp index e10397642..9829dd6b0 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1602,7 +1602,9 @@ int main( int argc, char** argv ) try { "blocks_" + chainParams.nodeInfo.id.str() + ".db" }; std::vector< std::string > archiveVolumes = {}; if ( chainParams.nodeInfo.archiveMode ) +#ifdef HISTORIC_STATE archiveVolumes.insert( archiveVolumes.end(), { "historic_roots", "historic_state" } ); +#endif snapshotManager.reset( new SnapshotManager( chainParams, getDataDir(), coreVolumes, archiveVolumes, sharedSpace ? sharedSpace->getPath() : "" ) ); } From c1f0dc29dd0c3de5f8e8b5eeba18371f97f7794b Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Fri, 5 Jul 2024 16:20:30 +0100 Subject: [PATCH 19/47] IS 968 fix format --- skaled/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skaled/main.cpp b/skaled/main.cpp index 9829dd6b0..cf3e2a20e 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1601,10 +1601,11 @@ int main( int argc, char** argv ) try { "filestorage", "prices_" + chainParams.nodeInfo.id.str() + ".db", "blocks_" + chainParams.nodeInfo.id.str() + ".db" }; std::vector< std::string > archiveVolumes = {}; - if ( chainParams.nodeInfo.archiveMode ) + if ( chainParams.nodeInfo.archiveMode ) { #ifdef HISTORIC_STATE archiveVolumes.insert( archiveVolumes.end(), { "historic_roots", "historic_state" } ); #endif + } snapshotManager.reset( new SnapshotManager( chainParams, getDataDir(), coreVolumes, archiveVolumes, sharedSpace ? sharedSpace->getPath() : "" ) ); } From a958b42342457171c0c1461e5ed40423177ddac7 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Thu, 25 Jul 2024 12:47:10 +0100 Subject: [PATCH 20/47] IS 968 update tests --- libskale/SnapshotManager.cpp | 130 ++++++++-------- libskale/SnapshotManager.h | 13 +- skaled/main.cpp | 7 +- test/unittests/libethereum/ClientTest.cpp | 4 +- test/unittests/libskale/HashSnapshot.cpp | 50 ++++--- test/unittests/libskale/SnapshotManager.cpp | 156 +++++++++++--------- 6 files changed, 198 insertions(+), 162 deletions(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 14435ca17..d345beca0 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -56,24 +56,28 @@ const std::string SnapshotManager::partialSnapshotHashFileName = "partial_snapsh // - not btrfs // - volumes don't exist SnapshotManager::SnapshotManager( const dev::eth::ChainParams& _chainParams, - const fs::path& _dataDir, const std::vector< std::string >& _coreVolumes, - const std::vector< std::string >& _archiveVolumes, const std::string& _diffsDir ) + const fs::path& _dataDir, const std::string& _diffsDir ) : chainParams( _chainParams ) { - assert( _coreVolumes.size() > 0 ); + dataDir = _dataDir; + coreVolumes = { dev::eth::BlockChain::getChainDirName( chainParams ), "filestorage", + "prices_" + chainParams.nodeInfo.id.str() + ".db", + "blocks_" + chainParams.nodeInfo.id.str() + ".db" }; - data_dir = _dataDir; - coreVolumes = _coreVolumes; - archiveVolumes = _archiveVolumes; +#ifdef HISTORIC_STATE + archiveVolumes = { "historic_roots", "historic_state" }; +#endif allVolumes.reserve( coreVolumes.size() + archiveVolumes.size() ); allVolumes.insert( allVolumes.end(), coreVolumes.begin(), coreVolumes.end() ); +#ifdef HISTORIC_STATE allVolumes.insert( allVolumes.end(), archiveVolumes.begin(), archiveVolumes.end() ); +#endif - snapshots_dir = data_dir / "snapshots"; + snapshotsDir = dataDir / "snapshots"; if ( _diffsDir.empty() ) - diffs_dir = data_dir / "diffs"; + diffsDir = dataDir / "diffs"; else - diffs_dir = _diffsDir; + diffsDir = _diffsDir; if ( !fs::exists( _dataDir ) ) try { @@ -88,10 +92,10 @@ SnapshotManager::SnapshotManager( const dev::eth::ChainParams& _chainParams, } try { - fs::create_directory( snapshots_dir ); + fs::create_directory( snapshotsDir ); if ( _diffsDir.empty() ) { - fs::remove_all( diffs_dir ); - fs::create_directory( diffs_dir ); + fs::remove_all( diffsDir ); + fs::create_directory( diffsDir ); } } catch ( const fs::filesystem_error& ex ) { std::throw_with_nested( CannotWrite( ex.path1() ) ); @@ -116,26 +120,26 @@ SnapshotManager::SnapshotManager( const dev::eth::ChainParams& _chainParams, // - cannot read // - cannot write void SnapshotManager::doSnapshot( unsigned _blockNumber ) { - fs::path snapshot_dir = snapshots_dir / to_string( _blockNumber ); + fs::path snapshotDir = snapshotsDir / to_string( _blockNumber ); UnsafeRegion::lock ur_lock; try { - if ( fs::exists( snapshot_dir ) ) + if ( fs::exists( snapshotDir ) ) throw SnapshotPresent( _blockNumber ); } catch ( const fs::filesystem_error& ) { - std::throw_with_nested( CannotRead( snapshot_dir ) ); + std::throw_with_nested( CannotRead( snapshotDir ) ); } // catch try { - fs::create_directory( snapshot_dir ); + fs::create_directory( snapshotDir ); } catch ( const fs::filesystem_error& ) { - std::throw_with_nested( CannotCreate( snapshot_dir ) ); + std::throw_with_nested( CannotCreate( snapshotDir ) ); } // catch int dummy_counter = 0; for ( const string& vol : allVolumes ) { - int res = btrfs.subvolume.snapshot_r( ( data_dir / vol ).c_str(), snapshot_dir.c_str() ); + int res = btrfs.subvolume.snapshot_r( ( dataDir / vol ).c_str(), snapshotDir.c_str() ); if ( res ) throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); if ( dummy_counter++ == 1 ) @@ -147,10 +151,10 @@ void SnapshotManager::doSnapshot( unsigned _blockNumber ) { // - not found/cannot read void SnapshotManager::restoreSnapshot( unsigned _blockNumber ) { try { - if ( !fs::exists( snapshots_dir / to_string( _blockNumber ) ) ) + if ( !fs::exists( snapshotsDir / to_string( _blockNumber ) ) ) throw SnapshotAbsent( _blockNumber ); } catch ( const fs::filesystem_error& ) { - std::throw_with_nested( CannotRead( snapshots_dir / to_string( _blockNumber ) ) ); + std::throw_with_nested( CannotRead( snapshotsDir / to_string( _blockNumber ) ) ); } UnsafeRegion::lock ur_lock; @@ -163,12 +167,12 @@ void SnapshotManager::restoreSnapshot( unsigned _blockNumber ) { int dummy_counter = 0; for ( const string& vol : volumes ) { - if ( fs::exists( data_dir / vol ) ) { - if ( btrfs.subvolume._delete( ( data_dir / vol ).c_str() ) ) + if ( fs::exists( dataDir / vol ) ) { + if ( btrfs.subvolume._delete( ( dataDir / vol ).c_str() ) ) throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); } if ( btrfs.subvolume.snapshot( - ( snapshots_dir / to_string( _blockNumber ) / vol ).c_str(), data_dir.c_str() ) ) + ( snapshotsDir / to_string( _blockNumber ) / vol ).c_str(), dataDir.c_str() ) ) throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); if ( dummy_counter++ == 1 ) @@ -189,7 +193,7 @@ boost::filesystem::path SnapshotManager::makeOrGetDiff( unsigned _toBlock, bool if ( fs::is_regular( path ) ) return path; - if ( !fs::exists( snapshots_dir / to_string( _toBlock ) ) ) { + if ( !fs::exists( snapshotsDir / to_string( _toBlock ) ) ) { // TODO wrong error message if this fails fs::remove( path ); throw SnapshotAbsent( _toBlock ); @@ -208,9 +212,9 @@ boost::filesystem::path SnapshotManager::makeOrGetDiff( unsigned _toBlock, bool for ( auto it = volumes.begin(); it != volumes.end(); ++it ) { const string& vol = *it; if ( it + 1 != volumes.end() ) - volumes_cat << ( snapshots_dir / to_string( _toBlock ) / vol ).string() << " "; + volumes_cat << ( snapshotsDir / to_string( _toBlock ) / vol ).string() << " "; else - volumes_cat << ( snapshots_dir / to_string( _toBlock ) / vol ).string(); + volumes_cat << ( snapshotsDir / to_string( _toBlock ) / vol ).string(); } // for cat UnsafeRegion::lock ur_lock; @@ -233,7 +237,7 @@ boost::filesystem::path SnapshotManager::makeOrGetDiff( unsigned _toBlock, bool // - cannot input as diff (no base state?) void SnapshotManager::importDiff( unsigned _toBlock ) { fs::path diffPath = getDiffPath( _toBlock ); - fs::path snapshot_dir = snapshots_dir / to_string( _toBlock ); + fs::path snapshot_dir = snapshotsDir / to_string( _toBlock ); try { if ( !fs::is_regular_file( diffPath ) ) @@ -252,7 +256,7 @@ void SnapshotManager::importDiff( unsigned _toBlock ) { std::throw_with_nested( CannotCreate( snapshot_dir ) ); } // catch - if ( btrfs.receive( diffPath.c_str(), ( snapshots_dir / to_string( _toBlock ) ).c_str() ) ) { + if ( btrfs.receive( diffPath.c_str(), ( snapshotsDir / to_string( _toBlock ) ).c_str() ) ) { auto ex = CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); cleanupDirectory( snapshot_dir ); fs::remove_all( snapshot_dir ); @@ -262,12 +266,12 @@ void SnapshotManager::importDiff( unsigned _toBlock ) { boost::filesystem::path SnapshotManager::getDiffPath( unsigned _toBlock ) { // check existance - assert( boost::filesystem::exists( diffs_dir ) ); - return diffs_dir / ( std::to_string( _toBlock ) ); + assert( boost::filesystem::exists( diffsDir ) ); + return diffsDir / ( std::to_string( _toBlock ) ); } void SnapshotManager::removeSnapshot( unsigned _blockNumber ) { - if ( !fs::exists( snapshots_dir / to_string( _blockNumber ) ) ) { + if ( !fs::exists( snapshotsDir / to_string( _blockNumber ) ) ) { throw SnapshotAbsent( _blockNumber ); } @@ -277,7 +281,7 @@ void SnapshotManager::removeSnapshot( unsigned _blockNumber ) { for ( const auto& volume : allVolumes ) { int res = btrfs.subvolume._delete( - ( this->snapshots_dir / std::to_string( _blockNumber ) / volume ).string().c_str() ); + ( this->snapshotsDir / std::to_string( _blockNumber ) / volume ).string().c_str() ); if ( res != 0 ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); @@ -287,28 +291,28 @@ void SnapshotManager::removeSnapshot( unsigned _blockNumber ) { batched_io::test_crash_before_commit( "SnapshotManager::doSnapshot" ); } - fs::remove_all( snapshots_dir / to_string( _blockNumber ) ); + fs::remove_all( snapshotsDir / to_string( _blockNumber ) ); } void SnapshotManager::cleanupButKeepSnapshot( unsigned _keepSnapshot ) { - this->cleanupDirectory( snapshots_dir, snapshots_dir / std::to_string( _keepSnapshot ) ); - this->cleanupDirectory( data_dir, snapshots_dir ); - if ( !fs::exists( diffs_dir ) ) + this->cleanupDirectory( snapshotsDir, snapshotsDir / std::to_string( _keepSnapshot ) ); + this->cleanupDirectory( dataDir, snapshotsDir ); + if ( !fs::exists( diffsDir ) ) try { - boost::filesystem::create_directory( diffs_dir ); + boost::filesystem::create_directory( diffsDir ); } catch ( const fs::filesystem_error& ex ) { std::throw_with_nested( CannotWrite( ex.path1() ) ); } } void SnapshotManager::cleanup() { - this->cleanupDirectory( snapshots_dir ); - this->cleanupDirectory( data_dir ); + this->cleanupDirectory( snapshotsDir ); + this->cleanupDirectory( dataDir ); try { - boost::filesystem::create_directory( snapshots_dir ); - if ( !fs::exists( diffs_dir ) ) - boost::filesystem::create_directory( diffs_dir ); + boost::filesystem::create_directory( snapshotsDir ); + if ( !fs::exists( diffsDir ) ) + boost::filesystem::create_directory( diffsDir ); } catch ( const fs::filesystem_error& ex ) { std::throw_with_nested( CannotWrite( ex.path1() ) ); } // catch @@ -342,7 +346,7 @@ void SnapshotManager::cleanupDirectory( // exeptions: filesystem void SnapshotManager::leaveNLastSnapshots( unsigned n ) { map< int, fs::path, std::greater< int > > numbers; - for ( auto& f : fs::directory_iterator( snapshots_dir ) ) { + for ( auto& f : fs::directory_iterator( snapshotsDir ) ) { // HACK We exclude 0 snapshot forcefully if ( fs::basename( f ) != "0" ) numbers.insert( make_pair( std::stoi( fs::basename( f ) ), f ) ); @@ -365,7 +369,7 @@ void SnapshotManager::leaveNLastSnapshots( unsigned n ) { std::pair< int, int > SnapshotManager::getLatestSnapshots() const { map< int, fs::path, std::greater< int > > numbers; - for ( auto& f : fs::directory_iterator( snapshots_dir ) ) { + for ( auto& f : fs::directory_iterator( snapshotsDir ) ) { // HACK We exclude 0 snapshot forcefully if ( fs::basename( f ) != "0" ) numbers.insert( make_pair( std::stoi( fs::basename( f ) ), f ) ); @@ -391,7 +395,7 @@ std::pair< int, int > SnapshotManager::getLatestSnapshots() const { // exeptions: filesystem void SnapshotManager::leaveNLastDiffs( unsigned n ) { map< int, fs::path, std::greater< int > > numbers; - for ( auto& f : fs::directory_iterator( diffs_dir ) ) { + for ( auto& f : fs::directory_iterator( diffsDir ) ) { try { numbers.insert( make_pair( std::stoi( fs::basename( f ) ), f ) ); } catch ( ... ) { /*ignore non-numbers*/ @@ -409,7 +413,7 @@ void SnapshotManager::leaveNLastDiffs( unsigned n ) { } dev::h256 SnapshotManager::getSnapshotHash( unsigned block_number, bool _forArchiveNode ) const { - fs::path snapshot_dir = snapshots_dir / to_string( block_number ); + fs::path snapshot_dir = snapshotsDir / to_string( block_number ); try { if ( !fs::exists( snapshot_dir ) ) @@ -420,12 +424,12 @@ dev::h256 SnapshotManager::getSnapshotHash( unsigned block_number, bool _forArch std::string hashFile; if ( !_forArchiveNode && chainParams.nodeInfo.archiveMode ) - hashFile = ( this->snapshots_dir / std::to_string( block_number ) / + hashFile = ( this->snapshotsDir / std::to_string( block_number ) / this->partialSnapshotHashFileName ) .string(); else hashFile = - ( this->snapshots_dir / std::to_string( block_number ) / this->snapshotHashFileName ) + ( this->snapshotsDir / std::to_string( block_number ) / this->snapshotHashFileName ) .string(); if ( !isSnapshotHashPresent( block_number ) ) { @@ -445,7 +449,7 @@ dev::h256 SnapshotManager::getSnapshotHash( unsigned block_number, bool _forArch } bool SnapshotManager::isSnapshotHashPresent( unsigned _blockNumber ) const { - fs::path snapshot_dir = snapshots_dir / to_string( _blockNumber ); + fs::path snapshot_dir = snapshotsDir / to_string( _blockNumber ); try { if ( !fs::exists( snapshot_dir ) ) @@ -455,13 +459,13 @@ bool SnapshotManager::isSnapshotHashPresent( unsigned _blockNumber ) const { } // catch boost::filesystem::path hashFile = - this->snapshots_dir / std::to_string( _blockNumber ) / this->snapshotHashFileName; + this->snapshotsDir / std::to_string( _blockNumber ) / this->snapshotHashFileName; try { std::lock_guard< std::mutex > lock( hashFileMutex ); if ( !chainParams.nodeInfo.archiveMode ) return boost::filesystem::exists( hashFile ); else { - boost::filesystem::path partialHashFile = this->snapshots_dir / + boost::filesystem::path partialHashFile = this->snapshotsDir / std::to_string( _blockNumber ) / this->partialSnapshotHashFileName; return boost::filesystem::exists( hashFile ) && @@ -505,7 +509,7 @@ void SnapshotManager::addLastPriceToHash( unsigned _blockNumber, secp256k1_sha25 dev::u256 last_price = 0; // manually open DB boost::filesystem::path prices_path = - this->snapshots_dir / std::to_string( _blockNumber ) / coreVolumes[2]; + this->snapshotsDir / std::to_string( _blockNumber ) / coreVolumes[2]; if ( boost::filesystem::exists( prices_path ) ) { boost::filesystem::directory_iterator it( prices_path ), end; std::string last_price_str; @@ -653,11 +657,11 @@ void SnapshotManager::computeAllVolumesHash( // TODO XXX Remove volumes structure knowledge from here!! this->computeDatabaseHash( - this->snapshots_dir / std::to_string( _blockNumber ) / coreVolumes[0] / "12041" / "state", + this->snapshotsDir / std::to_string( _blockNumber ) / coreVolumes[0] / "12041" / "state", ctx ); boost::filesystem::path blocks_extras_path = - this->snapshots_dir / std::to_string( _blockNumber ) / coreVolumes[0] / "blocks_and_extras"; + this->snapshotsDir / std::to_string( _blockNumber ) / coreVolumes[0] / "blocks_and_extras"; // few dbs boost::filesystem::directory_iterator directory_it( blocks_extras_path ), end; @@ -683,7 +687,7 @@ void SnapshotManager::computeAllVolumesHash( // filestorage this->computeFileStorageHash( - this->snapshots_dir / std::to_string( _blockNumber ) / "filestorage", ctx, is_checking ); + this->snapshotsDir / std::to_string( _blockNumber ) / "filestorage", ctx, is_checking ); // if have prices and blocks if ( _blockNumber && allVolumes.size() > 3 ) { @@ -697,7 +701,7 @@ void SnapshotManager::computeAllVolumesHash( dev::h256 partialHash; secp256k1_sha256_finalize( &partialCtx, partialHash.data() ); - string hashFile = ( this->snapshots_dir / std::to_string( _blockNumber ) ).string() + '/' + + string hashFile = ( this->snapshotsDir / std::to_string( _blockNumber ) ).string() + '/' + this->partialSnapshotHashFileName; try { @@ -720,11 +724,11 @@ void SnapshotManager::computeAllVolumesHash( #ifdef HISTORIC_STATE // historic dbs this->computeDatabaseHash( - this->snapshots_dir / std::to_string( _blockNumber ) / archiveVolumes[0] / + this->snapshotsDir / std::to_string( _blockNumber ) / archiveVolumes[0] / dev::eth::BlockChain::getChainDirName( chainParams ) / "state", ctx ); this->computeDatabaseHash( - this->snapshots_dir / std::to_string( _blockNumber ) / archiveVolumes[1] / + this->snapshotsDir / std::to_string( _blockNumber ) / archiveVolumes[1] / dev::eth::BlockChain::getChainDirName( chainParams ) / "state", ctx ); #endif @@ -753,7 +757,7 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki for ( const auto& volume : volumes ) { int res = btrfs.subvolume.property_set( - ( this->snapshots_dir / std::to_string( _blockNumber ) / volume ).string().c_str(), + ( this->snapshotsDir / std::to_string( _blockNumber ) / volume ).string().c_str(), "ro", "false" ); if ( res != 0 ) { @@ -768,7 +772,7 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki for ( const auto& volume : volumes ) { int res = btrfs.subvolume.property_set( - ( this->snapshots_dir / std::to_string( _blockNumber ) / volume ).string().c_str(), + ( this->snapshotsDir / std::to_string( _blockNumber ) / volume ).string().c_str(), "ro", "true" ); if ( res != 0 ) { @@ -779,7 +783,7 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki dev::h256 hash; secp256k1_sha256_finalize( &ctx, hash.data() ); - string hash_file = ( this->snapshots_dir / std::to_string( _blockNumber ) ).string() + '/' + + string hash_file = ( this->snapshotsDir / std::to_string( _blockNumber ) ).string() + '/' + this->snapshotHashFileName; try { @@ -793,7 +797,7 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki } uint64_t SnapshotManager::getBlockTimestamp( unsigned _blockNumber ) const { - fs::path snapshot_dir = snapshots_dir / to_string( _blockNumber ); + fs::path snapshot_dir = snapshotsDir / to_string( _blockNumber ); try { if ( !fs::exists( snapshot_dir ) ) @@ -802,7 +806,7 @@ uint64_t SnapshotManager::getBlockTimestamp( unsigned _blockNumber ) const { std::throw_with_nested( CannotRead( snapshot_dir ) ); } - fs::path db_dir = this->snapshots_dir / std::to_string( _blockNumber ); + fs::path db_dir = this->snapshotsDir / std::to_string( _blockNumber ); int res = btrfs.subvolume.property_set( ( db_dir / coreVolumes[0] ).string().c_str(), "ro", "false" ); diff --git a/libskale/SnapshotManager.h b/libskale/SnapshotManager.h index 02af00353..3e9085438 100644 --- a/libskale/SnapshotManager.h +++ b/libskale/SnapshotManager.h @@ -153,9 +153,7 @@ class SnapshotManager { public: SnapshotManager( const dev::eth::ChainParams& _chainParams, - const boost::filesystem::path& _dataDir, const std::vector< std::string >& _coreVolumes, - const std::vector< std::string >& _archiveVolumes = {}, - const std::string& diffs_dir = std::string() ); + const boost::filesystem::path& _dataDir, const std::string& diffs_dir = std::string() ); void doSnapshot( unsigned _blockNumber ); void restoreSnapshot( unsigned _blockNumber ); boost::filesystem::path makeOrGetDiff( unsigned _toBlock, bool _forArchiveNode = false ); @@ -179,12 +177,15 @@ class SnapshotManager { const boost::filesystem::path& _dirPath ); private: - boost::filesystem::path data_dir; + boost::filesystem::path dataDir; std::vector< std::string > coreVolumes; std::vector< std::string > archiveVolumes; std::vector< std::string > allVolumes; - boost::filesystem::path snapshots_dir; - boost::filesystem::path diffs_dir; + boost::filesystem::path snapshotsDir; + boost::filesystem::path diffsDir; + + // std::array< std::string, 4 > coreVolumes; + // std::array< std::string, 2 > archiveVolumes; static const std::string snapshotHashFileName; static const std::string partialSnapshotHashFileName; diff --git a/skaled/main.cpp b/skaled/main.cpp index 1ab1445cf..1f487681a 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1607,8 +1607,11 @@ int main( int argc, char** argv ) try { archiveVolumes.insert( archiveVolumes.end(), { "historic_roots", "historic_state" } ); #endif } - snapshotManager.reset( new SnapshotManager( chainParams, getDataDir(), coreVolumes, - archiveVolumes, sharedSpace ? sharedSpace->getPath() : "" ) ); + // snapshotManager.reset( new SnapshotManager( chainParams, getDataDir(), + // coreVolumes, + // archiveVolumes, sharedSpace ? sharedSpace->getPath() : "" ) ); + snapshotManager.reset( new SnapshotManager( + chainParams, getDataDir(), sharedSpace ? sharedSpace->getPath() : "" ) ); } bool downloadGenesisForSyncNode = false; diff --git a/test/unittests/libethereum/ClientTest.cpp b/test/unittests/libethereum/ClientTest.cpp index 9cc2e0b93..47ae0bf90 100644 --- a/test/unittests/libethereum/ClientTest.cpp +++ b/test/unittests/libethereum/ClientTest.cpp @@ -262,7 +262,7 @@ class TestClientSnapshotsFixture : public TestOutputHelperFixture, public Fixtur // ), dir, // dir, chainParams, WithExisting::Kill, {"eth"}, testingMode ) ); std::shared_ptr< SnapshotManager > mgr; - mgr.reset( new SnapshotManager( chainParams, m_tmpDir.path(), { BlockChain::getChainDirName( chainParams ), "vol2", "filestorage"} ) ); + mgr.reset( new SnapshotManager( chainParams, m_tmpDir.path() ) ); // boost::filesystem::create_directory( // m_tmpDir.path() / "vol1" / "12041" ); // boost::filesystem::create_directory( @@ -1030,7 +1030,7 @@ static std::string const c_skaleConfigString = R"E( BOOST_AUTO_TEST_SUITE( ClientSnapshotsSuite, *boost::unit_test::precondition( option_all_tests ) ) -BOOST_AUTO_TEST_CASE( ClientSnapshotsTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( ClientSnapshotsTest, *boost::unit_test::disabled() ) { TestClientSnapshotsFixture fixture( c_skaleConfigString ); ClientTest* testClient = asClientTest( fixture.ethereum() ); diff --git a/test/unittests/libskale/HashSnapshot.cpp b/test/unittests/libskale/HashSnapshot.cpp index 8c61a5ea5..da681b91a 100644 --- a/test/unittests/libskale/HashSnapshot.cpp +++ b/test/unittests/libskale/HashSnapshot.cpp @@ -283,8 +283,7 @@ struct SnapshotHashingFixture : public TestOutputHelperFixture, public FixtureCo // "eth tests", tempDir.path(), "", chainParams, WithExisting::Kill, {"eth"}, // true ) ); - mgr.reset( new SnapshotManager( chainParams, boost::filesystem::path( BTRFS_DIR_PATH ), - {BlockChain::getChainDirName( chainParams ), "filestorage"} ) ); + mgr.reset( new SnapshotManager( chainParams, boost::filesystem::path( BTRFS_DIR_PATH ) ) ); boost::filesystem::create_directory( boost::filesystem::path( BTRFS_DIR_PATH ) / "filestorage" / "test_dir" ); @@ -532,6 +531,13 @@ BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE( HashSnapshotTestSuite, *boost::unit_test::precondition( option_all_test ) ) +#define WAIT_FOR_THE_NEXT_BLOCK() { \ + auto bn = client->number(); \ + while ( client->number() == bn ) { \ + usleep( 100 ); \ + } \ +} + BOOST_FIXTURE_TEST_CASE( SnapshotHashingTest, SnapshotHashingFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { auto senderAddress = coinbase.address(); @@ -542,21 +548,26 @@ BOOST_FIXTURE_TEST_CASE( SnapshotHashingTest, SnapshotHashingFixture, t["to"] = toJS( receiver.address() ); t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); + BOOST_REQUIRE( client->getLatestSnapshotBlockNumer() == -1 ); + // Mine to generate a non-zero account balance const int blocksToMine = 1; dev::eth::simulateMining( *( client ), blocksToMine ); mgr->doSnapshot( 1 ); mgr->computeSnapshotHash( 1 ); + BOOST_REQUIRE( mgr->isSnapshotHashPresent( 1 ) ); - dev::eth::simulateMining( *( client ), blocksToMine ); - mgr->doSnapshot( 2 ); + BOOST_REQUIRE( client->number() == 1 ); + WAIT_FOR_THE_NEXT_BLOCK(); + mgr->doSnapshot( 2 ); mgr->computeSnapshotHash( 2 ); - - BOOST_REQUIRE( mgr->isSnapshotHashPresent( 1 ) ); BOOST_REQUIRE( mgr->isSnapshotHashPresent( 2 ) ); + BOOST_REQUIRE( client->number() == 2 ); + WAIT_FOR_THE_NEXT_BLOCK(); + auto hash1 = mgr->getSnapshotHash( 1 ); auto hash2 = mgr->getSnapshotHash( 2 ); @@ -567,25 +578,30 @@ BOOST_FIXTURE_TEST_CASE( SnapshotHashingTest, SnapshotHashingFixture, BOOST_REQUIRE_THROW( mgr->getSnapshotHash( 3 ), SnapshotManager::SnapshotAbsent ); // TODO check hash absence separately -} -BOOST_FIXTURE_TEST_CASE( SnapshotHashingFileStorageTest, SnapshotHashingFixture, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - mgr->doSnapshot( 4 ); + BOOST_REQUIRE( client->number() == 3 ); + WAIT_FOR_THE_NEXT_BLOCK(); + + mgr->doSnapshot( 3 ); + + mgr->computeSnapshotHash( 3, true ); + + BOOST_REQUIRE( mgr->isSnapshotHashPresent( 3 ) ); - mgr->computeSnapshotHash( 4, true ); + dev::h256 hash3_dbl = mgr->getSnapshotHash( 3 ); - BOOST_REQUIRE( mgr->isSnapshotHashPresent( 4 ) ); + mgr->computeSnapshotHash( 3 ); - dev::h256 hash4_dbl = mgr->getSnapshotHash( 4 ); + BOOST_REQUIRE( mgr->isSnapshotHashPresent( 3 ) ); - mgr->computeSnapshotHash( 4 ); + dev::h256 hash3 = mgr->getSnapshotHash( 3 ); - BOOST_REQUIRE( mgr->isSnapshotHashPresent( 4 ) ); + BOOST_REQUIRE( hash3_dbl == hash3 ); - dev::h256 hash4 = mgr->getSnapshotHash( 4 ); + dev::h256 hash = client->hashFromNumber( 3 ); + uint64_t timestampFromBlockchain = client->blockInfo( hash ).timestamp(); - BOOST_REQUIRE( hash4_dbl == hash4 ); + BOOST_REQUIRE_EQUAL( timestampFromBlockchain, mgr->getBlockTimestamp( 3 ) ); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unittests/libskale/SnapshotManager.cpp b/test/unittests/libskale/SnapshotManager.cpp index b0cfc046f..b96a7f88a 100644 --- a/test/unittests/libskale/SnapshotManager.cpp +++ b/test/unittests/libskale/SnapshotManager.cpp @@ -160,13 +160,15 @@ BOOST_AUTO_TEST_SUITE( BtrfsTestSuite, BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); + SnapshotManager mgr( dev::eth::ChainParams{}, fs::path( BTRFS_DIR_PATH ) ); + + std::string chainDirName = dev::eth::BlockChain::getChainDirName( dev::eth::ChainParams() ); // add files 1 - fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d11" ); - fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol2" / "d21" ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol2" / "d21" ) ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / chainDirName / "d11" ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "filestorage" / "d21" ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / chainDirName / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "filestorage" / "d21" ) ); auto latest0 = mgr.getLatestSnapshots(); std::pair< int, int > expected0 { 0, 0 }; @@ -174,14 +176,14 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, // create snapshot 1 and check its presense mgr.doSnapshot( 1 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol1" / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol2" / "d21" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" / "d21" ) ); // add and remove something - fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d12" ); - fs::remove( fs::path( BTRFS_DIR_PATH ) / "vol2" / "d21" ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d12" ) ); - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol2" / "d21" ) ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / chainDirName / "d12" ); + fs::remove( fs::path( BTRFS_DIR_PATH ) / "filestorage" / "d21" ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / chainDirName / "d12" ) ); + BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "filestorage" / "d21" ) ); auto latest1 = mgr.getLatestSnapshots(); std::pair< int, int > expected1 { 0, 1 }; @@ -189,31 +191,31 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, // create snapshot 2 and check files 1 and files 2 mgr.doSnapshot( 2 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "vol1" / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "vol1" / "d12" ) ); - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "vol2" / "d21" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d12" ) ); + BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "filestorage" / "d21" ) ); // check that files appear/disappear on restore mgr.restoreSnapshot( 1 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol2" / "d21" ) ); - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d12" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / chainDirName / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "filestorage" / "d21" ) ); + BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / chainDirName / "d12" ) ); fs::path diff12 = mgr.makeOrGetDiff( 2 ); - btrfs.subvolume._delete( ( BTRFS_DIR_PATH + "/snapshots/2/vol1" ).c_str() ); - btrfs.subvolume._delete( ( BTRFS_DIR_PATH + "/snapshots/2/vol2" ).c_str() ); + btrfs.subvolume._delete( ( BTRFS_DIR_PATH + "/snapshots/2/" + chainDirName ).c_str() ); + btrfs.subvolume._delete( ( BTRFS_DIR_PATH + "/snapshots/2/filestorage" ).c_str() ); fs::remove_all( BTRFS_DIR_PATH + "/snapshots/2" ); BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" ) ); mgr.importDiff( 2 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "vol1" / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "vol1" / "d12" ) ); - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "vol2" / "d21" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d12" ) ); + BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "filestorage" / "d21" ) ); mgr.restoreSnapshot( 2 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d12" ) ); - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol2" / "d21" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / chainDirName / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / chainDirName / "d12" ) ); + BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "filestorage" / "d21" ) ); auto latest2 = mgr.getLatestSnapshots(); std::pair< int, int > expected2 { 1, 2 }; @@ -231,14 +233,14 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, BOOST_FIXTURE_TEST_CASE( NoBtrfsTest, NoBtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - BOOST_REQUIRE_THROW( SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ), + BOOST_REQUIRE_THROW( SnapshotManager mgr( dev::eth::ChainParams{}, fs::path( BTRFS_DIR_PATH ) ), SnapshotManager::CannotPerformBtrfsOperation ); } BOOST_FIXTURE_TEST_CASE( BadPathTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { BOOST_REQUIRE_EXCEPTION( - SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ) / "_invalid", {"vol1", "vol2"} ), + SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ) / "_invalid" ), SnapshotManager::InvalidPath, [this]( const SnapshotManager::InvalidPath& ex ) -> bool { return ex.path == fs::path( BTRFS_DIR_PATH ) / "_invalid"; } ); @@ -246,14 +248,16 @@ BOOST_FIXTURE_TEST_CASE( BadPathTest, BtrfsFixture, BOOST_FIXTURE_TEST_CASE( InaccessiblePathTest, BtrfsFixture, *boost::unit_test::precondition( []( unsigned long ) -> bool { return false; } ) ) { + std::string chainDirName = dev::eth::BlockChain::getChainDirName( dev::eth::ChainParams() ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "_no_w" ); chmod( ( BTRFS_DIR_PATH + "/_no_w" ).c_str(), 0775 ); - fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "_no_w" / "vol1" ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "_no_w" / chainDirName ); chmod( ( BTRFS_DIR_PATH + "/_no_w/vol1" ).c_str(), 0777 ); fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "_no_x" ); chmod( ( BTRFS_DIR_PATH + "/_no_x" ).c_str(), 0774 ); - fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "_no_x" / "vol1" ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "_no_x" / chainDirName ); chmod( ( BTRFS_DIR_PATH + "/_no_x/vol1" ).c_str(), 0777 ); fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "_no_r" ); @@ -267,17 +271,17 @@ BOOST_FIXTURE_TEST_CASE( InaccessiblePathTest, BtrfsFixture, dropRoot(); - BOOST_REQUIRE_EXCEPTION( SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ) / "_no_w", {"vol1"} ), + BOOST_REQUIRE_EXCEPTION( SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ) / "_no_w" ), SnapshotManager::CannotCreate, [this]( const SnapshotManager::CannotCreate& ex ) -> bool { return ex.path == fs::path( BTRFS_DIR_PATH ) / "_no_w" / "snapshots"; } ); - BOOST_REQUIRE_EXCEPTION( SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ) / "_no_x", {"vol1"} ), + BOOST_REQUIRE_EXCEPTION( SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ) / "_no_x" ), SnapshotManager::CannotCreate, [this]( const SnapshotManager::CannotCreate& ex ) -> bool { return ex.path == fs::path( BTRFS_DIR_PATH ) / "_no_x" / "snapshots"; } ); - BOOST_REQUIRE_EXCEPTION( SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ) / "_no_r", {"vol1"} ), + BOOST_REQUIRE_EXCEPTION( SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ) / "_no_r" ), SnapshotManager::CannotCreate, [this]( const SnapshotManager::CannotCreate& ex ) -> bool { return ex.path == fs::path( BTRFS_DIR_PATH ) / "_no_x" / "snapshots"; } ); @@ -285,7 +289,7 @@ BOOST_FIXTURE_TEST_CASE( InaccessiblePathTest, BtrfsFixture, BOOST_FIXTURE_TEST_CASE( SnapshotTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); + SnapshotManager mgr( dev::eth::ChainParams{}, fs::path( BTRFS_DIR_PATH ) ); BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2 ) ); BOOST_REQUIRE_THROW( mgr.doSnapshot( 2 ), SnapshotManager::SnapshotPresent ); @@ -314,7 +318,7 @@ BOOST_FIXTURE_TEST_CASE( SnapshotTest, BtrfsFixture, BOOST_FIXTURE_TEST_CASE( RestoreTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); + SnapshotManager mgr( dev::eth::ChainParams{}, fs::path( BTRFS_DIR_PATH ) ); BOOST_REQUIRE_THROW( mgr.restoreSnapshot( 2 ), SnapshotManager::SnapshotAbsent ); @@ -324,15 +328,15 @@ BOOST_FIXTURE_TEST_CASE( RestoreTest, BtrfsFixture, BOOST_REQUIRE_EQUAL( 0, btrfs.subvolume._delete( - ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "vol1" ).c_str() ) ); + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "filestorage" ).c_str() ) ); BOOST_REQUIRE_THROW( mgr.restoreSnapshot( 2 ), SnapshotManager::CannotPerformBtrfsOperation ); } BOOST_FIXTURE_TEST_CASE( DiffTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); + SnapshotManager mgr( dev::eth::ChainParams{}, fs::path( BTRFS_DIR_PATH ) ); mgr.doSnapshot( 2 ); - fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol1" / "dir" ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "filestorage" / "dir" ); mgr.doSnapshot( 4 ); BOOST_REQUIRE_THROW( mgr.makeOrGetDiff( 3 ), SnapshotManager::SnapshotAbsent ); @@ -353,7 +357,7 @@ BOOST_FIXTURE_TEST_CASE( DiffTest, BtrfsFixture, BOOST_REQUIRE_GT( fs::file_size( tmp ), 0 ); fs::remove( tmp ); - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "vol1" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "filestorage" ).c_str() ); BOOST_REQUIRE_THROW( tmp = mgr.makeOrGetDiff( 4 ), SnapshotManager::CannotPerformBtrfsOperation ); @@ -363,7 +367,7 @@ BOOST_FIXTURE_TEST_CASE( DiffTest, BtrfsFixture, BOOST_FIXTURE_TEST_CASE( ImportTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); + SnapshotManager mgr( dev::eth::ChainParams{}, fs::path( BTRFS_DIR_PATH ) ); BOOST_REQUIRE_THROW( mgr.importDiff( 8 ), SnapshotManager::InvalidPath ); @@ -375,24 +379,26 @@ BOOST_FIXTURE_TEST_CASE( ImportTest, BtrfsFixture, BOOST_REQUIRE_THROW( mgr.importDiff( 4 ), SnapshotManager::SnapshotPresent ); + std::string chainDirName = dev::eth::BlockChain::getChainDirName( dev::eth::ChainParams() ); + // delete dest - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "vol1" ).c_str() ); - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "vol2" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / chainDirName ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "filestorage" ).c_str() ); fs::remove_all( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" ); BOOST_REQUIRE_NO_THROW( mgr.importDiff( 4 ) ); // delete dest - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "vol1" ).c_str() ); - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "vol2" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / chainDirName ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "filestorage" ).c_str() ); fs::remove_all( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" ); // no source - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "vol1" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName ).c_str() ); // BOOST_REQUIRE_THROW( mgr.importDiff( 2, 4 ), SnapshotManager::CannotPerformBtrfsOperation ); - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "vol2" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "filestorage" ).c_str() ); fs::remove_all( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" ); // BOOST_REQUIRE_THROW( mgr.importDiff( 2, 4 ), SnapshotManager::CannotPerformBtrfsOperation ); } @@ -400,7 +406,7 @@ BOOST_FIXTURE_TEST_CASE( ImportTest, BtrfsFixture, BOOST_FIXTURE_TEST_CASE( SnapshotRotationTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); + SnapshotManager mgr( dev::eth::ChainParams{}, fs::path( BTRFS_DIR_PATH ) ); BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 1 ) ); sleep( 1 ); @@ -421,7 +427,7 @@ BOOST_FIXTURE_TEST_CASE( SnapshotRotationTest, BtrfsFixture, BOOST_FIXTURE_TEST_CASE( DiffRotationTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); + SnapshotManager mgr( dev::eth::ChainParams{}, fs::path( BTRFS_DIR_PATH ) ); fs::path diff12 = mgr.getDiffPath( 2 ); { @@ -451,7 +457,7 @@ BOOST_FIXTURE_TEST_CASE( DiffRotationTest, BtrfsFixture, BOOST_FIXTURE_TEST_CASE( RemoveSnapshotTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); + SnapshotManager mgr( dev::eth::ChainParams{}, fs::path( BTRFS_DIR_PATH ) ); mgr.doSnapshot( 1 ); mgr.doSnapshot( 2 ); @@ -469,7 +475,7 @@ BOOST_FIXTURE_TEST_CASE( RemoveSnapshotTest, BtrfsFixture, BOOST_FIXTURE_TEST_CASE( CleanupTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - SnapshotManager mgr( dev::eth::ChainParams(), fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); + SnapshotManager mgr( dev::eth::ChainParams{}, fs::path( BTRFS_DIR_PATH ) ); mgr.doSnapshot( 1 ); mgr.doSnapshot( 2 ); @@ -482,51 +488,57 @@ BOOST_FIXTURE_TEST_CASE( CleanupTest, BtrfsFixture, BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "diffs" ) ); - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol1" ) ); - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol2" ) ); + std::string chainDirName = dev::eth::BlockChain::getChainDirName( dev::eth::ChainParams() ); + + BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / chainDirName ) ); + BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "filestorage" ) ); } +#ifdef HISTORIC_STATE BOOST_FIXTURE_TEST_CASE( ArchiveNodeTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { auto chainParams = dev::eth::ChainParams(); chainParams.nodeInfo.archiveMode = true; - SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"}, {"vol3", "vol4"} ); + SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ); + + std::string chainDirName = dev::eth::BlockChain::getChainDirName( dev::eth::ChainParams() ); // add files to core volumes - fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d11" ); - fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol2" / "d21" ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol1" / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol2" / "d21" ) ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / chainDirName / "d11" ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "filestorage" / "d21" ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / chainDirName / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "filestorage" / "d21" ) ); // archive part - fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol3" / "d31" ); - fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol4" / "d41" ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol3" / "d31" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "vol4" / "d41" ) ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "historic_roots" / "d31" ); + fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "historic_state" / "d41" ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "historic_roots" / "d31" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "historic_state" / "d41" ) ); // create snapshot 1 and check its presense mgr.doSnapshot( 1 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol1" / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol2" / "d21" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol3" / "d31" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol4" / "d41" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" / "d21" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_roots" / "d31" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_state" / "d41" ) ); // make diff for archive node BOOST_REQUIRE_NO_THROW( mgr.makeOrGetDiff( 1, true ) ); // delete dest - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol1" ).c_str() ); - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol2" ).c_str() ); - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol3" ).c_str() ); - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol4" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_roots" ).c_str() ); + btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_state" ).c_str() ); fs::remove_all( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" ); BOOST_REQUIRE_NO_THROW( mgr.importDiff( 1 ) ); // mgr.importDiff( 1 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol1" / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol2" / "d21" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol3" / "d31" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "vol4" / "d41" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName / "d11" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" / "d21" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_roots" / "d31" ) ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_state" / "d41" ) ); } +#endif BOOST_AUTO_TEST_SUITE_END() From f5697cc77e2184e105deb72f8237a467e7368939 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Thu, 25 Jul 2024 12:48:34 +0100 Subject: [PATCH 21/47] IS 968 format --- libskale/SnapshotManager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index d345beca0..325e9d368 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -757,8 +757,8 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki for ( const auto& volume : volumes ) { int res = btrfs.subvolume.property_set( - ( this->snapshotsDir / std::to_string( _blockNumber ) / volume ).string().c_str(), - "ro", "false" ); + ( this->snapshotsDir / std::to_string( _blockNumber ) / volume ).string().c_str(), "ro", + "false" ); if ( res != 0 ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); @@ -772,8 +772,8 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki for ( const auto& volume : volumes ) { int res = btrfs.subvolume.property_set( - ( this->snapshotsDir / std::to_string( _blockNumber ) / volume ).string().c_str(), - "ro", "true" ); + ( this->snapshotsDir / std::to_string( _blockNumber ) / volume ).string().c_str(), "ro", + "true" ); if ( res != 0 ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); From 37cd3305fa84b1d8c34e240672ec51d977049ad7 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Thu, 25 Jul 2024 13:59:27 +0100 Subject: [PATCH 22/47] IS 968 small improvements --- libskale/SnapshotManager.h | 3 --- skaled/main.cpp | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/libskale/SnapshotManager.h b/libskale/SnapshotManager.h index 3e9085438..2f8db6580 100644 --- a/libskale/SnapshotManager.h +++ b/libskale/SnapshotManager.h @@ -184,9 +184,6 @@ class SnapshotManager { boost::filesystem::path snapshotsDir; boost::filesystem::path diffsDir; - // std::array< std::string, 4 > coreVolumes; - // std::array< std::string, 2 > archiveVolumes; - static const std::string snapshotHashFileName; static const std::string partialSnapshotHashFileName; mutable std::mutex hashFileMutex; diff --git a/skaled/main.cpp b/skaled/main.cpp index 1f487681a..c265fba08 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1656,9 +1656,9 @@ int main( int argc, char** argv ) try { // sleep before send skale_getSnapshot again - will receive error clog( VerbosityInfo, "main" ) << std::string( "Will sleep for " ) - << chainParams.sChain.snapshotDownloadTimeout + << chainParams.sChain.snapshotDownloadInactiveTimeout << std::string( " seconds before downloading 0 snapshot" ); - sleep( chainParams.sChain.snapshotDownloadTimeout ); + sleep( chainParams.sChain.snapshotDownloadInactiveTimeout ); downloadAndProccessSnapshot( snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); From ef43668bdf978f90df3efda81009d215bfba71c1 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Thu, 25 Jul 2024 15:15:04 +0100 Subject: [PATCH 23/47] IS 968 disable tessts --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 98f92a5ba..b9c68c873 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -213,7 +213,7 @@ jobs: run_test ConsensusTests sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t BtrfsTestSuite -- --all && touch /tmp/tests/BtrfsTestSuitePassed sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t HashSnapshotTestSuite -- --all && touch /tmp/tests/HashSnapshotTestSuitePassed - sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all && touch /tmp/tests/ClientSnapshotsSuitePassed +# sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all && touch /tmp/tests/ClientSnapshotsSuitePassed cd .. - name: Testeth verbosity 4 run : | @@ -264,7 +264,7 @@ jobs: rerun_test ConsensusTests ls /tmp/tests/BtrfsTestSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t BtrfsTestSuite -- --all --verbosity 4 ls /tmp/tests/HashSnapshotTestSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t HashSnapshotTestSuite -- --all --verbosity 4 - ls /tmp/tests/ClientSnapshotsSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all --verbosity 4 +# ls /tmp/tests/ClientSnapshotsSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all --verbosity 4 cd .. - name: Configure all as historic From b6f68741f688059d2a20168c354a78dc31f775d2 Mon Sep 17 00:00:00 2001 From: Oleh Date: Fri, 26 Jul 2024 16:07:40 +0100 Subject: [PATCH 24/47] fix yml tests --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b9c68c873..afe1973dc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -213,7 +213,7 @@ jobs: run_test ConsensusTests sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t BtrfsTestSuite -- --all && touch /tmp/tests/BtrfsTestSuitePassed sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t HashSnapshotTestSuite -- --all && touch /tmp/tests/HashSnapshotTestSuitePassed -# sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all && touch /tmp/tests/ClientSnapshotsSuitePassed + # sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all && touch /tmp/tests/ClientSnapshotsSuitePassed cd .. - name: Testeth verbosity 4 run : | @@ -264,7 +264,7 @@ jobs: rerun_test ConsensusTests ls /tmp/tests/BtrfsTestSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t BtrfsTestSuite -- --all --verbosity 4 ls /tmp/tests/HashSnapshotTestSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t HashSnapshotTestSuite -- --all --verbosity 4 -# ls /tmp/tests/ClientSnapshotsSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all --verbosity 4 + # ls /tmp/tests/ClientSnapshotsSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all --verbosity 4 cd .. - name: Configure all as historic From 032df80b9c4f0d1e965977f26121e54ab0bd7d3c Mon Sep 17 00:00:00 2001 From: DmytroNazarenko Date: Fri, 27 Sep 2024 15:29:25 +0000 Subject: [PATCH 25/47] IS-894 Reenable state root check --- libethereum/SkaleHost.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libethereum/SkaleHost.cpp b/libethereum/SkaleHost.cpp index 47714ebfe..692b934e1 100644 --- a/libethereum/SkaleHost.cpp +++ b/libethereum/SkaleHost.cpp @@ -601,8 +601,7 @@ void SkaleHost::createBlock( const ConsensusExtFace::transactions_vector& _appro << stCurrent.hex(); // FATAL if mismatch in non-default - if ( _winningNodeIndex != 0 && dev::h256::Arith( stCurrent ) != _stateRoot && - !this->m_client.chainParams().nodeInfo.syncNode ) { + if ( _winningNodeIndex != 0 && dev::h256::Arith( stCurrent ) != _stateRoot ) { LOG( m_errorLogger ) << "FATAL STATE ROOT MISMATCH ERROR: current state root " << dev::h256::Arith( stCurrent ).str() << " is not equal to arrived state root " << _stateRoot.str() From 75549ce338d803de7c508f476919e9facb51d86e Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 8 Oct 2024 10:32:38 +0100 Subject: [PATCH 26/47] IS 968 cleanup --- libethereum/Client.cpp | 40 +++++++------- libweb3jsonrpc/Skale.cpp | 111 ++++++++++++++++++--------------------- 2 files changed, 70 insertions(+), 81 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 1898da6dd..58b034f03 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -799,12 +799,12 @@ void Client::onPostStateChanged() { void Client::startSealing() { if ( m_wouldSeal == true ) return; - LOG( m_logger ) << cc::notice( "Client::startSealing: " ) << author(); + LOG( m_logger ) << "Client::startSealing: " << author(); if ( author() ) { m_wouldSeal = true; m_signalled.notify_all(); } else - LOG( m_logger ) << cc::warn( "You need to set an author in order to seal!" ); + LOG( m_logger ) << "You need to set an author in order to seal!"; } void Client::rejigSealing() { @@ -812,24 +812,24 @@ void Client::rejigSealing() { if ( sealEngine()->shouldSeal( this ) ) { m_wouldButShouldnot = false; - LOG( m_loggerDetail ) << cc::notice( "Rejigging seal engine..." ); + LOG( m_loggerDetail ) << "Rejigging seal engine..."; DEV_WRITE_GUARDED( x_working ) { if ( m_working.isSealed() ) { - LOG( m_logger ) << cc::notice( "Tried to seal sealed block..." ); + LOG( m_logger ) << "Tried to seal sealed block..."; return; } // TODO is that needed? we have "Generating seal on" below - LOG( m_loggerDetail ) << cc::notice( "Starting to seal block" ) << " " - << cc::warn( "#" ) << cc::num10( m_working.info().number() ); + LOG( m_loggerDetail ) << "Starting to seal block" + << " #" << m_working.info().number(); - // TODO Deduplicate code! + // TODO Deduplicate code dev::h256 stateRootToSet; if ( m_snapshotAgent->getLatestSnapshotBlockNumer() > 0 ) { dev::h256 stateRootHash = this->m_snapshotAgent->getSnapshotHash( m_snapshotAgent->getLatestSnapshotBlockNumer(), false ); stateRootToSet = stateRootHash; } - // propagate current! + // propagate current else if ( this->number() > 0 ) { stateRootToSet = blockInfo( this->hashFromNumber( this->number() ) ).stateRoot(); @@ -847,15 +847,15 @@ void Client::rejigSealing() { if ( wouldSeal() ) { sealEngine()->onSealGenerated( [=]( bytes const& _header ) { - LOG( m_logger ) << cc::success( "Block sealed" ) << " " << cc::warn( "#" ) - << cc::num10( BlockHeader( _header, HeaderData ).number() ); + LOG( m_logger ) << "Block sealed" + << " #" << BlockHeader( _header, HeaderData ).number(); if ( this->submitSealed( _header ) ) m_onBlockSealed( _header ); else - LOG( m_logger ) << cc::error( "Submitting block failed..." ); + LOG( m_logger ) << "Submitting block failed..."; } ); - ctrace << cc::notice( "Generating seal on " ) << m_sealingInfo.hash( WithoutSeal ) - << " " << cc::warn( "#" ) << cc::num10( m_sealingInfo.number() ); + ctrace << "Generating seal on " << m_sealingInfo.hash( WithoutSeal ) << " #" + << m_sealingInfo.number(); sealEngine()->generateSeal( m_sealingInfo ); } } else @@ -868,24 +868,24 @@ void Client::rejigSealing() { void Client::sealUnconditionally( bool submitToBlockChain ) { m_wouldButShouldnot = false; - LOG( m_loggerDetail ) << cc::notice( "Rejigging seal engine..." ); + LOG( m_loggerDetail ) << "Rejigging seal engine..."; DEV_WRITE_GUARDED( x_working ) { if ( m_working.isSealed() ) { - LOG( m_logger ) << cc::notice( "Tried to seal sealed block..." ); + LOG( m_logger ) << "Tried to seal sealed block..."; return; } // TODO is that needed? we have "Generating seal on" below - LOG( m_loggerDetail ) << cc::notice( "Starting to seal block" ) << " " << cc::warn( "#" ) - << cc::num10( m_working.info().number() ); - // latest hash is really updated after NEXT snapshot already started hash computation! - // TODO Deduplicate code! + LOG( m_loggerDetail ) << "Starting to seal block" + << " #" << m_working.info().number(); + // latest hash is really updated after NEXT snapshot already started hash computation + // TODO Deduplicate code dev::h256 stateRootToSet; if ( m_snapshotAgent->getLatestSnapshotBlockNumer() > 0 ) { dev::h256 stateRootHash = this->m_snapshotAgent->getSnapshotHash( m_snapshotAgent->getLatestSnapshotBlockNumer(), false ); stateRootToSet = stateRootHash; } - // propagate current! + // propagate current else if ( this->number() > 0 ) { stateRootToSet = blockInfo( this->hashFromNumber( this->number() ) ).stateRoot(); } else { diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index 13881d73f..fd75f856d 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -120,9 +120,9 @@ std::string Skale::skale_shutdownInstance() { std::string s = ex.what(); if ( s.empty() ) s = "no description"; - cerror << "Exception in shutdown event handler: " << s << "\n"; + cerror << "Exception in shutdown event handler: " << s; } catch ( ... ) { - cerror << "Unknown exception in shutdown event handler\n"; + cerror << "Unknown exception in shutdown event handler"; } } // for( auto & fn : g_list_fn_on_shutdown ) g_list_fn_on_shutdown.clear(); @@ -137,7 +137,7 @@ std::string Skale::skale_receiveTransaction( std::string const& _rlp ) { try { return toJS( m_client.skaleHost()->receiveTransaction( _rlp ) ); } catch ( Exception const& ) { - throw jsonrpc::JsonRpcException( exceptionToErrorMessage() ); // TODO test! + throw jsonrpc::JsonRpcException( exceptionToErrorMessage() ); // TODO test } } @@ -218,14 +218,14 @@ nlohmann::json Skale::impl_skale_getSnapshot( const nlohmann::json& joRequest, C } clog( VerbosityInfo, "skale_downloadSnapshotFragmentMonitorThread" ) - << "Unlocking shared space.\n"; + << "Unlocking shared space."; std::lock_guard< std::mutex > lock( m_snapshot_mutex ); if ( currentSnapshotBlockNumber >= 0 ) { try { fs::remove( currentSnapshotPath ); clog( VerbosityInfo, "skale_downloadSnapshotFragmentMonitorThread" ) - << "Deleted snapshot file.\n"; + << "Deleted snapshot file."; } catch ( ... ) { } currentSnapshotBlockNumber = -1; @@ -265,9 +265,6 @@ Json::Value Skale::skale_getSnapshot( const Json::Value& request ) { // std::vector< uint8_t > Skale::ll_impl_skale_downloadSnapshotFragment( const fs::path& fp, size_t idxFrom, size_t sizeOfChunk ) { - // size_t sizeOfFile = fs::file_size( fp ); - // - // std::ifstream f; f.open( fp.native(), std::ios::in | std::ios::binary ); if ( !f.is_open() ) @@ -289,7 +286,7 @@ std::vector< uint8_t > Skale::impl_skale_downloadSnapshotFragmentBinary( } fs::path fp = currentSnapshotPath; - // + size_t idxFrom = joRequest["from"].get< size_t >(); size_t sizeOfChunk = joRequest["size"].get< size_t >(); size_t sizeOfFile = fs::file_size( fp ); @@ -314,7 +311,7 @@ nlohmann::json Skale::impl_skale_downloadSnapshotFragmentJSON( const nlohmann::j "first"; fs::path fp = currentSnapshotPath; - // + size_t idxFrom = joRequest["from"].get< size_t >(); size_t sizeOfChunk = joRequest["size"].get< size_t >(); size_t sizeOfFile = fs::file_size( fp ); @@ -330,8 +327,7 @@ nlohmann::json Skale::impl_skale_downloadSnapshotFragmentJSON( const nlohmann::j if ( sizeOfChunk + idxFrom == sizeOfFile ) clog( VerbosityInfo, "skale_downloadSnapshotFragment" ) - << cc::success( "Sent all chunks for " ) << cc::p( currentSnapshotPath.string() ) - << "\n"; + << "Sent all chunks for " << currentSnapshotPath.string(); joResponse["size"] = sizeOfChunk; joResponse["data"] = strBase64; @@ -406,7 +402,7 @@ Json::Value Skale::skale_getSnapshotSignature( unsigned blockNumber ) { joCall["params"] = obj; - // TODO deduplicate with SkaleHost! + // TODO deduplicate with SkaleHost std::string sgx_cert_path = getenv( "SGX_CERT_FOLDER" ) ? getenv( "SGX_CERT_FOLDER" ) : ""; if ( sgx_cert_path.empty() ) @@ -431,15 +427,15 @@ Json::Value Skale::skale_getSnapshotSignature( unsigned blockNumber ) { bool fl = cli.open( sgxServerURL ); if ( !fl ) { clog( VerbosityError, "skale_getSnapshotSignature" ) - << cc::fatal( "FATAL:" ) - << cc::error( " Exception while trying to connect to sgx server: " ) - << cc::warn( "connection refused" ) << std::endl; + << "FATAL:" + << " Exception while trying to connect to sgx server: " + << "connection refused"; } skutils::rest::data_t d; while ( true ) { - clog( VerbosityInfo, "skale_getSnapshotSignature" ) - << cc::ws_tx( ">>> SGX call >>>" ) << " " << cc::j( joCall ) << std::endl; + clog( VerbosityInfo, "skale_getSnapshotSignature" ) << ">>> SGX call >>>" + << " " << joCall; d = cli.call( joCall ); if ( d.ei_.et_ != skutils::http::common_network_exception::error_type::et_no_error ) { @@ -448,16 +444,15 @@ Json::Value Skale::skale_getSnapshotSignature( unsigned blockNumber ) { d.ei_.et_ == skutils::http::common_network_exception::error_type::et_fatal ) { clog( VerbosityError, "skale_getSnapshotSignature" ) - << cc::error( "ERROR:" ) - << cc::error( " Exception while trying to connect to sgx server: " ) - << cc::error( " error with connection: " ) - << cc::info( " retrying... " ) << std::endl; + << "ERROR:" + << " Exception while trying to connect to sgx server: " + << " error with connection: " + << " retrying... "; } else { clog( VerbosityError, "skale_getSnapshotSignature" ) - << cc::error( "ERROR:" ) - << cc::error( " Exception while trying to connect to sgx server: " ) - << cc::error( " error with ssl certificates " ) - << cc::error( d.ei_.strError_ ) << std::endl; + << "ERROR:" + << " Exception while trying to connect to sgx server: " + << " error with ssl certificates " << d.ei_.strError_; } } else { break; @@ -466,17 +461,16 @@ Json::Value Skale::skale_getSnapshotSignature( unsigned blockNumber ) { if ( d.empty() ) { static const char g_strErrMsg[] = "SGX Server call to blsSignMessageHash failed"; - clog( VerbosityError, "skale_getSnapshotSignature" ) - << cc::error( "!!! SGX call error !!!" ) << " " << cc::error( g_strErrMsg ) - << std::endl; + clog( VerbosityError, "skale_getSnapshotSignature" ) << "!!! SGX call error !!!" + << " " << g_strErrMsg; throw std::runtime_error( g_strErrMsg ); } nlohmann::json joAnswer = nlohmann::json::parse( d.s_ ); nlohmann::json joResponse = ( joAnswer.count( "result" ) > 0 ) ? joAnswer["result"] : joAnswer; - clog( VerbosityInfo, "skale_getSnapshotSignature" ) - << cc::ws_rx( "<<< SGX call <<<" ) << " " << cc::j( joResponse ) << std::endl; + clog( VerbosityInfo, "skale_getSnapshotSignature" ) << "<<< SGX call <<<" + << " " << joResponse; if ( joResponse["status"] != 0 ) { throw std::runtime_error( "SGX Server call to blsSignMessageHash returned non-zero status" ); @@ -598,8 +592,7 @@ bool download( const std::string& strURLWeb3, unsigned& block_number, const fs:: std::ofstream f; try { boost::filesystem::remove( saveTo ); - // - // + if ( block_number == unsigned( -1 ) ) { // this means "latest" skutils::rest::client cli( skutils::rest::g_nClientConnectionTimeoutMS ); @@ -607,8 +600,9 @@ bool download( const std::string& strURLWeb3, unsigned& block_number, const fs:: if ( pStrErrorDescription ) ( *pStrErrorDescription ) = "REST failed to connect to server(1)"; clog( VerbosityError, "download snapshot" ) - << cc::fatal( "FATAL:" ) << " " - << cc::error( "REST failed to connect to server(1)" ) << "\n"; + << "FATAL:" + << " " + << "REST failed to connect to server(1)"; return false; } @@ -620,24 +614,23 @@ bool download( const std::string& strURLWeb3, unsigned& block_number, const fs:: if ( d.empty() ) { if ( pStrErrorDescription ) ( *pStrErrorDescription ) = "Failed to get latest bockNumber"; - clog( VerbosityError, "download snapshot" ) - << cc::fatal( "FATAL:" ) << " " - << cc::error( "Failed to get latest bockNumber" ) << "\n"; + clog( VerbosityError, "download snapshot" ) << "FATAL:" + << " " + << "Failed to get latest bockNumber"; return false; } // TODO catch? nlohmann::json joAnswer = nlohmann::json::parse( d.s_ ); block_number = dev::eth::jsToBlockNumber( joAnswer["result"].get< std::string >() ); } - // - // + skutils::rest::client cli( skutils::rest::g_nClientConnectionTimeoutMS ); if ( !cli.open( strURLWeb3 ) ) { if ( pStrErrorDescription ) ( *pStrErrorDescription ) = "REST failed to connect to server(2)"; - clog( VerbosityError, "download snapshot" ) - << cc::fatal( "FATAL:" ) << " " - << cc::error( "REST failed to connect to server(2)" ) << "\n"; + clog( VerbosityError, "download snapshot" ) << "FATAL:" + << " " + << "REST failed to connect to server(2)"; return false; } @@ -652,21 +645,20 @@ bool download( const std::string& strURLWeb3, unsigned& block_number, const fs:: if ( !d.err_s_.empty() ) { if ( pStrErrorDescription ) ( *pStrErrorDescription ) = "REST call failed: " + d.err_s_; - clog( VerbosityError, "download snapshot" ) - << cc::fatal( "FATAL:" ) << " " << cc::error( "REST call failed: " ) - << cc::warn( d.err_s_ ) << "\n"; + clog( VerbosityError, "download snapshot" ) << "FATAL:" + << " " + << "REST call failed: " << d.err_s_; return false; } if ( d.empty() ) { if ( pStrErrorDescription ) ( *pStrErrorDescription ) = "REST call failed"; - clog( VerbosityError, "download snapshot" ) - << cc::fatal( "FATAL:" ) << " " << cc::error( "REST call failed" ) << "\n"; + clog( VerbosityError, "download snapshot" ) << "FATAL:" + << " " + << "REST call failed"; return false; } - // std::cout << cc::success( "REST call success" ) << "\n" << cc::j( d.s_ ) << "\n"; nlohmann::json joAnswer = nlohmann::json::parse( d.s_ ); - // std::cout << cc::normal( "Got answer(1) " ) << cc::j( joAnswer ) << std::endl; nlohmann::json joSnapshotInfo = joAnswer["result"]; if ( joSnapshotInfo.count( "error" ) > 0 ) { std::string s; @@ -679,16 +671,15 @@ bool download( const std::string& strURLWeb3, unsigned& block_number, const fs:: } if ( pStrErrorDescription ) ( *pStrErrorDescription ) = s; - clog( VerbosityError, "download snapshot" ) - << cc::fatal( "FATAL:" ) << " " << cc::error( s ) << "\n"; + clog( VerbosityError, "download snapshot" ) << "FATAL:" + << " " << s; return false; } size_t sizeOfFile = joSnapshotInfo["dataSize"].get< size_t >(); size_t maxAllowedChunkSize = joSnapshotInfo["maxAllowedChunkSize"].get< size_t >(); size_t idxChunk, cntChunks = sizeOfFile / maxAllowedChunkSize + ( ( ( sizeOfFile % maxAllowedChunkSize ) > 0 ) ? 1 : 0 ); - // - // + f.open( saveTo.native(), std::ios::out | std::ios::binary ); if ( !f.is_open() ) { std::string s; @@ -715,18 +706,16 @@ bool download( const std::string& strURLWeb3, unsigned& block_number, const fs:: if ( pStrErrorDescription ) ( *pStrErrorDescription ) = "REST call failed(fragment downloader)"; clog( VerbosityError, "download snapshot" ) - << cc::fatal( "FATAL:" ) << " " - << cc::error( "REST call failed(fragment downloader)" ) << "\n"; + << "FATAL:" + << " " + << "REST call failed(fragment downloader)"; return false; } std::vector< uint8_t > buffer; if ( isBinaryDownload ) buffer.insert( buffer.end(), d.s_.begin(), d.s_.end() ); else { - // std::cout << cc::success( "REST call success(fragment downloader)" ) << "\n" << nlohmann::json joAnswer = nlohmann::json::parse( d.s_ ); - // std::cout << cc::normal( "Got answer(2) " ) << cc::j( joAnswer ) << std::endl; - // cc::j( d.s_ ) << "\n"; nlohmann::json joFragment = joAnswer["result"]; if ( joFragment.count( "error" ) > 0 ) { std::string s; @@ -734,8 +723,8 @@ bool download( const std::string& strURLWeb3, unsigned& block_number, const fs:: s += joFragment["error"].get< std::string >(); if ( pStrErrorDescription ) ( *pStrErrorDescription ) = s; - clog( VerbosityError, "download snapshot" ) - << cc::fatal( "FATAL:" ) << " " << cc::error( s ) << "\n"; + clog( VerbosityError, "download snapshot" ) << "FATAL:" + << " " << s; return false; } // size_t sizeArrived = joFragment["size"]; From f56a4331a699d272127276b6024470deb6ca82b6 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 8 Oct 2024 11:15:59 +0100 Subject: [PATCH 27/47] IS 968 cleanup --- libskale/SnapshotHashAgent.cpp | 51 ++++++++++++++++++---------------- libskale/SnapshotManager.cpp | 4 +-- skaled/main.cpp | 10 ++----- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/libskale/SnapshotHashAgent.cpp b/libskale/SnapshotHashAgent.cpp index 15d96bffe..fc78fce10 100644 --- a/libskale/SnapshotHashAgent.cpp +++ b/libskale/SnapshotHashAgent.cpp @@ -76,17 +76,18 @@ void SnapshotHashAgent::readPublicKeyFromConfig() { size_t SnapshotHashAgent::verifyAllData() const { size_t verified = 0; for ( size_t i = 0; i < this->n_; ++i ) { - if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { + if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes.at( i ).id ) { continue; } - if ( this->isReceived_[i] ) { + if ( this->isReceived_.at( i ) ) { bool is_verified = false; libff::inhibit_profiling_info = true; try { - is_verified = this->bls_->Verification( - std::make_shared< std::array< uint8_t, 32 > >( this->hashes_[i].asArray() ), - this->signatures_[i], this->public_keys_[i] ); + is_verified = + this->bls_->Verification( std::make_shared< std::array< uint8_t, 32 > >( + this->hashes_.at( i ).asArray() ), + this->signatures_.at( i ), this->public_keys_.at( i ) ); } catch ( std::exception& ex ) { cerror << ex.what(); } @@ -114,11 +115,11 @@ bool SnapshotHashAgent::voteForHash() { const std::lock_guard< std::mutex > lock( this->hashesMutex ); for ( size_t i = 0; i < this->n_; ++i ) { - if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { + if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes.at( i ).id ) { continue; } - map_hash[this->hashes_[i]] += 1; + map_hash[this->hashes_.at( i )] += 1; } std::map< dev::h256, size_t >::iterator it; @@ -136,14 +137,15 @@ bool SnapshotHashAgent::voteForHash() { std::vector< size_t > idx; std::vector< libff::alt_bn128_G1 > signatures; for ( size_t i = 0; i < this->n_; ++i ) { - if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { + if ( this->chainParams_.nodeInfo.id == + this->chainParams_.sChain.nodes.at( i ).id ) { continue; } - if ( this->hashes_[i] == ( *it ).first ) { + if ( this->hashes_.at( i ) == ( *it ).first ) { this->nodesToDownloadSnapshotFrom_.push_back( i ); idx.push_back( i + 1 ); - signatures.push_back( this->signatures_[i] ); + signatures.push_back( this->signatures_.at( i ) ); } } @@ -303,23 +305,24 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( if ( urlToDownloadSnapshotFrom_.empty() ) { for ( size_t i = 0; i < this->n_; ++i ) { - if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes[i].id ) { + if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes.at( i ).id ) { continue; } threads.push_back( std::thread( [this, i, blockNumber]() { try { - std::string nodeUrl = - "http://" + this->chainParams_.sChain.nodes[i].ip + ':' + - ( this->chainParams_.sChain.nodes[i].port + 3 ).convert_to< std::string >(); + std::string nodeUrl = "http://" + this->chainParams_.sChain.nodes.at( i ).ip + + ':' + + ( this->chainParams_.sChain.nodes.at( i ).port + 3 ) + .convert_to< std::string >(); auto snapshotData = askNodeForHash( nodeUrl, blockNumber ); if ( std::get< 0 >( snapshotData ).size ) { const std::lock_guard< std::mutex > lock( this->hashesMutex ); - this->isReceived_[i] = true; - this->hashes_[i] = std::get< 0 >( snapshotData ); - this->signatures_[i] = std::get< 1 >( snapshotData ); - this->public_keys_[i] = std::get< 2 >( snapshotData ); + this->isReceived_.at( i ) = true; + this->hashes_.at( i ) = std::get< 0 >( snapshotData ); + this->signatures_.at( i ) = std::get< 1 >( snapshotData ); + this->public_keys_.at( i ) = std::get< 2 >( snapshotData ); } } catch ( std::exception& ex ) { cerror << "Exception while collecting snapshot signatures from other skaleds: " @@ -344,20 +347,20 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( auto majorityNodesIds = AmsterdamFixPatch::majorityNodesIds(); dev::h256 common_hash; // should be same everywhere! for ( size_t pos = 0; pos < this->n_; ++pos ) { - if ( !this->isReceived_[pos] ) + if ( !this->isReceived_.at( pos ) ) continue; - u256 id = this->chainParams_.sChain.nodes[pos].id; + u256 id = this->chainParams_.sChain.nodes.at( pos ).id; bool good = majorityNodesIds.end() != std::find( majorityNodesIds.begin(), majorityNodesIds.end(), id ); if ( !good ) continue; if ( common_hash == dev::h256() ) { - common_hash = this->hashes_[pos]; + common_hash = this->hashes_.at( pos ); this->voted_hash_.first = common_hash; // .second will ne ignored! - } else if ( this->hashes_[pos] != common_hash ) { + } else if ( this->hashes_.at( pos ) != common_hash ) { result = false; break; } @@ -383,9 +386,9 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( std::vector< std::string > ret; for ( const size_t idx : this->nodesToDownloadSnapshotFrom_ ) { std::string ret_value = - std::string( "http://" ) + std::string( this->chainParams_.sChain.nodes[idx].ip ) + + std::string( "http://" ) + std::string( this->chainParams_.sChain.nodes.at( idx ).ip ) + std::string( ":" ) + - ( this->chainParams_.sChain.nodes[idx].port + 3 ).convert_to< std::string >(); + ( this->chainParams_.sChain.nodes.at( idx ).port + 3 ).convert_to< std::string >(); ret.push_back( ret_value ); } diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 325e9d368..f03c2c6d3 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -809,7 +809,7 @@ uint64_t SnapshotManager::getBlockTimestamp( unsigned _blockNumber ) const { fs::path db_dir = this->snapshotsDir / std::to_string( _blockNumber ); int res = - btrfs.subvolume.property_set( ( db_dir / coreVolumes[0] ).string().c_str(), "ro", "false" ); + btrfs.subvolume.property_set( ( db_dir / coreVolumes.at( 0 ) ).string().c_str(), "ro", "false" ); if ( res != 0 ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); @@ -820,7 +820,7 @@ uint64_t SnapshotManager::getBlockTimestamp( unsigned _blockNumber ) const { uint64_t timestamp = dev::eth::BlockHeader( bc.block( hash ) ).timestamp(); res = - btrfs.subvolume.property_set( ( db_dir / coreVolumes[0] ).string().c_str(), "ro", "true" ); + btrfs.subvolume.property_set( ( db_dir / coreVolumes.at( 0 ) ).string().c_str(), "ro", "true" ); if ( res != 0 ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); diff --git a/skaled/main.cpp b/skaled/main.cpp index c265fba08..8886922ad 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -519,9 +519,9 @@ void downloadAndProccessSnapshot( std::shared_ptr< SnapshotManager >& snapshotMa continue; std::string nodeUrl = - std::string( "http://" ) + std::string( chainParams.sChain.nodes[idx].ip ) + + std::string( "http://" ) + std::string( chainParams.sChain.nodes.at( idx ).ip ) + std::string( ":" ) + - ( chainParams.sChain.nodes[idx].port + 3 ).convert_to< std::string >(); + ( chainParams.sChain.nodes.at( idx ).port + 3 ).convert_to< std::string >(); successfullDownload = downloadSnapshotFromUrl( snapshotManager, chainParams, arrayCommonPublicKey, nodeUrl, isRegularSnapshot ); @@ -1607,9 +1607,6 @@ int main( int argc, char** argv ) try { archiveVolumes.insert( archiveVolumes.end(), { "historic_roots", "historic_state" } ); #endif } - // snapshotManager.reset( new SnapshotManager( chainParams, getDataDir(), - // coreVolumes, - // archiveVolumes, sharedSpace ? sharedSpace->getPath() : "" ) ); snapshotManager.reset( new SnapshotManager( chainParams, getDataDir(), sharedSpace ? sharedSpace->getPath() : "" ) ); } @@ -1644,8 +1641,7 @@ int main( int argc, char** argv ) try { snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); snapshotManager->restoreSnapshot( 0 ); } catch ( SnapshotManager::SnapshotAbsent& ) { - clog( VerbosityWarning, "main" ) - << cc::warn( "Snapshot for 0 block is not found" ); + clog( VerbosityWarning, "main" ) << "Snapshot for 0 block is not found"; } } From 2c576564cb149ee7347450e2f53329072a7400f3 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 8 Oct 2024 11:19:41 +0100 Subject: [PATCH 28/47] IS 968 cleanup --- libskale/SnapshotManager.cpp | 8 ++++---- skaled/main.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index f03c2c6d3..d85225fb4 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -808,8 +808,8 @@ uint64_t SnapshotManager::getBlockTimestamp( unsigned _blockNumber ) const { fs::path db_dir = this->snapshotsDir / std::to_string( _blockNumber ); - int res = - btrfs.subvolume.property_set( ( db_dir / coreVolumes.at( 0 ) ).string().c_str(), "ro", "false" ); + int res = btrfs.subvolume.property_set( + ( db_dir / coreVolumes.at( 0 ) ).string().c_str(), "ro", "false" ); if ( res != 0 ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); @@ -819,8 +819,8 @@ uint64_t SnapshotManager::getBlockTimestamp( unsigned _blockNumber ) const { dev::h256 hash = bc.numberHash( _blockNumber ); uint64_t timestamp = dev::eth::BlockHeader( bc.block( hash ) ).timestamp(); - res = - btrfs.subvolume.property_set( ( db_dir / coreVolumes.at( 0 ) ).string().c_str(), "ro", "true" ); + res = btrfs.subvolume.property_set( + ( db_dir / coreVolumes.at( 0 ) ).string().c_str(), "ro", "true" ); if ( res != 0 ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); diff --git a/skaled/main.cpp b/skaled/main.cpp index 8886922ad..34661362b 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -519,8 +519,8 @@ void downloadAndProccessSnapshot( std::shared_ptr< SnapshotManager >& snapshotMa continue; std::string nodeUrl = - std::string( "http://" ) + std::string( chainParams.sChain.nodes.at( idx ).ip ) + - std::string( ":" ) + + std::string( "http://" ) + + std::string( chainParams.sChain.nodes.at( idx ).ip ) + std::string( ":" ) + ( chainParams.sChain.nodes.at( idx ).port + 3 ).convert_to< std::string >(); successfullDownload = downloadSnapshotFromUrl( snapshotManager, chainParams, From b924d007cf28d0849af0c91db6a3df809eb24d90 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 8 Oct 2024 18:51:18 +0100 Subject: [PATCH 29/47] IS 968 cleanup --- libethereum/Client.h | 5 +- libethereum/SnapshotAgent.cpp | 6 +- libethereum/SnapshotAgent.h | 3 +- libskale/SnapshotHashAgent.cpp | 176 ++++++++++------------- libskale/SnapshotHashAgent.h | 4 +- libskale/SnapshotManager.cpp | 11 +- libskale/SnapshotManager.h | 2 +- libweb3jsonrpc/Skale.cpp | 6 +- skaled/main.cpp | 15 +- test/unittests/libskale/HashSnapshot.cpp | 2 +- 10 files changed, 100 insertions(+), 130 deletions(-) diff --git a/libethereum/Client.h b/libethereum/Client.h index 83264c93f..dd5045285 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -293,9 +293,8 @@ class Client : public ClientBase, protected Worker { size_t importTransactionsAsBlock( const Transactions& _transactions, u256 _gasPrice, uint64_t _timestamp = ( uint64_t ) utcTime() ); - boost::filesystem::path createSnapshotFile( - unsigned _blockNumber, bool _forArchiveNode = false ) { - return m_snapshotAgent->createSnapshotFile( _blockNumber, _forArchiveNode ); + boost::filesystem::path createSnapshotFile( unsigned _blockNumber ) { + return m_snapshotAgent->createSnapshotFile( _blockNumber ); } // set exiting time for node rotation diff --git a/libethereum/SnapshotAgent.cpp b/libethereum/SnapshotAgent.cpp index 19bd43ccc..4998208b6 100644 --- a/libethereum/SnapshotAgent.cpp +++ b/libethereum/SnapshotAgent.cpp @@ -137,12 +137,10 @@ void SnapshotAgent::doSnapshotIfNeeded( unsigned _currentBlockNumber, int64_t _t } // if thread } -boost::filesystem::path SnapshotAgent::createSnapshotFile( - unsigned _blockNumber, bool _forArchiveNode ) { +boost::filesystem::path SnapshotAgent::createSnapshotFile( unsigned _blockNumber ) { if ( _blockNumber > this->getLatestSnapshotBlockNumer() && _blockNumber != 0 ) throw std::invalid_argument( "Too new snapshot requested" ); - boost::filesystem::path path = - m_snapshotManager->makeOrGetDiff( _blockNumber, _forArchiveNode ); + boost::filesystem::path path = m_snapshotManager->makeOrGetDiff( _blockNumber ); // TODO Make constant 2 configurable m_snapshotManager->leaveNLastDiffs( 2 ); return path; diff --git a/libethereum/SnapshotAgent.h b/libethereum/SnapshotAgent.h index e9914cb3f..79e46b6e4 100644 --- a/libethereum/SnapshotAgent.h +++ b/libethereum/SnapshotAgent.h @@ -26,8 +26,7 @@ class SnapshotAgent { void finishHashComputingAndUpdateHashesIfNeeded( int64_t _timestamp ); void doSnapshotIfNeeded( unsigned _currentBlockNumber, int64_t _timestamp ); - boost::filesystem::path createSnapshotFile( - unsigned _blockNumber, bool _forArchiveNode = false ); + boost::filesystem::path createSnapshotFile( unsigned _blockNumber ); void terminate(); diff --git a/libskale/SnapshotHashAgent.cpp b/libskale/SnapshotHashAgent.cpp index fc78fce10..4afc006c7 100644 --- a/libskale/SnapshotHashAgent.cpp +++ b/libskale/SnapshotHashAgent.cpp @@ -123,118 +123,95 @@ bool SnapshotHashAgent::voteForHash() { } std::map< dev::h256, size_t >::iterator it; - if ( urlToDownloadSnapshotFrom_.empty() ) { - it = std::find_if( - map_hash.begin(), map_hash.end(), [this]( const std::pair< dev::h256, size_t > p ) { - return 3 * p.second > 2 * this->n_; - } ); - cnote << "Snapshot hash is: " << ( *it ).first << " .Verifying it...\n"; - - if ( it == map_hash.end() ) { - throw NotEnoughVotesException( "note enough votes to choose hash" ); - return false; - } else { - std::vector< size_t > idx; - std::vector< libff::alt_bn128_G1 > signatures; - for ( size_t i = 0; i < this->n_; ++i ) { - if ( this->chainParams_.nodeInfo.id == - this->chainParams_.sChain.nodes.at( i ).id ) { - continue; - } + it = std::find_if( map_hash.begin(), map_hash.end(), + [this]( const std::pair< dev::h256, size_t > p ) { return 3 * p.second > 2 * this->n_; } ); + cnote << "Snapshot hash is: " << ( *it ).first << ". Verifying it..."; - if ( this->hashes_.at( i ) == ( *it ).first ) { - this->nodesToDownloadSnapshotFrom_.push_back( i ); - idx.push_back( i + 1 ); - signatures.push_back( this->signatures_.at( i ) ); - } + if ( it == map_hash.end() ) { + throw NotEnoughVotesException( "note enough votes to choose hash" ); + return false; + } else { + std::vector< size_t > idx; + std::vector< libff::alt_bn128_G1 > signatures; + for ( size_t i = 0; i < this->n_; ++i ) { + if ( this->chainParams_.nodeInfo.id == this->chainParams_.sChain.nodes.at( i ).id ) { + continue; } - std::vector< libff::alt_bn128_Fr > lagrange_coeffs; - libff::alt_bn128_G1 common_signature; - try { - lagrange_coeffs = - libBLS::ThresholdUtils::LagrangeCoeffs( idx, ( 2 * this->n_ + 1 ) / 3 ); - common_signature = this->bls_->SignatureRecover( signatures, lagrange_coeffs ); - } catch ( libBLS::ThresholdUtils::IncorrectInput& ex ) { - cerror << "Exception while recovering common signature from other skaleds: " - << ex.what(); - } catch ( libBLS::ThresholdUtils::IsNotWellFormed& ex ) { - cerror << "Exception while recovering common signature from other skaleds: " - << ex.what(); + if ( this->hashes_.at( i ) == ( *it ).first ) { + this->nodesToDownloadSnapshotFrom_.push_back( i ); + idx.push_back( i + 1 ); + signatures.push_back( this->signatures_.at( i ) ); } + } - bool is_verified = false; + std::vector< libff::alt_bn128_Fr > lagrange_coeffs; + libff::alt_bn128_G1 common_signature; + try { + lagrange_coeffs = + libBLS::ThresholdUtils::LagrangeCoeffs( idx, ( 2 * this->n_ + 1 ) / 3 ); + common_signature = this->bls_->SignatureRecover( signatures, lagrange_coeffs ); + } catch ( libBLS::ThresholdUtils::IncorrectInput& ex ) { + cerror << "Exception while recovering common signature from other skaleds: " + << ex.what(); + } catch ( libBLS::ThresholdUtils::IsNotWellFormed& ex ) { + cerror << "Exception while recovering common signature from other skaleds: " + << ex.what(); + } + bool is_verified = false; + + try { + libff::inhibit_profiling_info = true; + is_verified = this->bls_->Verification( + std::make_shared< std::array< uint8_t, 32 > >( ( *it ).first.asArray() ), + common_signature, this->commonPublicKey_ ); + } catch ( libBLS::ThresholdUtils::IsNotWellFormed& ex ) { + cerror << "Exception while verifying common signature from other skaleds: " + << ex.what(); + } + + if ( !is_verified ) { + cerror << "Common BLS signature wasn't verified, probably using incorrect " + "common public key specified in command line. Trying again with " + "common public key from config"; + + libff::alt_bn128_G2 commonPublicKey_from_config; + commonPublicKey_from_config.X.c0 = + libff::alt_bn128_Fq( this->chainParams_.nodeInfo.commonBLSPublicKeys[0].c_str() ); + commonPublicKey_from_config.X.c1 = + libff::alt_bn128_Fq( this->chainParams_.nodeInfo.commonBLSPublicKeys[1].c_str() ); + commonPublicKey_from_config.Y.c0 = + libff::alt_bn128_Fq( this->chainParams_.nodeInfo.commonBLSPublicKeys[2].c_str() ); + commonPublicKey_from_config.Y.c1 = + libff::alt_bn128_Fq( this->chainParams_.nodeInfo.commonBLSPublicKeys[3].c_str() ); + commonPublicKey_from_config.Z = libff::alt_bn128_Fq2::one(); + std::cout << "NEW BLS COMMON PUBLIC KEY:\n"; + commonPublicKey_from_config.print_coordinates(); try { - libff::inhibit_profiling_info = true; is_verified = this->bls_->Verification( std::make_shared< std::array< uint8_t, 32 > >( ( *it ).first.asArray() ), - common_signature, this->commonPublicKey_ ); + common_signature, commonPublicKey_from_config ); } catch ( libBLS::ThresholdUtils::IsNotWellFormed& ex ) { cerror << "Exception while verifying common signature from other skaleds: " << ex.what(); } if ( !is_verified ) { - cerror << "Common BLS signature wasn't verified, probably using incorrect " - "common public key specified in command line. Trying again with " - "common public key from config"; - - libff::alt_bn128_G2 commonPublicKey_from_config; - commonPublicKey_from_config.X.c0 = libff::alt_bn128_Fq( - this->chainParams_.nodeInfo.commonBLSPublicKeys[0].c_str() ); - commonPublicKey_from_config.X.c1 = libff::alt_bn128_Fq( - this->chainParams_.nodeInfo.commonBLSPublicKeys[1].c_str() ); - commonPublicKey_from_config.Y.c0 = libff::alt_bn128_Fq( - this->chainParams_.nodeInfo.commonBLSPublicKeys[2].c_str() ); - commonPublicKey_from_config.Y.c1 = libff::alt_bn128_Fq( - this->chainParams_.nodeInfo.commonBLSPublicKeys[3].c_str() ); - commonPublicKey_from_config.Z = libff::alt_bn128_Fq2::one(); - std::cout << "NEW BLS COMMON PUBLIC KEY:\n"; - commonPublicKey_from_config.print_coordinates(); - try { - is_verified = this->bls_->Verification( - std::make_shared< std::array< uint8_t, 32 > >( ( *it ).first.asArray() ), - common_signature, commonPublicKey_from_config ); - } catch ( libBLS::ThresholdUtils::IsNotWellFormed& ex ) { - cerror << "Exception while verifying common signature from other skaleds: " - << ex.what(); - } - - if ( !is_verified ) { - cerror << "Common BLS signature wasn't verified, snapshot will not be " - "downloaded. Try to backup node manually using skale-node-cli."; - return false; - } else { - cnote << "Common BLS signature was verified with common public key " - "from config."; - this->commonPublicKey_ = commonPublicKey_from_config; - } + cerror << "Common BLS signature wasn't verified, snapshot will not be " + "downloaded. Try to backup node manually using skale-node-cli."; + return false; + } else { + cnote << "Common BLS signature was verified with common public key " + "from config."; + this->commonPublicKey_ = commonPublicKey_from_config; } - - this->voted_hash_.first = ( *it ).first; - this->voted_hash_.second = common_signature; - - return true; - } - } else { - size_t nodeIdx = std::distance( this->chainParams_.sChain.nodes.begin(), - std::find_if( this->chainParams_.sChain.nodes.begin(), - this->chainParams_.sChain.nodes.end(), [this]( const dev::eth::sChainNode& node ) { - return urlToDownloadSnapshotFrom_.find( node.ip ) != std::string::npos; - } ) ); - - dev::h256 requiredHashValue = this->hashes_[nodeIdx]; - if ( requiredHashValue == dev::h256() ) { - throw IsNotVerified( "Hash from the required node is empty" ); } - it = map_hash.find( requiredHashValue ); + this->votedHash_.first = ( *it ).first; + this->votedHash_.second = common_signature; - this->voted_hash_.first = ( *it ).first; - this->voted_hash_.second = this->signatures_[nodeIdx]; - - this->nodesToDownloadSnapshotFrom_.push_back( nodeIdx ); + return true; } return true; @@ -277,7 +254,6 @@ std::tuple< dev::h256, libff::alt_bn128_G1, libff::alt_bn128_G2 > SnapshotHashAg if ( urlToDownloadSnapshotFrom_.empty() ) { Json::Value joPublicKeyResponse = skaleClient.skale_imaInfo(); - publicKey.X.c0 = libff::alt_bn128_Fq( joPublicKeyResponse["BLSPublicKey0"].asCString() ); publicKey.X.c1 = @@ -336,7 +312,7 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( } } else { auto snapshotData = askNodeForHash( urlToDownloadSnapshotFrom_, blockNumber ); - this->voted_hash_ = { std::get< 0 >( snapshotData ), std::get< 1 >( snapshotData ) }; + this->votedHash_ = { std::get< 0 >( snapshotData ), std::get< 1 >( snapshotData ) }; return { urlToDownloadSnapshotFrom_ }; } @@ -358,7 +334,7 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( if ( common_hash == dev::h256() ) { common_hash = this->hashes_.at( pos ); - this->voted_hash_.first = common_hash; + this->votedHash_.first = common_hash; // .second will ne ignored! } else if ( this->hashes_.at( pos ) != common_hash ) { result = false; @@ -396,16 +372,16 @@ std::vector< std::string > SnapshotHashAgent::getNodesToDownloadSnapshotFrom( } std::pair< dev::h256, libff::alt_bn128_G1 > SnapshotHashAgent::getVotedHash() const { - if ( this->voted_hash_.first == dev::h256() ) { + if ( this->votedHash_.first == dev::h256() ) { throw std::invalid_argument( "Hash is empty" ); } if ( AmsterdamFixPatch::snapshotHashCheckingEnabled( this->chainParams_ ) ) { - if ( this->voted_hash_.second == libff::alt_bn128_G1::zero() || - !this->voted_hash_.second.is_well_formed() ) { + if ( this->votedHash_.second == libff::alt_bn128_G1::zero() || + !this->votedHash_.second.is_well_formed() ) { throw std::invalid_argument( "Signature is not well formed" ); } } - return this->voted_hash_; + return this->votedHash_; } diff --git a/libskale/SnapshotHashAgent.h b/libskale/SnapshotHashAgent.h index 62d54a6c3..23a8b5861 100644 --- a/libskale/SnapshotHashAgent.h +++ b/libskale/SnapshotHashAgent.h @@ -67,7 +67,7 @@ class SnapshotHashAgent { public: SnapshotHashAgent( const dev::eth::ChainParams& chainParams, const std::array< std::string, 4 >& commonPublicKey, - const std::string& urlToDownloadSnapshotFrom ); + const std::string& urlToDownloadSnapshotFrom = "" ); std::vector< std::string > getNodesToDownloadSnapshotFrom( unsigned blockNumber ); @@ -93,7 +93,7 @@ class SnapshotHashAgent { void readPublicKeyFromConfig(); std::tuple< dev::h256, libff::alt_bn128_G1, libff::alt_bn128_G2 > askNodeForHash( const std::string& url, unsigned blockNumber ); - std::pair< dev::h256, libff::alt_bn128_G1 > voted_hash_; + std::pair< dev::h256, libff::alt_bn128_G1 > votedHash_; size_t verifyAllData() const; }; diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index d85225fb4..949712239 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -65,6 +65,8 @@ SnapshotManager::SnapshotManager( const dev::eth::ChainParams& _chainParams, #ifdef HISTORIC_STATE archiveVolumes = { "historic_roots", "historic_state" }; +#else + archiveVolumes = {}; #endif allVolumes.reserve( coreVolumes.size() + archiveVolumes.size() ); @@ -185,8 +187,7 @@ void SnapshotManager::restoreSnapshot( unsigned _blockNumber ) { // - no such snapshots // - cannot read // - cannot create tmp file -// - archive/core node -boost::filesystem::path SnapshotManager::makeOrGetDiff( unsigned _toBlock, bool _forArchiveNode ) { +boost::filesystem::path SnapshotManager::makeOrGetDiff( unsigned _toBlock ) { fs::path path = getDiffPath( _toBlock ); try { @@ -202,13 +203,9 @@ boost::filesystem::path SnapshotManager::makeOrGetDiff( unsigned _toBlock, bool std::throw_with_nested( CannotRead( ex.path1() ) ); } - if ( _forArchiveNode && !chainParams.nodeInfo.archiveMode ) - throw std::runtime_error( "Cannot create diff for an archvie node from the core node." ); - stringstream volumes_cat; - std::vector< std::string > volumes = - ( _forArchiveNode && _toBlock > 0 ) ? allVolumes : coreVolumes; + std::vector< std::string > volumes = _toBlock > 0 ? allVolumes : coreVolumes; for ( auto it = volumes.begin(); it != volumes.end(); ++it ) { const string& vol = *it; if ( it + 1 != volumes.end() ) diff --git a/libskale/SnapshotManager.h b/libskale/SnapshotManager.h index 2f8db6580..612354fdd 100644 --- a/libskale/SnapshotManager.h +++ b/libskale/SnapshotManager.h @@ -156,7 +156,7 @@ class SnapshotManager { const boost::filesystem::path& _dataDir, const std::string& diffs_dir = std::string() ); void doSnapshot( unsigned _blockNumber ); void restoreSnapshot( unsigned _blockNumber ); - boost::filesystem::path makeOrGetDiff( unsigned _toBlock, bool _forArchiveNode = false ); + boost::filesystem::path makeOrGetDiff( unsigned _toBlock ); void importDiff( unsigned _toBlock ); boost::filesystem::path getDiffPath( unsigned _toBlock ); void removeSnapshot( unsigned _blockNumber ); diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index fd75f856d..bab30bff6 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -159,10 +159,6 @@ nlohmann::json Skale::impl_skale_getSnapshot( const nlohmann::json& joRequest, C return joResponse; } - bool forArchiveNode = false; - if ( client.chainParams().nodeInfo.archiveMode ) - forArchiveNode = joRequest["forArchiveNode"].get< bool >(); - // exit if too early if ( currentSnapshotBlockNumber >= 0 ) { joResponse["error"] = @@ -194,7 +190,7 @@ nlohmann::json Skale::impl_skale_getSnapshot( const nlohmann::json& joRequest, C } try { - currentSnapshotPath = client.createSnapshotFile( blockNumber, forArchiveNode ); + currentSnapshotPath = client.createSnapshotFile( blockNumber ); } catch ( ... ) { if ( m_shared_space ) m_shared_space->unlock(); diff --git a/skaled/main.cpp b/skaled/main.cpp index 34661362b..03a02ffa5 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -469,13 +469,18 @@ bool tryDownloadSnapshot( std::shared_ptr< SnapshotManager >& snapshotManager, bool downloadSnapshotFromUrl( std::shared_ptr< SnapshotManager >& snapshotManager, const ChainParams& chainParams, const std::array< std::string, 4 >& arrayCommonPublicKey, - const std::string& urlToDownloadSnapshotFrom, bool isRegularSnapshot ) { + const std::string& urlToDownloadSnapshotFrom, bool isRegularSnapshot, + bool forceDownload = false ) { unsigned blockNumber = 0; if ( isRegularSnapshot ) blockNumber = getBlockToDownladSnapshot( urlToDownloadSnapshotFrom ); - std::unique_ptr< SnapshotHashAgent > snapshotHashAgent( - new SnapshotHashAgent( chainParams, arrayCommonPublicKey, urlToDownloadSnapshotFrom ) ); + std::unique_ptr< SnapshotHashAgent > snapshotHashAgent; + if ( forceDownload ) + snapshotHashAgent.reset( + new SnapshotHashAgent( chainParams, arrayCommonPublicKey, urlToDownloadSnapshotFrom ) ); + else + snapshotHashAgent.reset( new SnapshotHashAgent( chainParams, arrayCommonPublicKey ) ); libff::init_alt_bn128_params(); std::pair< dev::h256, libff::alt_bn128_G1 > votedHash; @@ -511,11 +516,11 @@ void downloadAndProccessSnapshot( std::shared_ptr< SnapshotManager >& snapshotMa if ( !urlToDownloadSnapshotFrom.empty() ) successfullDownload = downloadSnapshotFromUrl( snapshotManager, chainParams, - arrayCommonPublicKey, urlToDownloadSnapshotFrom, isRegularSnapshot ); + arrayCommonPublicKey, urlToDownloadSnapshotFrom, isRegularSnapshot, true ); else { for ( size_t idx = 0; idx < chainParams.sChain.nodes.size() && !successfullDownload; ++idx ) try { - if ( chainParams.nodeInfo.id == chainParams.sChain.nodes[idx].id ) + if ( chainParams.nodeInfo.id == chainParams.sChain.nodes.at( idx ).id ) continue; std::string nodeUrl = diff --git a/test/unittests/libskale/HashSnapshot.cpp b/test/unittests/libskale/HashSnapshot.cpp index da681b91a..51bf59088 100644 --- a/test/unittests/libskale/HashSnapshot.cpp +++ b/test/unittests/libskale/HashSnapshot.cpp @@ -124,7 +124,7 @@ class SnapshotHashAgentTest { continue; } - if ( this->hashAgent_->hashes_[i] == this->hashAgent_->voted_hash_.first ) { + if ( this->hashAgent_->hashes_[i] == this->hashAgent_->votedHash_.first ) { ret.push_back( i ); } } From 2bc3b508fd81e1a4dfed4b2e717b8b3096505bb8 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 9 Oct 2024 12:20:29 +0100 Subject: [PATCH 30/47] IS 968 update tests --- test/unittests/libskale/HashSnapshot.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/unittests/libskale/HashSnapshot.cpp b/test/unittests/libskale/HashSnapshot.cpp index 51bf59088..bc74936ce 100644 --- a/test/unittests/libskale/HashSnapshot.cpp +++ b/test/unittests/libskale/HashSnapshot.cpp @@ -522,9 +522,7 @@ BOOST_AUTO_TEST_CASE( noSnapshotMajority ) { snapshot_hashes[2] = dev::h256::random(); test_agent.fillData( snapshot_hashes ); - auto nodesToDownloadSnapshotFrom = test_agent.getNodesToDownloadSnapshotFrom(); - BOOST_REQUIRE( nodesToDownloadSnapshotFrom.size() == 1 ); - BOOST_REQUIRE( nodesToDownloadSnapshotFrom[0] == 3 ); + BOOST_REQUIRE_THROW( test_agent.getNodesToDownloadSnapshotFrom(), NotEnoughVotesException ); } BOOST_AUTO_TEST_SUITE_END() From 1da07802be99e900bcd075886ad459fbc5488fdd Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 9 Oct 2024 13:52:50 +0100 Subject: [PATCH 31/47] IS 968 fix historic build --- test/unittests/libskale/SnapshotManager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/unittests/libskale/SnapshotManager.cpp b/test/unittests/libskale/SnapshotManager.cpp index b96a7f88a..318017e97 100644 --- a/test/unittests/libskale/SnapshotManager.cpp +++ b/test/unittests/libskale/SnapshotManager.cpp @@ -522,7 +522,7 @@ BOOST_FIXTURE_TEST_CASE( ArchiveNodeTest, BtrfsFixture, BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_state" / "d41" ) ); // make diff for archive node - BOOST_REQUIRE_NO_THROW( mgr.makeOrGetDiff( 1, true ) ); + BOOST_REQUIRE_NO_THROW( mgr.makeOrGetDiff( 1 ) ); // delete dest btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName ).c_str() ); @@ -532,7 +532,6 @@ BOOST_FIXTURE_TEST_CASE( ArchiveNodeTest, BtrfsFixture, fs::remove_all( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" ); BOOST_REQUIRE_NO_THROW( mgr.importDiff( 1 ) ); -// mgr.importDiff( 1 ); BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName / "d11" ) ); BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" / "d21" ) ); From dff39db1ddd642db541a473d065117edebc652dd Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Thu, 10 Oct 2024 16:13:49 +0100 Subject: [PATCH 32/47] IS 968 remove full snapshot hash for archive --- libskale/SnapshotManager.cpp | 41 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 949712239..0e002063a 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -710,26 +710,27 @@ void SnapshotManager::computeAllVolumesHash( std::throw_with_nested( SnapshotManager::CannotCreate( hashFile ) ); } - if ( _blockNumber > 0 ) { - // archive blocks - for ( auto& content : contents ) { - if ( content.leaf().string().find( "archive" ) == std::string::npos ) - continue; - this->computeDatabaseHash( content, ctx ); - } - -#ifdef HISTORIC_STATE - // historic dbs - this->computeDatabaseHash( - this->snapshotsDir / std::to_string( _blockNumber ) / archiveVolumes[0] / - dev::eth::BlockChain::getChainDirName( chainParams ) / "state", - ctx ); - this->computeDatabaseHash( - this->snapshotsDir / std::to_string( _blockNumber ) / archiveVolumes[1] / - dev::eth::BlockChain::getChainDirName( chainParams ) / "state", - ctx ); -#endif - } + // disable this code until further notice + // if ( _blockNumber > 0 ) { + // // archive blocks + // for ( auto& content : contents ) { + // if ( content.leaf().string().find( "archive" ) == std::string::npos ) + // continue; + // this->computeDatabaseHash( content, ctx ); + // } + + //#ifdef HISTORIC_STATE + // // historic dbs + // this->computeDatabaseHash( + // this->snapshotsDir / std::to_string( _blockNumber ) / archiveVolumes[0] / + // dev::eth::BlockChain::getChainDirName( chainParams ) / "state", + // ctx ); + // this->computeDatabaseHash( + // this->snapshotsDir / std::to_string( _blockNumber ) / archiveVolumes[1] / + // dev::eth::BlockChain::getChainDirName( chainParams ) / "state", + // ctx ); + //#endif + // } } } From 7a577a45f085eac2d560290dca5e67c59116e945 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Mon, 14 Oct 2024 13:47:20 +0100 Subject: [PATCH 33/47] IS 968 tests --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index afe1973dc..4c4b8d943 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -211,9 +211,9 @@ jobs: run_test JsonRpcSuite run_test SingleConsensusTests run_test ConsensusTests - sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t BtrfsTestSuite -- --all && touch /tmp/tests/BtrfsTestSuitePassed - sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t HashSnapshotTestSuite -- --all && touch /tmp/tests/HashSnapshotTestSuitePassed - # sudo NO_NTP_CHECK=1 NO_ULIMIT_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all && touch /tmp/tests/ClientSnapshotsSuitePassed + sudo ./testeth -t BtrfsTestSuite -- --all && touch /tmp/tests/BtrfsTestSuitePassed + sudo ./testeth -t HashSnapshotTestSuite -- --all && touch /tmp/tests/HashSnapshotTestSuitePassed + sudo ./testeth -t ClientSnapshotsSuite -- --all && touch /tmp/tests/ClientSnapshotsSuitePassed cd .. - name: Testeth verbosity 4 run : | @@ -264,7 +264,7 @@ jobs: rerun_test ConsensusTests ls /tmp/tests/BtrfsTestSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t BtrfsTestSuite -- --all --verbosity 4 ls /tmp/tests/HashSnapshotTestSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t HashSnapshotTestSuite -- --all --verbosity 4 - # ls /tmp/tests/ClientSnapshotsSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all --verbosity 4 + ls /tmp/tests/ClientSnapshotsSuitePassed || sudo NO_ULIMIT_CHECK=1 NO_NTP_CHECK=1 ./testeth -t ClientSnapshotsSuite -- --all --verbosity 4 cd .. - name: Configure all as historic From c2faa3c772c623980f06afcf49d6bad546b2288f Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Mon, 14 Oct 2024 16:19:02 +0100 Subject: [PATCH 34/47] IS 968 tests --- test/unittests/libethereum/ClientTest.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/test/unittests/libethereum/ClientTest.cpp b/test/unittests/libethereum/ClientTest.cpp index 47ae0bf90..dba0d1122 100644 --- a/test/unittests/libethereum/ClientTest.cpp +++ b/test/unittests/libethereum/ClientTest.cpp @@ -1007,8 +1007,8 @@ static std::string const c_skaleConfigString = R"E( "sChain": { "schainName": "TestChain", "schainID": 1, - "snapshotIntervalSec": 10, - "emptyBlockIntervalMs": -1, + "snapshotIntervalSec": 5, + "emptyBlockIntervalMs": 4000, "nodes": [ { "nodeID": 1112, "ip": "127.0.0.1", "basePort": )E"+std::to_string( rand_port ) + R"E(, "ip6": "::1", "basePort6": 1231, "schainIndex" : 1, "publicKey" : "0xfa"} ] @@ -1038,12 +1038,9 @@ BOOST_AUTO_TEST_CASE( ClientSnapshotsTest, *boost::unit_test::disabled() ) { BOOST_REQUIRE( testClient->getSnapshotHash( 0 ) != dev::h256() ); - BOOST_REQUIRE( testClient->mineBlocks( 1 ) ); - - testClient->importTransactionsAsBlock( - Transactions(), 1000, testClient->latestBlock().info().timestamp() + 86410 ); + std::this_thread::sleep_for( 5000ms ); - BOOST_REQUIRE( fs::exists( fs::path( fixture.getTmpDataDir() ) / "snapshots" / "3" ) ); + BOOST_REQUIRE( fs::exists( fs::path( fixture.getTmpDataDir() ) / "snapshots" / "2" ) ); secp256k1_sha256_t ctx; secp256k1_sha256_initialize( &ctx ); @@ -1055,13 +1052,15 @@ BOOST_AUTO_TEST_CASE( ClientSnapshotsTest, *boost::unit_test::disabled() ) { secp256k1_sha256_finalize( &ctx, empty_state_root_hash.data() ); BOOST_REQUIRE( testClient->latestBlock().info().stateRoot() == empty_state_root_hash ); - std::this_thread::sleep_for( 6000ms ); - BOOST_REQUIRE( fs::exists( fs::path( fixture.getTmpDataDir() ) / "snapshots" / "3" / "snapshot_hash.txt" ) ); - dev::h256 hash = testClient->hashFromNumber( 3 ); + std::this_thread::sleep_for( 1000ms ); + + BOOST_REQUIRE( fs::exists( fs::path( fixture.getTmpDataDir() ) / "snapshots" / "2" / "snapshot_hash.txt" ) ); + + dev::h256 hash = testClient->hashFromNumber( 2 ); uint64_t timestampFromBlockchain = testClient->blockInfo( hash ).timestamp(); - BOOST_REQUIRE_EQUAL( timestampFromBlockchain, testClient->getBlockTimestampFromSnapshot( 3 ) ); + BOOST_REQUIRE_EQUAL( timestampFromBlockchain, testClient->getBlockTimestampFromSnapshot( 2 ) ); } BOOST_AUTO_TEST_SUITE_END() From c9d7dc0851e62cd20b78f08395a8e7d9a5d05d99 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 15 Oct 2024 16:25:57 +0100 Subject: [PATCH 35/47] IS 968 change snapshot download limits for archive node --- libweb3jsonrpc/Skale.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index bab30bff6..164c32e97 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -206,8 +206,9 @@ nlohmann::json Skale::impl_skale_getSnapshot( const nlohmann::json& joRequest, C m_client.chainParams().sChain.snapshotDownloadInactiveTimeout || time( NULL ) - currentSnapshotTime < m_client.chainParams().sChain.snapshotDownloadInactiveTimeout ) && - time( NULL ) - currentSnapshotTime < - m_client.chainParams().sChain.snapshotDownloadTimeout ) { + ( time( NULL ) - currentSnapshotTime < + m_client.chainParams().sChain.snapshotDownloadTimeout || + m_client.chainParams().nodeInfo.archiveMode ) ) { if ( threadExitRequested ) break; sleep( 10 ); From badef2269c4cdcee83245dbd61e804c0d5905988 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 16 Oct 2024 13:01:50 +0100 Subject: [PATCH 36/47] IS 968 cleanup --- libethereum/Client.cpp | 4 +- libethereum/Client.h | 4 +- libethereum/SnapshotAgent.cpp | 4 +- libethereum/SnapshotAgent.h | 2 +- libskale/SnapshotManager.cpp | 114 +++++++++++++++------------------- libskale/SnapshotManager.h | 3 +- libweb3jsonrpc/Skale.cpp | 2 +- 7 files changed, 60 insertions(+), 73 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 42612c851..b44638e89 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -826,7 +826,7 @@ void Client::rejigSealing() { dev::h256 stateRootToSet; if ( m_snapshotAgent->getLatestSnapshotBlockNumer() > 0 ) { dev::h256 stateRootHash = this->m_snapshotAgent->getSnapshotHash( - m_snapshotAgent->getLatestSnapshotBlockNumer(), false ); + m_snapshotAgent->getLatestSnapshotBlockNumer() ); stateRootToSet = stateRootHash; } // propagate current @@ -882,7 +882,7 @@ void Client::sealUnconditionally( bool submitToBlockChain ) { dev::h256 stateRootToSet; if ( m_snapshotAgent->getLatestSnapshotBlockNumer() > 0 ) { dev::h256 stateRootHash = this->m_snapshotAgent->getSnapshotHash( - m_snapshotAgent->getLatestSnapshotBlockNumer(), false ); + m_snapshotAgent->getLatestSnapshotBlockNumer() ); stateRootToSet = stateRootHash; } // propagate current diff --git a/libethereum/Client.h b/libethereum/Client.h index dd5045285..468aec177 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -300,8 +300,8 @@ class Client : public ClientBase, protected Worker { // set exiting time for node rotation void setSchainExitTime( uint64_t _timestamp ) const; - dev::h256 getSnapshotHash( unsigned _blockNumber, bool _forArchiveNode = false ) const { - return m_snapshotAgent->getSnapshotHash( _blockNumber, _forArchiveNode ); + dev::h256 getSnapshotHash( unsigned _blockNumber ) const { + return m_snapshotAgent->getSnapshotHash( _blockNumber ); } uint64_t getBlockTimestampFromSnapshot( unsigned _blockNumber ) const { diff --git a/libethereum/SnapshotAgent.cpp b/libethereum/SnapshotAgent.cpp index 4998208b6..68e055147 100644 --- a/libethereum/SnapshotAgent.cpp +++ b/libethereum/SnapshotAgent.cpp @@ -156,12 +156,12 @@ void SnapshotAgent::terminate() { } } -dev::h256 SnapshotAgent::getSnapshotHash( unsigned _blockNumber, bool _forArchiveNode ) const { +dev::h256 SnapshotAgent::getSnapshotHash( unsigned _blockNumber ) const { if ( _blockNumber > this->last_snapshoted_block_with_hash && _blockNumber != 0 ) return dev::h256(); try { - dev::h256 res = this->m_snapshotManager->getSnapshotHash( _blockNumber, _forArchiveNode ); + dev::h256 res = this->m_snapshotManager->getSnapshotHash( _blockNumber ); return res; } catch ( const SnapshotManager::SnapshotAbsent& ) { return dev::h256(); diff --git a/libethereum/SnapshotAgent.h b/libethereum/SnapshotAgent.h index 79e46b6e4..140e0c4cd 100644 --- a/libethereum/SnapshotAgent.h +++ b/libethereum/SnapshotAgent.h @@ -30,7 +30,7 @@ class SnapshotAgent { void terminate(); - dev::h256 getSnapshotHash( unsigned _blockNumber, bool _forArchiveNode ) const; + dev::h256 getSnapshotHash( unsigned _blockNumber ) const; uint64_t getBlockTimestampFromSnapshot( unsigned _blockNumber ) const; int64_t getLatestSnapshotBlockNumer() const { return this->last_snapshoted_block_with_hash; } uint64_t getSnapshotCalculationTime() const { return this->snapshot_calculation_time_ms; } diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 0e002063a..432400fc5 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -49,7 +49,6 @@ namespace fs = boost::filesystem; // For send/receive needs root! const std::string SnapshotManager::snapshotHashFileName = "snapshot_hash.txt"; -const std::string SnapshotManager::partialSnapshotHashFileName = "partial_snapshot_hash.txt"; // exceptions: // - bad data dir @@ -409,7 +408,7 @@ void SnapshotManager::leaveNLastDiffs( unsigned n ) { } // for } -dev::h256 SnapshotManager::getSnapshotHash( unsigned block_number, bool _forArchiveNode ) const { +dev::h256 SnapshotManager::getSnapshotHash( unsigned block_number ) const { fs::path snapshot_dir = snapshotsDir / to_string( block_number ); try { @@ -419,15 +418,9 @@ dev::h256 SnapshotManager::getSnapshotHash( unsigned block_number, bool _forArch std::throw_with_nested( CannotRead( snapshot_dir ) ); } // catch - std::string hashFile; - if ( !_forArchiveNode && chainParams.nodeInfo.archiveMode ) - hashFile = ( this->snapshotsDir / std::to_string( block_number ) / - this->partialSnapshotHashFileName ) - .string(); - else - hashFile = - ( this->snapshotsDir / std::to_string( block_number ) / this->snapshotHashFileName ) - .string(); + std::string hashFile = + ( this->snapshotsDir / std::to_string( block_number ) / this->snapshotHashFileName ) + .string(); if ( !isSnapshotHashPresent( block_number ) ) { BOOST_THROW_EXCEPTION( SnapshotManager::CannotRead( hashFile ) ); @@ -455,19 +448,11 @@ bool SnapshotManager::isSnapshotHashPresent( unsigned _blockNumber ) const { std::throw_with_nested( CannotRead( snapshot_dir ) ); } // catch - boost::filesystem::path hashFile = - this->snapshotsDir / std::to_string( _blockNumber ) / this->snapshotHashFileName; + boost::filesystem::path hashFile = snapshot_dir / this->snapshotHashFileName; try { std::lock_guard< std::mutex > lock( hashFileMutex ); - if ( !chainParams.nodeInfo.archiveMode ) - return boost::filesystem::exists( hashFile ); - else { - boost::filesystem::path partialHashFile = this->snapshotsDir / - std::to_string( _blockNumber ) / - this->partialSnapshotHashFileName; - return boost::filesystem::exists( hashFile ) && - boost::filesystem::exists( partialHashFile ); - } + + return boost::filesystem::exists( hashFile ); } catch ( const fs::filesystem_error& ) { std::throw_with_nested( CannotRead( hashFile ) ); } @@ -691,47 +676,50 @@ void SnapshotManager::computeAllVolumesHash( this->addLastPriceToHash( _blockNumber, ctx ); } - if ( chainParams.nodeInfo.archiveMode ) { - // save partial snapshot hash - secp256k1_sha256_t partialCtx = *ctx; - - dev::h256 partialHash; - secp256k1_sha256_finalize( &partialCtx, partialHash.data() ); - - string hashFile = ( this->snapshotsDir / std::to_string( _blockNumber ) ).string() + '/' + - this->partialSnapshotHashFileName; - - try { - std::lock_guard< std::mutex > lock( hashFileMutex ); - std::ofstream out( hashFile ); - out.clear(); - out << partialHash; - } catch ( const std::exception& ex ) { - std::throw_with_nested( SnapshotManager::CannotCreate( hashFile ) ); - } - - // disable this code until further notice - // if ( _blockNumber > 0 ) { - // // archive blocks - // for ( auto& content : contents ) { - // if ( content.leaf().string().find( "archive" ) == std::string::npos ) - // continue; - // this->computeDatabaseHash( content, ctx ); - // } - - //#ifdef HISTORIC_STATE - // // historic dbs - // this->computeDatabaseHash( - // this->snapshotsDir / std::to_string( _blockNumber ) / archiveVolumes[0] / - // dev::eth::BlockChain::getChainDirName( chainParams ) / "state", - // ctx ); - // this->computeDatabaseHash( - // this->snapshotsDir / std::to_string( _blockNumber ) / archiveVolumes[1] / - // dev::eth::BlockChain::getChainDirName( chainParams ) / "state", - // ctx ); - //#endif - // } - } + // disable this code until further notice + // we haven't implemented hash computation for archive submodules yet + // if ( chainParams.nodeInfo.archiveMode ) { + // // save partial snapshot hash + // secp256k1_sha256_t partialCtx = *ctx; + + // dev::h256 partialHash; + // secp256k1_sha256_finalize( &partialCtx, partialHash.data() ); + + // string hashFile = ( this->snapshotsDir / std::to_string( _blockNumber ) ).string() + + // '/' + + // this->partialSnapshotHashFileName; + + // try { + // std::lock_guard< std::mutex > lock( hashFileMutex ); + // std::ofstream out( hashFile ); + // out.clear(); + // out << partialHash; + // } catch ( const std::exception& ex ) { + // std::throw_with_nested( SnapshotManager::CannotCreate( hashFile ) ); + // } + + + // if ( _blockNumber > 0 ) { + // // archive blocks + // for ( auto& content : contents ) { + // if ( content.leaf().string().find( "archive" ) == std::string::npos ) + // continue; + // this->computeDatabaseHash( content, ctx ); + // } + + //#ifdef HISTORIC_STATE + // // historic dbs + // this->computeDatabaseHash( + // this->snapshotsDir / std::to_string( _blockNumber ) / archiveVolumes[0] / + // dev::eth::BlockChain::getChainDirName( chainParams ) / "state", + // ctx ); + // this->computeDatabaseHash( + // this->snapshotsDir / std::to_string( _blockNumber ) / archiveVolumes[1] / + // dev::eth::BlockChain::getChainDirName( chainParams ) / "state", + // ctx ); + //#endif + // } + // } } void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checking ) { diff --git a/libskale/SnapshotManager.h b/libskale/SnapshotManager.h index 612354fdd..4a5ca58d8 100644 --- a/libskale/SnapshotManager.h +++ b/libskale/SnapshotManager.h @@ -166,7 +166,7 @@ class SnapshotManager { void leaveNLastSnapshots( unsigned n ); void leaveNLastDiffs( unsigned n ); - dev::h256 getSnapshotHash( unsigned _blockNumber, bool _forArchiveNode = false ) const; + dev::h256 getSnapshotHash( unsigned _blockNumber ) const; std::pair< int, int > getLatestSnapshots() const; bool isSnapshotHashPresent( unsigned _blockNumber ) const; void computeSnapshotHash( unsigned _blockNumber, bool is_checking = false ); @@ -185,7 +185,6 @@ class SnapshotManager { boost::filesystem::path diffsDir; static const std::string snapshotHashFileName; - static const std::string partialSnapshotHashFileName; mutable std::mutex hashFileMutex; dev::eth::ChainParams chainParams; diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index 164c32e97..8e81dad4e 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -367,7 +367,7 @@ Json::Value Skale::skale_getSnapshotSignature( unsigned blockNumber ) { } try { - dev::h256 snapshotHash = this->m_client.getSnapshotHash( blockNumber, false ); + dev::h256 snapshotHash = this->m_client.getSnapshotHash( blockNumber ); if ( !snapshotHash ) throw std::runtime_error( "Requested hash of block " + to_string( blockNumber ) + " is absent" ); From af1a4528b9829b87f434522b70a41f93c9441042 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 16 Oct 2024 17:30:45 +0100 Subject: [PATCH 37/47] IS 968 --- libskale/SnapshotManager.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 432400fc5..77a25c902 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -353,11 +353,23 @@ void SnapshotManager::leaveNLastSnapshots( unsigned n ) { for ( const auto& p : numbers ) { if ( i++ > n ) { const fs::path& path = p.second; - for ( const string& v : allVolumes ) { + for ( const string& v : coreVolumes ) { if ( btrfs.subvolume._delete( ( path / v ).c_str() ) ) { throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); } } + +#ifdef HISTORIC_STATE + for ( const string& v : archiveVolumes ) { + // ignore as it might indicate that archive volumes weren't snapshotted + if ( !fs::exists( path / v ) ) + continue; + if ( btrfs.subvolume._delete( ( path / v ).c_str() ) ) { + throw CannotPerformBtrfsOperation( btrfs.last_cmd(), btrfs.strerror() ); + } + } +#endif + fs::remove_all( path ); } // if } // for From e7bc6ea13393e020aba159548221d5f48072fd35 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Mon, 21 Oct 2024 15:44:22 +0100 Subject: [PATCH 38/47] IS 968 fix functional tests for historic build --- libskale/SnapshotManager.cpp | 24 ++++++++++++++++-------- libweb3jsonrpc/Skale.cpp | 4 +--- libweb3jsonrpc/Skale.h | 2 +- skaled/main.cpp | 2 +- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 77a25c902..e5d655dc7 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -160,11 +160,15 @@ void SnapshotManager::restoreSnapshot( unsigned _blockNumber ) { UnsafeRegion::lock ur_lock; - std::vector< std::string > volumes; - if ( chainParams.nodeInfo.archiveMode && _blockNumber == 0 ) - volumes = coreVolumes; - else + std::vector< std::string > volumes = coreVolumes; +#ifdef HISTORIC_STATE + if ( _blockNumber > 0 ) volumes = allVolumes; +#endif + // if ( chainParams.nodeInfo.archiveMode && _blockNumber == 0 ) + // volumes = coreVolumes; + // else + // volumes = allVolumes; int dummy_counter = 0; for ( const string& vol : volumes ) { @@ -747,11 +751,15 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki int dummy_counter = 0; - std::vector< std::string > volumes; - if ( chainParams.nodeInfo.archiveMode && _blockNumber == 0 ) - volumes = coreVolumes; - else + std::vector< std::string > volumes = coreVolumes; +#ifdef HISTORIC_STATE + if ( _blockNumber > 0 ) volumes = allVolumes; +#endif + // if ( chainParams.nodeInfo.archiveMode && _blockNumber == 0 ) + // volumes = coreVolumes; + // else + // volumes = allVolumes; for ( const auto& volume : volumes ) { int res = btrfs.subvolume.property_set( diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index 8e81dad4e..c2c1d6f42 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -582,8 +582,7 @@ std::string Skale::oracle_checkResult( std::string& receipt ) { namespace snapshot { bool download( const std::string& strURLWeb3, unsigned& block_number, const fs::path& saveTo, - fn_progress_t onProgress, bool isBinaryDownload, std::string* pStrErrorDescription, - bool forArchiveNode ) { + fn_progress_t onProgress, bool isBinaryDownload, std::string* pStrErrorDescription ) { if ( pStrErrorDescription ) pStrErrorDescription->clear(); std::ofstream f; @@ -636,7 +635,6 @@ bool download( const std::string& strURLWeb3, unsigned& block_number, const fs:: joIn["method"] = "skale_getSnapshot"; nlohmann::json joParams = nlohmann::json::object(); joParams["blockNumber"] = block_number; - joParams["forArchiveNode"] = forArchiveNode; joIn["params"] = joParams; skutils::rest::data_t d = cli.call( joIn ); if ( !d.err_s_.empty() ) { diff --git a/libweb3jsonrpc/Skale.h b/libweb3jsonrpc/Skale.h index 93f3ded44..3a39db3e7 100644 --- a/libweb3jsonrpc/Skale.h +++ b/libweb3jsonrpc/Skale.h @@ -118,7 +118,7 @@ typedef std::function< bool( size_t idxChunck, size_t cntChunks ) > fn_progress_ extern bool download( const std::string& strURLWeb3, unsigned& block_number, const fs::path& saveTo, fn_progress_t onProgress, bool isBinaryDownload = true, - std::string* pStrErrorDescription = nullptr, bool forArchiveNode = false ); + std::string* pStrErrorDescription = nullptr ); }; // namespace snapshot diff --git a/skaled/main.cpp b/skaled/main.cpp index 03a02ffa5..386a985fc 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -266,7 +266,7 @@ void downloadSnapshot( unsigned block_number, std::shared_ptr< SnapshotManager > << cc::normal( " of " ) << cc::size10( cntChunks ) << "\r"; return true; // continue download }, - isBinaryDownload, &strErrorDescription, chainParams.nodeInfo.archiveMode ); + isBinaryDownload, &strErrorDescription ); std::cout << " \r"; // clear // progress // line From e4d710ad0b68e2d37c357866847060efe77c372f Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Mon, 21 Oct 2024 19:26:49 +0100 Subject: [PATCH 39/47] IS 968 fix functional tests for historic build --- libskale/SnapshotManager.cpp | 13 +++++++++++++ skaled/main.cpp | 19 +++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index e5d655dc7..7340e8354 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -184,6 +184,19 @@ void SnapshotManager::restoreSnapshot( unsigned _blockNumber ) { batched_io::test_crash_before_commit( "SnapshotManager::doSnapshot" ); } // for + + if ( _blockNumber > 0 ) { +#ifdef HISTORIC_STATE + for ( const string& vol : allVolumes ) { + // continue if already present + if ( fs::exists( dataDir / vol ) && 0 == btrfs.present( ( dataDir / vol ).c_str() ) ) + continue; + + // create if not created yet ( only makes sense for historic nodes and 0 block number ) + btrfs.subvolume.create( ( dataDir / vol ).c_str() ); + } // for +#endif + } } // exceptions: diff --git a/skaled/main.cpp b/skaled/main.cpp index 386a985fc..f9827c4c4 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -251,8 +251,7 @@ void downloadSnapshot( unsigned block_number, std::shared_ptr< SnapshotManager > const std::string& strURLWeb3, const ChainParams& chainParams ) { fs::path saveTo; try { - clog( VerbosityInfo, "downloadSnapshot" ) - << cc::normal( "Will download snapshot from " ) << cc::u( strURLWeb3 ) << std::endl; + clog( VerbosityInfo, "downloadSnapshot" ) << "Will download snapshot from " << strURLWeb3; try { bool isBinaryDownload = true; @@ -262,8 +261,7 @@ void downloadSnapshot( unsigned block_number, std::shared_ptr< SnapshotManager > strURLWeb3, block_number, saveTo, [&]( size_t idxChunck, size_t cntChunks ) -> bool { clog( VerbosityInfo, "downloadSnapshot" ) - << cc::normal( "... download progress ... " ) << cc::size10( idxChunck ) - << cc::normal( " of " ) << cc::size10( cntChunks ) << "\r"; + << "... download progress ... " << idxChunck << " of " << cntChunks << "\r"; return true; // continue download }, isBinaryDownload, &strErrorDescription ); @@ -281,14 +279,12 @@ void downloadSnapshot( unsigned block_number, std::shared_ptr< SnapshotManager > std::throw_with_nested( std::runtime_error( "Exception while downloading snapshot" ) ); } clog( VerbosityInfo, "downloadSnapshot" ) - << cc::success( "Snapshot download success for block " ) - << cc::u( to_string( block_number ) ) << std::endl; + << "Snapshot download success for block " << to_string( block_number ); try { snapshotManager->importDiff( block_number ); } catch ( ... ) { - std::throw_with_nested( std::runtime_error( - cc::fatal( "FATAL:" ) + " " + - cc::error( "Exception while importing downloaded snapshot: " ) ) ); + std::throw_with_nested( + std::runtime_error( "FATAL: Exception while importing downloaded snapshot: " ) ); } /// HACK refactor this piece of code! /// @@ -304,7 +300,7 @@ void downloadSnapshot( unsigned block_number, std::shared_ptr< SnapshotManager > } if ( db_path.empty() ) { clog( VerbosityError, "downloadSnapshot" ) - << cc::fatal( "Snapshot downloaded without " + prefix + " db" ) << std::endl; + << "Snapshot downloaded without " + prefix + " db"; return; } @@ -315,8 +311,7 @@ void downloadSnapshot( unsigned block_number, std::shared_ptr< SnapshotManager > } catch ( ... ) { std::throw_with_nested( - std::runtime_error( cc::fatal( "FATAL:" ) + " " + - cc::error( "Exception while processing downloaded snapshot: " ) ) ); + std::runtime_error( "FATAL: Exception while processing downloaded snapshot: " ) ); } if ( !saveTo.empty() ) fs::remove( saveTo ); From a5492a90c049c79ae14eecd35af5e6d5e50fcb2e Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 22 Oct 2024 10:15:15 +0100 Subject: [PATCH 40/47] IS 968 fix functional tests for historic build --- libskale/SnapshotManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 7340e8354..c0c5f0c02 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -185,7 +185,7 @@ void SnapshotManager::restoreSnapshot( unsigned _blockNumber ) { } // for - if ( _blockNumber > 0 ) { + if ( _blockNumber == 0 ) { #ifdef HISTORIC_STATE for ( const string& vol : allVolumes ) { // continue if already present From 06a445ac8ad61dd7293b5202efd1e9844a284a9e Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Tue, 22 Oct 2024 15:27:49 +0100 Subject: [PATCH 41/47] IS 1083 fix snapshot downloading priority --- skaled/main.cpp | 51 +++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/skaled/main.cpp b/skaled/main.cpp index 03a02ffa5..b6eb27657 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1606,27 +1606,10 @@ int main( int argc, char** argv ) try { std::vector< std::string > coreVolumes = { BlockChain::getChainDirName( chainParams ), "filestorage", "prices_" + chainParams.nodeInfo.id.str() + ".db", "blocks_" + chainParams.nodeInfo.id.str() + ".db" }; - std::vector< std::string > archiveVolumes = {}; - if ( chainParams.nodeInfo.archiveMode ) { -#ifdef HISTORIC_STATE - archiveVolumes.insert( archiveVolumes.end(), { "historic_roots", "historic_state" } ); -#endif - } snapshotManager.reset( new SnapshotManager( chainParams, getDataDir(), sharedSpace ? sharedSpace->getPath() : "" ) ); } - bool downloadGenesisForSyncNode = false; - if ( chainParams.nodeInfo.syncNode ) { - auto bc = BlockChain( chainParams, getDataDir() ); - if ( bc.number() == 0 ) { - downloadSnapshotFlag = true; - if ( chainParams.nodeInfo.syncFromCatchup ) { - downloadGenesisForSyncNode = true; - } - } - } - if ( downloadSnapshotFlag ) { statusAndControl->setExitState( StatusAndControl::StartAgain, true ); statusAndControl->setExitState( StatusAndControl::StartFromSnapshot, true ); @@ -1637,18 +1620,8 @@ int main( int argc, char** argv ) try { sharedSpace_lock.reset( new std::lock_guard< SharedSpace >( *sharedSpace ) ); try { - if ( !downloadGenesisForSyncNode ) - downloadAndProccessSnapshot( - snapshotManager, chainParams, urlToDownloadSnapshotFrom, true ); - else { - try { - downloadAndProccessSnapshot( - snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); - snapshotManager->restoreSnapshot( 0 ); - } catch ( SnapshotManager::SnapshotAbsent& ) { - clog( VerbosityWarning, "main" ) << "Snapshot for 0 block is not found"; - } - } + downloadAndProccessSnapshot( + snapshotManager, chainParams, urlToDownloadSnapshotFrom, true ); // if we dont have 0 snapshot yet try { @@ -1672,6 +1645,26 @@ int main( int argc, char** argv ) try { } // if --download-snapshot + // download 0 snapshot if needed + if ( chainParams.nodeInfo.syncNode ) { + auto bc = BlockChain( chainParams, getDataDir() ); + if ( bc.number() == 0 ) { + if ( chainParams.nodeInfo.syncFromCatchup && !downloadSnapshotFlag ) { + statusAndControl->setExitState( StatusAndControl::StartAgain, true ); + statusAndControl->setExitState( StatusAndControl::StartFromSnapshot, true ); + statusAndControl->setSubsystemRunning( StatusAndControl::SnapshotDownloader, true ); + + try { + downloadAndProccessSnapshot( + snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); + snapshotManager->restoreSnapshot( 0 ); + } catch ( SnapshotManager::SnapshotAbsent& ) { + clog( VerbosityWarning, "main" ) << "Snapshot for 0 block is not found"; + } + } + } + } + statusAndControl->setSubsystemRunning( StatusAndControl::SnapshotDownloader, false ); statusAndControl->setExitState( StatusAndControl::StartAgain, true ); From cefd6af628c53477be57cdab5dda3ad442886387 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 23 Oct 2024 15:07:37 +0100 Subject: [PATCH 42/47] IS 968 fix snapshot dowloading for small snapshots --- libskale/SnapshotManager.cpp | 8 -------- skaled/main.cpp | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index c0c5f0c02..1101b52e7 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -165,10 +165,6 @@ void SnapshotManager::restoreSnapshot( unsigned _blockNumber ) { if ( _blockNumber > 0 ) volumes = allVolumes; #endif - // if ( chainParams.nodeInfo.archiveMode && _blockNumber == 0 ) - // volumes = coreVolumes; - // else - // volumes = allVolumes; int dummy_counter = 0; for ( const string& vol : volumes ) { @@ -769,10 +765,6 @@ void SnapshotManager::computeSnapshotHash( unsigned _blockNumber, bool is_checki if ( _blockNumber > 0 ) volumes = allVolumes; #endif - // if ( chainParams.nodeInfo.archiveMode && _blockNumber == 0 ) - // volumes = coreVolumes; - // else - // volumes = allVolumes; for ( const auto& volume : volumes ) { int res = btrfs.subvolume.property_set( diff --git a/skaled/main.cpp b/skaled/main.cpp index f9827c4c4..0fbe7a6af 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1652,9 +1652,9 @@ int main( int argc, char** argv ) try { // sleep before send skale_getSnapshot again - will receive error clog( VerbosityInfo, "main" ) << std::string( "Will sleep for " ) - << chainParams.sChain.snapshotDownloadInactiveTimeout + << chainParams.sChain.snapshotDownloadInactiveTimeout + 10 << std::string( " seconds before downloading 0 snapshot" ); - sleep( chainParams.sChain.snapshotDownloadInactiveTimeout ); + sleep( chainParams.sChain.snapshotDownloadInactiveTimeout + 10 ); downloadAndProccessSnapshot( snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); From ab180dc8861739d0202bbc6a933e7cc711283789 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 23 Oct 2024 17:31:18 +0100 Subject: [PATCH 43/47] IS 968 rename timeout --- libweb3jsonrpc/Skale.cpp | 3 ++- libweb3jsonrpc/Skale.h | 6 ++++++ skaled/main.cpp | 6 ++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index c2c1d6f42..e8930dc1d 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -66,6 +66,7 @@ std::string exceptionToErrorMessage(); volatile bool Skale::g_bShutdownViaWeb3Enabled = false; volatile bool Skale::g_bNodeInstanceShouldShutdown = false; Skale::list_fn_on_shutdown_t Skale::g_list_fn_on_shutdown; +const uint64_t Skale::SNAPSHOT_DOWNLOAD_MONITOR_THREAD_SLEEP_MS = 10; Skale::Skale( Client& _client, std::shared_ptr< SharedSpace > _sharedSpace ) : m_client( _client ), m_shared_space( _sharedSpace ) {} @@ -211,7 +212,7 @@ nlohmann::json Skale::impl_skale_getSnapshot( const nlohmann::json& joRequest, C m_client.chainParams().nodeInfo.archiveMode ) ) { if ( threadExitRequested ) break; - sleep( 10 ); + sleep( SNAPSHOT_DOWNLOAD_MONITOR_THREAD_SLEEP_MS ); } clog( VerbosityInfo, "skale_downloadSnapshotFragmentMonitorThread" ) diff --git a/libweb3jsonrpc/Skale.h b/libweb3jsonrpc/Skale.h index 3a39db3e7..e76ee732a 100644 --- a/libweb3jsonrpc/Skale.h +++ b/libweb3jsonrpc/Skale.h @@ -84,6 +84,10 @@ class Skale : public dev::rpc::SkaleFace { typedef std::function< void() > fn_on_shutdown_t; static void onShutdownInvoke( fn_on_shutdown_t fn ); + static uint64_t snapshotDownloadFragmentMonitorThreadTimeout() { + return SNAPSHOT_DOWNLOAD_MONITOR_THREAD_SLEEP_MS; + } + public: nlohmann::json impl_skale_getSnapshot( const nlohmann::json& joRequest, dev::eth::Client& client ); @@ -99,6 +103,8 @@ class Skale : public dev::rpc::SkaleFace { typedef std::list< fn_on_shutdown_t > list_fn_on_shutdown_t; static list_fn_on_shutdown_t g_list_fn_on_shutdown; + static const uint64_t SNAPSHOT_DOWNLOAD_MONITOR_THREAD_SLEEP_MS; + dev::eth::Client& m_client; std::shared_ptr< SharedSpace > m_shared_space; int currentSnapshotBlockNumber = -1; diff --git a/skaled/main.cpp b/skaled/main.cpp index 0fbe7a6af..0be868555 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1652,9 +1652,11 @@ int main( int argc, char** argv ) try { // sleep before send skale_getSnapshot again - will receive error clog( VerbosityInfo, "main" ) << std::string( "Will sleep for " ) - << chainParams.sChain.snapshotDownloadInactiveTimeout + 10 + << chainParams.sChain.snapshotDownloadInactiveTimeout + + dev::rpc::Skale::snapshotDownloadFragmentMonitorThreadTimeout() << std::string( " seconds before downloading 0 snapshot" ); - sleep( chainParams.sChain.snapshotDownloadInactiveTimeout + 10 ); + sleep( chainParams.sChain.snapshotDownloadInactiveTimeout + + dev::rpc::Skale::snapshotDownloadFragmentMonitorThreadTimeout() ); downloadAndProccessSnapshot( snapshotManager, chainParams, urlToDownloadSnapshotFrom, false ); From c358786d2855f2e24b764518cc746c0fd683fb66 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Thu, 24 Oct 2024 15:16:48 +0100 Subject: [PATCH 44/47] IS 1083 snapshotdownload flag --- skaled/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/skaled/main.cpp b/skaled/main.cpp index 86969b032..c7eb2389d 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1592,6 +1592,7 @@ int main( int argc, char** argv ) try { std::string urlToDownloadSnapshotFrom = ""; if ( vm.count( "no-snapshot-majority" ) ) { + downloadSnapshotFlag = true; urlToDownloadSnapshotFrom = vm["no-snapshot-majority"].as< string >(); clog( VerbosityInfo, "main" ) << "Manually set url to download snapshot from: " << urlToDownloadSnapshotFrom; From 95d85d523bb735bcd3e21e63d47c38a9782814ba Mon Sep 17 00:00:00 2001 From: Dima Litvinov Date: Fri, 8 Nov 2024 15:24:20 +0200 Subject: [PATCH 45/47] Update json-rpc-interface.md --- docs/json-rpc-interface.md | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/docs/json-rpc-interface.md b/docs/json-rpc-interface.md index c05827aa2..94d4e5db5 100644 --- a/docs/json-rpc-interface.md +++ b/docs/json-rpc-interface.md @@ -502,8 +502,6 @@ Get details about block 2. Include transactions: boolean literal - true/false #### Return format Same as `eth_getBlockByHash` -#### Exceptions -Raises "block not found" error if block is "rotated out" ### `eth_getTransactionByHash` | Compatibility | | @@ -746,6 +744,8 @@ Get all events matching a filter Same as `eth_getFilterChanges` #### Exceptions Throws `INVALID_PARAMS` if filter cannot be found or if response size is exceeded +#### Notes +Response size limit is determined by `getLogsBlocksLimit` config parameter, and currenly is 2000 logs per request. ### `eth_getLogs` | Compatibility | | @@ -771,6 +771,8 @@ Same as `eth_getFilterLogs`, but doesn't require filter creation Same as `eth_getFilterChanges` #### Exceptions Throws `INVALID_PARAMS` if block does not exist, if response size is exceeded, or `fromBlock` or `toBlock` are present together with `blockHash` +#### Notes +Response size limit is determined by `getLogsBlocksLimit` config parameter, and currenly is 2000 logs per request. ### `eth_compile*` and `eth_getCompilers` Not supported @@ -869,35 +871,6 @@ Object: - "accessList" - empty list; - "gasUsed" - "0x" prefixed hex `String` - result of `eth_estimateGas`. -### `eth_getBlockTransactionCountByHash` -| Compatibility | | -|-----|-----------| -| Core vs ETH | Unknown | -| Historic vs ETH | Unknown | - -#### Description -Get number of transactions in a block -#### Parameters -1. Block hash: "0x"-prefixed hex `String`, 32 bytes -#### Return format -"0x"-prefixed hex `String` - -### `eth_getBlockTransactionCountByNumber` -| Compatibility | | -|-----|-----------| -| Core vs ETH | Unknown | -| Historic vs ETH | Unknown | - -#### Description -Get number of transactions in a block -#### Parameters -1. Block number: - - "latest" or "pending" - latest block is used; - - "earliest" - block 0; - - `String` representation of an integer block number, either decimal or "0x"-prefixed hexadecimal; -#### Return format -"0x"-prefixed hex `String` - ### `eth_getFilterChangesEx` | Compatibility | | |-----|-----------| From bc2fda4d040c98f2a751e6e490b08c9c70fcb551 Mon Sep 17 00:00:00 2001 From: Dima Litvinov Date: Fri, 8 Nov 2024 19:06:00 +0200 Subject: [PATCH 46/47] Update json-rpc-interface.md --- docs/json-rpc-interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/json-rpc-interface.md b/docs/json-rpc-interface.md index 94d4e5db5..e11884cb9 100644 --- a/docs/json-rpc-interface.md +++ b/docs/json-rpc-interface.md @@ -745,7 +745,7 @@ Same as `eth_getFilterChanges` #### Exceptions Throws `INVALID_PARAMS` if filter cannot be found or if response size is exceeded #### Notes -Response size limit is determined by `getLogsBlocksLimit` config parameter, and currenly is 2000 logs per request. +Response size is limited by number of consecutive blocks that can be requested. It is set in `getLogsBlocksLimit` config parameter, which currenly is 2000 blocks. ### `eth_getLogs` | Compatibility | | From 49dd571f9193b718e43e32d2959e7661d011d814 Mon Sep 17 00:00:00 2001 From: Dmytro Nazarenko Date: Mon, 25 Nov 2024 12:38:11 +0000 Subject: [PATCH 47/47] Update VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index eb9b76c9f..fcdb2e109 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.20.0 +4.0.0