From e73c5a76fba381250b30b74c9fea614b89403410 Mon Sep 17 00:00:00 2001 From: kladkogex <13399135+kladkogex@users.noreply.github.com> Date: Fri, 6 Jan 2023 16:17:06 +0000 Subject: [PATCH 1/2] 1270 Remove consensus blocks from snapshots --- libethereum/Client.cpp | 12 ++++- libethereum/Client.h | 1 - libethereum/SkaleHost.cpp | 10 ++++ libethereum/SkaleHost.h | 5 ++ libskale/SnapshotManager.cpp | 24 ++++++++- skaled/main.cpp | 14 +++-- test/unittests/libskale/HashSnapshot.cpp | 18 +++++-- test/unittests/libskale/SnapshotManager.cpp | 59 +++++++++++++-------- 8 files changed, 109 insertions(+), 34 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 8b06f76ed..fc9e73044 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -652,7 +652,17 @@ size_t Client::importTransactionsAsBlock( m_debugTracer.tracepoint( "doing_snapshot" ); t1 = boost::chrono::high_resolution_clock::now(); - m_snapshotManager->doSnapshot( block_number ); + + + // get serialized last consensus block + + if ( !m_skaleHost ) { + throw std::runtime_error( "Null skalehost in " + string(__FUNCTION__) ); + } + + m_snapshotManager->doSnapshot( block_number, + m_skaleHost->getSerializedConsensusBlock(block_number)); + t2 = boost::chrono::high_resolution_clock::now(); this->snapshot_calculation_time_ms = boost::chrono::duration_cast< boost::chrono::milliseconds >( t2 - t1 ).count(); diff --git a/libethereum/Client.h b/libethereum/Client.h index 9ba97b482..b271f2daa 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -380,7 +380,6 @@ class Client : public ClientBase, protected Worker { Block blockByNumber( BlockNumber _h ) const; #endif -protected: /// Called when Worker is starting. void startedWorking() override; diff --git a/libethereum/SkaleHost.cpp b/libethereum/SkaleHost.cpp index ba024fffa..71fdd1f81 100644 --- a/libethereum/SkaleHost.cpp +++ b/libethereum/SkaleHost.cpp @@ -375,6 +375,16 @@ class unlock_guard { void will_exit() { m_will_exit = true; } }; + + +std::shared_ptr> SkaleHost::getSerializedConsensusBlock( + std::uint64_t _blockNumber) { + if (!m_extFace) { + throw std::runtime_error("Null m_extFace in " + string(__FUNCTION__)); + } + return this->m_consensus->getSerializedBlock((uint64_t)_blockNumber); +}; + ConsensusExtFace::transactions_vector SkaleHost::pendingTransactions( size_t _limit, u256& _stateRoot ) { assert( _limit > 0 ); diff --git a/libethereum/SkaleHost.h b/libethereum/SkaleHost.h index 3f3a7ed81..a8a4164ed 100644 --- a/libethereum/SkaleHost.h +++ b/libethereum/SkaleHost.h @@ -148,6 +148,11 @@ class SkaleHost { SkaleDebugInterface::handler getDebugHandler() const { return m_debugHandler; } + // Get serialized consensus block for a particular block number + // this is used for snapshots + std::shared_ptr> getSerializedConsensusBlock( + std::uint64_t _blockNumber); + private: std::atomic_bool working = false; std::atomic_bool m_exitedForcefully = false; diff --git a/libskale/SnapshotManager.cpp b/libskale/SnapshotManager.cpp index 553fa6a73..f7fc79e16 100644 --- a/libskale/SnapshotManager.cpp +++ b/libskale/SnapshotManager.cpp @@ -106,7 +106,8 @@ SnapshotManager::SnapshotManager( const fs::path& _dataDir, // - exists // - cannot read // - cannot write -void SnapshotManager::doSnapshot( unsigned _blockNumber ) { +void SnapshotManager::doSnapshot( unsigned _blockNumber, + std::shared_ptr> _serializedLastConsensusBlock) { fs::path snapshot_dir = snapshots_dir / to_string( _blockNumber ); UnsafeRegion::lock ur_lock; @@ -125,6 +126,27 @@ void SnapshotManager::doSnapshot( unsigned _blockNumber ) { } // catch int dummy_counter = 0; + + + // consensus needs the last block to operate after a start from the snapshot + // just before creating snapshot, we copy the last consensus block + // if it was passed to us as a file into the prices.dir + if ( !_serializedLastConsensusBlock ) { + throw std::runtime_error( "Null consensus block in " + string( __FUNCTION__ ) ); + } + + auto pricesDir = volumes.at( SNAPSHOT_PRICES_DIR_INDEX ); + + // if file does not exist, it will be created, if exists it will be overwritten + std::ofstream outputFile( + pricesDir + "/" + LAST_CONSENSUS_BLOCK_FILE_NAME, std::ios::binary | std::ios::out ); + + outputFile.write( ( const char* ) _serializedLastConsensusBlock->data(), + _serializedLastConsensusBlock->size() ); + outputFile.close(); + + + // Now create shapshot for all volumes for ( const string& vol : volumes ) { int res = btrfs.subvolume.snapshot_r( ( data_dir / vol ).c_str(), snapshot_dir.c_str() ); if ( res ) diff --git a/skaled/main.cpp b/skaled/main.cpp index 6c8f6ad24..187724e18 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -290,7 +290,11 @@ void downloadSnapshot( unsigned block_number, std::shared_ptr< SnapshotManager > } /// HACK refactor this piece of code! /// - vector< string > prefixes{ "prices_", "blocks_" }; + // consensus prices directory now contains in addition to + // prices and the last consensus block + // this is the minimum needed for consensus to work well after a start + // from snapshot. + vector< string > prefixes{ SNAPSHOT_PRICES_PREFIX}; for ( const string& prefix : prefixes ) { fs::path db_path; for ( auto& f : @@ -1511,11 +1515,13 @@ int main( int argc, char** argv ) try { // auto mostRecentBlocksDBPath = (getDataDir() / ( "blocks_" + chainParams.nodeInfo.id.str() // + ".db" )) / "1.db"; + // PRICES directory contains prices and the last consensus block + // This is the minimum needed for consensus to work. In particular, + // consensus needs the previous block to make sure that the proposal time stamp + // is more or equal the previous block timestamp snapshotManager.reset( new SnapshotManager( getDataDir(), { BlockChain::getChainDirName( chainParams ), "filestorage", - "prices_" + chainParams.nodeInfo.id.str() + ".db", - "blocks_" + chainParams.nodeInfo.id.str() + ".db"/*, - mostRecentBlocksDBPath.string()*/ }, + SNAPSHOT_PRICES_PREFIX + chainParams.nodeInfo.id.str() + ".db" }, sharedSpace ? sharedSpace->getPath() : "" ) ); } diff --git a/test/unittests/libskale/HashSnapshot.cpp b/test/unittests/libskale/HashSnapshot.cpp index a2fb50a64..06a6ce881 100644 --- a/test/unittests/libskale/HashSnapshot.cpp +++ b/test/unittests/libskale/HashSnapshot.cpp @@ -37,7 +37,16 @@ boost::unit_test::assertion_result option_all_test( boost::unit_test::test_unit_ } namespace dev { -namespace test { +namespace test +{ + + +std::shared_ptr> getSampleLastConsensusBlock() { + std::shared_ptr> sampleLastConsensusBlock; + sampleLastConsensusBlock.reset(new vector { 1, 2, 3, 4, 5}); + return sampleLastConsensusBlock; +} + class SnapshotHashAgentTest { public: SnapshotHashAgentTest( ChainParams& _chainParams, bool requireSnapshotMajority = true ) { @@ -515,6 +524,7 @@ BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE( HashSnapshotTestSuite, *boost::unit_test::precondition( option_all_test ) ) + BOOST_FIXTURE_TEST_CASE( SnapshotHashingTest, SnapshotHashingFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { auto senderAddress = coinbase.address(); @@ -529,11 +539,11 @@ BOOST_FIXTURE_TEST_CASE( SnapshotHashingTest, SnapshotHashingFixture, const int blocksToMine = 1; dev::eth::simulateMining( *( client ), blocksToMine ); - mgr->doSnapshot( 1 ); + mgr->doSnapshot( 1 , getSampleLastConsensusBlock()); mgr->computeSnapshotHash( 1 ); dev::eth::simulateMining( *( client ), blocksToMine ); - mgr->doSnapshot( 2 ); + mgr->doSnapshot( 2 , getSampleLastConsensusBlock()); mgr->computeSnapshotHash( 2 ); @@ -554,7 +564,7 @@ BOOST_FIXTURE_TEST_CASE( SnapshotHashingTest, SnapshotHashingFixture, BOOST_FIXTURE_TEST_CASE( SnapshotHashingFileStorageTest, SnapshotHashingFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - mgr->doSnapshot( 4 ); + mgr->doSnapshot( 4 , getSampleLastConsensusBlock()); mgr->computeSnapshotHash( 4, true ); diff --git a/test/unittests/libskale/SnapshotManager.cpp b/test/unittests/libskale/SnapshotManager.cpp index b3d46dc1a..8100938d5 100644 --- a/test/unittests/libskale/SnapshotManager.cpp +++ b/test/unittests/libskale/SnapshotManager.cpp @@ -19,6 +19,14 @@ using namespace std; namespace fs = boost::filesystem; + +std::shared_ptr> getSampleLastConsensusBlock() { + std::shared_ptr> sampleLastConsensusBlock; + sampleLastConsensusBlock.reset(new vector { 1, 2, 3, 4, 5}); + return sampleLastConsensusBlock; +} + + int setid_system( const char* cmd, uid_t uid, gid_t gid ) { pid_t pid = fork(); if ( pid ) { @@ -173,7 +181,7 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, BOOST_REQUIRE( latest0 == expected0 ); // create snapshot 1 and check its presense - mgr.doSnapshot( 1 ); + mgr.doSnapshot( 1 , getSampleLastConsensusBlock()); 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" ) ); @@ -188,7 +196,7 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, BOOST_REQUIRE( latest1 == expected1 ); // create snapshot 2 and check files 1 and files 2 - mgr.doSnapshot( 2 ); + mgr.doSnapshot( 2 , getSampleLastConsensusBlock()); 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" ) ); @@ -219,7 +227,7 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, std::pair< int, int > expected2 { 1, 2 }; BOOST_REQUIRE( latest2 == expected2 ); - mgr.doSnapshot( 3 ); + mgr.doSnapshot( 3 , getSampleLastConsensusBlock()); auto latest3 = mgr.getLatestSnasphots(); std::pair< int, int > expected3 { 2, 3 }; BOOST_REQUIRE( latest3 == expected3 ); @@ -287,14 +295,16 @@ BOOST_FIXTURE_TEST_CASE( SnapshotTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { SnapshotManager mgr( fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); - BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2 ) ); - BOOST_REQUIRE_THROW( mgr.doSnapshot( 2 ), SnapshotManager::SnapshotPresent ); + BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2, getSampleLastConsensusBlock() ) ); + BOOST_REQUIRE_THROW( mgr.doSnapshot( 2, getSampleLastConsensusBlock() ), + SnapshotManager::SnapshotPresent ); chmod( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" ).c_str(), 0 ); dropRoot(); - BOOST_REQUIRE_EXCEPTION( mgr.doSnapshot( 3 ), SnapshotManager::CannotRead, + BOOST_REQUIRE_EXCEPTION( mgr.doSnapshot( 3 , + getSampleLastConsensusBlock()), SnapshotManager::CannotRead, [this]( const SnapshotManager::CannotRead& ex ) -> bool { return ex.path == fs::path( BTRFS_DIR_PATH ) / "snapshots" / "3"; } ); @@ -303,22 +313,25 @@ BOOST_FIXTURE_TEST_CASE( SnapshotTest, BtrfsFixture, chmod( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" ).c_str(), 0111 ); dropRoot(); - BOOST_REQUIRE_EXCEPTION( mgr.doSnapshot( 3 ), SnapshotManager::CannotCreate, + BOOST_REQUIRE_EXCEPTION( mgr.doSnapshot( 3, getSampleLastConsensusBlock() ), + SnapshotManager::CannotCreate, [this]( const SnapshotManager::CannotCreate& ex ) -> bool { return ex.path == fs::path( BTRFS_DIR_PATH ) / "snapshots" / "3"; } ); // cannot delete - BOOST_REQUIRE_THROW( mgr.restoreSnapshot( 2 ), SnapshotManager::CannotPerformBtrfsOperation ); + BOOST_REQUIRE_THROW( mgr.restoreSnapshot( 2 ), + SnapshotManager::CannotPerformBtrfsOperation ); } BOOST_FIXTURE_TEST_CASE( RestoreTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { SnapshotManager mgr( fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); - BOOST_REQUIRE_THROW( mgr.restoreSnapshot( 2 ), SnapshotManager::SnapshotAbsent ); + BOOST_REQUIRE_THROW( mgr.restoreSnapshot( 2 ), + SnapshotManager::SnapshotAbsent ); - BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2 ) ); + BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2 , getSampleLastConsensusBlock()) ); BOOST_REQUIRE_NO_THROW( mgr.restoreSnapshot( 2 ) ); @@ -331,9 +344,9 @@ BOOST_FIXTURE_TEST_CASE( RestoreTest, BtrfsFixture, BOOST_FIXTURE_TEST_CASE( DiffTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { SnapshotManager mgr( fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); - mgr.doSnapshot( 2 ); + mgr.doSnapshot( 2, getSampleLastConsensusBlock() ); fs::create_directory( fs::path( BTRFS_DIR_PATH ) / "vol1" / "dir" ); - mgr.doSnapshot( 4 ); + mgr.doSnapshot( 4, getSampleLastConsensusBlock() ); BOOST_REQUIRE_THROW( mgr.makeOrGetDiff( 3 ), SnapshotManager::SnapshotAbsent ); BOOST_REQUIRE_NO_THROW( mgr.makeOrGetDiff( 2 ) ); @@ -367,8 +380,8 @@ BOOST_FIXTURE_TEST_CASE( ImportTest, BtrfsFixture, BOOST_REQUIRE_THROW( mgr.importDiff( 8 ), SnapshotManager::InvalidPath ); - BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2 ) ); - BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 4 ) ); + BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2, getSampleLastConsensusBlock() ) ); + BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 4, getSampleLastConsensusBlock() ) ); fs::path diff24; BOOST_REQUIRE_NO_THROW( diff24 = mgr.makeOrGetDiff( 4 ) ); @@ -402,13 +415,13 @@ BOOST_FIXTURE_TEST_CASE( SnapshotRotationTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { SnapshotManager mgr( fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); - BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 1 ) ); + BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 1, getSampleLastConsensusBlock() ) ); sleep( 1 ); - BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 0 ) ); + BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 0, getSampleLastConsensusBlock() ) ); sleep( 1 ); - BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2 ) ); + BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2, getSampleLastConsensusBlock() ) ); sleep( 1 ); - BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 3 ) ); + BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 3, getSampleLastConsensusBlock() ) ); BOOST_REQUIRE_NO_THROW( mgr.leaveNLastSnapshots( 2 ) ); @@ -453,8 +466,8 @@ BOOST_FIXTURE_TEST_CASE( RemoveSnapshotTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { SnapshotManager mgr( fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); - mgr.doSnapshot( 1 ); - mgr.doSnapshot( 2 ); + mgr.doSnapshot( 1 , getSampleLastConsensusBlock() ); + mgr.doSnapshot( 2, getSampleLastConsensusBlock() ); mgr.cleanupButKeepSnapshot( 1 ); @@ -463,7 +476,7 @@ BOOST_FIXTURE_TEST_CASE( RemoveSnapshotTest, BtrfsFixture, BOOST_REQUIRE_NO_THROW( mgr.restoreSnapshot( 1 ) ); - BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2 ) ); + BOOST_REQUIRE_NO_THROW( mgr.doSnapshot( 2, getSampleLastConsensusBlock() ) ); } BOOST_FIXTURE_TEST_CASE( CleanupTest, BtrfsFixture, @@ -471,8 +484,8 @@ BOOST_FIXTURE_TEST_CASE( CleanupTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { SnapshotManager mgr( fs::path( BTRFS_DIR_PATH ), {"vol1", "vol2"} ); - mgr.doSnapshot( 1 ); - mgr.doSnapshot( 2 ); + mgr.doSnapshot( 1, getSampleLastConsensusBlock() ); + mgr.doSnapshot( 2, getSampleLastConsensusBlock() ); mgr.cleanup(); From e467b2ba8d43ed89f7216c8b2a7410d8eda9a6b9 Mon Sep 17 00:00:00 2001 From: kladkogex <13399135+kladkogex@users.noreply.github.com> Date: Tue, 10 Jan 2023 14:44:17 +0000 Subject: [PATCH 2/2] 1319 Verify DA sigs patch time stamp --- libconsensus | 2 +- libethereum/Client.cpp | 4 +++- libethereum/Client.h | 9 +++++---- libethereum/ConsensusStub.cpp | 2 +- libethereum/ConsensusStub.h | 5 ++++- libethereum/SkaleHost.cpp | 6 +++++- libethereum/SkaleHost.h | 3 ++- libskale/SnapshotManager.h | 12 ++++++++++-- 8 files changed, 31 insertions(+), 12 deletions(-) diff --git a/libconsensus b/libconsensus index bb9b1ed16..c7a8f3d17 160000 --- a/libconsensus +++ b/libconsensus @@ -1 +1 @@ -Subproject commit bb9b1ed16b9adeba72b8bb7510ef8a6291839b66 +Subproject commit c7a8f3d17daee9f993118f430f058c6c1209f500 diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index fc9e73044..e5cd23ead 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -214,7 +214,9 @@ void Client::stopWorking() { } -void Client::injectSkaleHost( std::shared_ptr< SkaleHost > _skaleHost ) { +void Client::injectSkaleHost( std::shared_ptr< SkaleHost > _skaleHost, + std::shared_ptr< std::vector< std::uint8_t > > + _startingFromSnapshotWithThisAsLastBlock) { assert( !m_skaleHost ); m_skaleHost = _skaleHost; diff --git a/libethereum/Client.h b/libethereum/Client.h index b271f2daa..219e3bdd6 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -92,8 +92,8 @@ class Client : public ClientBase, protected Worker { void stopWorking(); - void injectSkaleHost( std::shared_ptr< SkaleHost > _skaleHost = nullptr ); - + void injectSkaleHost( std::shared_ptr< SkaleHost > _skaleHost, + std::shared_ptr< std::vector< std::uint8_t > > _startingFromSnapshotWithThisAsLastBlock ); /// Get information on this chain. ChainParams const& chainParams() const { return bc().chainParams(); } @@ -245,10 +245,11 @@ class Client : public ClientBase, protected Worker { Block latestBlock() const; /// should be called after the constructor of the most derived class finishes. - void startWorking() { + void startWorking(std::shared_ptr< std::vector< std::uint8_t > > + _startingFromSnapshotWithThisAsLastBlock) { assert( m_skaleHost ); Worker::startWorking(); // these two lines are dependent!! - m_skaleHost->startWorking(); + m_skaleHost->startWorking(_startingFromSnapshotWithThisAsLastBlock); }; /// Change the function that is called when a new block is imported diff --git a/libethereum/ConsensusStub.cpp b/libethereum/ConsensusStub.cpp index 23215a836..7e3717859 100644 --- a/libethereum/ConsensusStub.cpp +++ b/libethereum/ConsensusStub.cpp @@ -57,7 +57,7 @@ void ConsensusStub::parseFullConfigAndCreateNode( const std::string&, const std: // TODO think this architecture thoroughly } -void ConsensusStub::startAll() { +void ConsensusStub::startAll( std::shared_ptr< std::vector< std::uint8_t > > ) { Worker::startWorking(); } diff --git a/libethereum/ConsensusStub.h b/libethereum/ConsensusStub.h index d102b78fc..beb852191 100644 --- a/libethereum/ConsensusStub.h +++ b/libethereum/ConsensusStub.h @@ -41,7 +41,10 @@ class ConsensusStub : private dev::Worker, public ConsensusInterface { ~ConsensusStub() override; void parseFullConfigAndCreateNode( const std::string& _jsonConfig, const string& _gethURL ) override; - void startAll() override; + + void startAll( + std::shared_ptr< std::vector< std::uint8_t > > _startingFromSnapshotWithThisAsLastBlock ) + override; void bootStrapAll() override; void exitGracefully() override; u256 getPriceForBlockId( uint64_t /*_blockId*/ ) const override { return 1000; } diff --git a/libethereum/SkaleHost.cpp b/libethereum/SkaleHost.cpp index 71fdd1f81..e9e8093a7 100644 --- a/libethereum/SkaleHost.cpp +++ b/libethereum/SkaleHost.cpp @@ -783,7 +783,11 @@ void SkaleHost::createBlock( const ConsensusExtFace::transactions_vector& _appro cerror << "\n" << skutils::signal::generate_stack_trace() << "\n" << std::endl; } -void SkaleHost::startWorking() { +// If starting from a snapshot, startWorking() all will pass to consensus the last comitted +// block coming from the snapshot. Normally, nullptr is passed. +void SkaleHost::startWorking( + std::shared_ptr< std::vector< std::uint8_t > > + _startingFromSnapshotWithThisAsLastBlock) { if ( working ) return; diff --git a/libethereum/SkaleHost.h b/libethereum/SkaleHost.h index a8a4164ed..8ecf674e2 100644 --- a/libethereum/SkaleHost.h +++ b/libethereum/SkaleHost.h @@ -111,7 +111,8 @@ class SkaleHost { const std::string& _gethURL = "", bool _broadcastEnabled = true ); virtual ~SkaleHost(); - void startWorking(); + void startWorking(std::shared_ptr< std::vector< std::uint8_t > > + _startingFromSnapshotWithThisAsLastBlock); void stopWorking(); bool isWorking() const { return this->working; } bool exitedForcefully() const { return m_exitedForcefully; } diff --git a/libskale/SnapshotManager.h b/libskale/SnapshotManager.h index 2dd15280b..886d5abe7 100644 --- a/libskale/SnapshotManager.h +++ b/libskale/SnapshotManager.h @@ -35,6 +35,13 @@ #include #include +const std::string SNAPSHOT_PRICES_PREFIX = "prices_"; +const std::string LAST_CONSENSUS_BLOCK_FILE_NAME = "last_consensus_block.bin"; + +constexpr std::uint64_t SNAPSHOT_PRICES_DIR_INDEX = 2; + + + class SnapshotManager { //////////////////////// EXCEPTIONS ///////////////////// @@ -154,9 +161,10 @@ class SnapshotManager { public: SnapshotManager( const boost::filesystem::path& _dataDir, const std::vector< std::string >& _volumes, const std::string& diffs_dir = std::string() ); - void doSnapshot( unsigned _blockNumber ); + void doSnapshot( unsigned _blockNumber, + std::shared_ptr> _serializedLastConsensusBlock ); void restoreSnapshot( unsigned _blockNumber ); - boost::filesystem::path makeOrGetDiff( unsigned _toBlock ); + boost::filesystem::path makeOrGetDiff( unsigned _toBlock); void importDiff( unsigned _toBlock ); boost::filesystem::path getDiffPath( unsigned _toBlock ); void removeSnapshot( unsigned _blockNumber );