diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 00c90351c..61c897ec9 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -1128,10 +1128,9 @@ Transactions Client::pending() const { } SyncStatus Client::syncStatus() const { - // TODO implement this when syncing will be needed - SyncStatus s; - s.startBlockNumber = s.currentBlockNumber = s.highestBlockNumber = 0; - return s; + if ( !m_skaleHost ) + BOOST_THROW_EXCEPTION( std::runtime_error( "SkaleHost was not initialized" ) ); + return m_skaleHost->syncStatus(); } TransactionSkeleton Client::populateTransactionWithDefaults( TransactionSkeleton const& _t ) const { diff --git a/libethereum/SkaleHost.cpp b/libethereum/SkaleHost.cpp index 0cbb4241f..0350fef51 100644 --- a/libethereum/SkaleHost.cpp +++ b/libethereum/SkaleHost.cpp @@ -942,6 +942,21 @@ u256 SkaleHost::getBlockRandom() const { return m_consensus->getRandomForBlockId( m_client.number() ); } +dev::eth::SyncStatus SkaleHost::syncStatus() const { + if ( !m_consensus ) + BOOST_THROW_EXCEPTION( std::runtime_error( "Consensus was not initialized" ) ); + auto syncInfo = m_consensus->getSyncInfo(); + dev::eth::SyncStatus syncStatus; + // SKALE: catchup downloads blocks with transactions, then the node executes them + // we don't download state changes separately + syncStatus.state = syncInfo.isSyncing ? dev::eth::SyncState::Blocks : dev::eth::SyncState::Idle; + syncStatus.startBlockNumber = syncInfo.startingBlock; + syncStatus.currentBlockNumber = syncInfo.currentBlock; + syncStatus.highestBlockNumber = syncInfo.highestBlock; + syncStatus.majorSyncing = syncInfo.isSyncing; + return syncStatus; +} + std::map< std::string, uint64_t > SkaleHost::getConsensusDbUsage() const { return m_consensus->getConsensusDbUsage(); } diff --git a/libethereum/SkaleHost.h b/libethereum/SkaleHost.h index 82a4c6357..a92fc5462 100644 --- a/libethereum/SkaleHost.h +++ b/libethereum/SkaleHost.h @@ -51,6 +51,7 @@ namespace dev { namespace eth { +struct SyncStatus; class Client; class TransactionQueue; class BlockHeader; @@ -123,6 +124,7 @@ class SkaleHost { dev::u256 getGasPrice() const; dev::u256 getBlockRandom() const; + dev::eth::SyncStatus syncStatus() const; std::map< std::string, uint64_t > getConsensusDbUsage() const; std::array< std::string, 4 > getIMABLSPublicKey() const; diff --git a/libweb3jsonrpc/Eth.cpp b/libweb3jsonrpc/Eth.cpp index 135b08584..9686c5301 100644 --- a/libweb3jsonrpc/Eth.cpp +++ b/libweb3jsonrpc/Eth.cpp @@ -892,15 +892,24 @@ Json::Value Eth::eth_getWork() { } Json::Value Eth::eth_syncing() { - dev::eth::SyncStatus sync = client()->syncStatus(); - if ( sync.state == SyncState::Idle || !sync.majorSyncing ) - return Json::Value( false ); - - Json::Value info( Json::objectValue ); - info["startingBlock"] = sync.startBlockNumber; - info["highestBlock"] = sync.highestBlockNumber; - info["currentBlock"] = sync.currentBlockNumber; - return info; + try { + auto client = this->client(); + if ( !client ) + BOOST_THROW_EXCEPTION( std::runtime_error( "Client was not initialized" ) ); + + // ask consensus whether the node is in catchup mode + dev::eth::SyncStatus sync = client->syncStatus(); + if ( !sync.majorSyncing ) + return Json::Value( false ); + + Json::Value info( Json::objectValue ); + info["startingBlock"] = sync.startBlockNumber; + info["highestBlock"] = sync.highestBlockNumber; + info["currentBlock"] = sync.currentBlockNumber; + return info; + } catch ( const Exception& e ) { + BOOST_THROW_EXCEPTION( jsonrpc::JsonRpcException( e.what() ) ); + } } string Eth::eth_chainId() {