diff --git a/catchup/client/CatchupClientAgent.cpp b/catchup/client/CatchupClientAgent.cpp index ebf52356..5dc0b7be 100644 --- a/catchup/client/CatchupClientAgent.cpp +++ b/catchup/client/CatchupClientAgent.cpp @@ -21,14 +21,12 @@ @date 2018 */ -#include "SkaleCommon.h" +#include "thirdparty/json.hpp" +#include "SkaleCommon.h" #include "Log.h" +#include "datastructures/PeerStateInfo.h" #include "exceptions/ExitRequestedException.h" -#include "exceptions/FatalError.h" - -#include "thirdparty/json.hpp" - #include "abstracttcpserver/ConnectionStatus.h" #include "crypto/CryptoManager.h" @@ -59,6 +57,12 @@ CatchupClientAgent::CatchupClientAgent( Schain& _sChain ) : Agent( _sChain, fals this->catchupClientThreadPool = make_shared< CatchupClientThreadPool >( 1, this ); catchupClientThreadPool->startService(); } + + for (int i = 0; i < _sChain.getNodeCount(); i++) { + // init peer state infos + peerStateInfos.push_back(nullptr); + } + } catch ( ExitRequestedException& ) { throw; } catch ( ... ) { @@ -128,6 +132,14 @@ nlohmann::json CatchupClientAgent::readCatchupResponseHeader( throw_with_nested( NetworkProtocolException( errString, __CLASS_NAME__ ) ); } + // now see if peerinfo information returned by the peer + ptr peerStateInfo = PeerStateInfo::extract(response); + + if (peerStateInfo) { + // update the info + LOCK(peerStateInfosMutex) + peerStateInfos.at((uint64_t)_dstIndex) = peerStateInfo; + } LOG( debug, "Catchupc step 2: read catchup response requestHeader" ); @@ -138,16 +150,13 @@ nlohmann::json CatchupClientAgent::readCatchupResponseHeader( return 0; } - if ( status != CONNECTION_PROCEED ) { BOOST_THROW_EXCEPTION( NetworkProtocolException( "Server error in catchup response:" + to_string( status ), __CLASS_NAME__ ) ); } - ptr< CommittedBlockList > blocks; - try { blocks = readMissingBlocks( socket, response, requestHeader ); diff --git a/catchup/client/CatchupClientAgent.h b/catchup/client/CatchupClientAgent.h index 13813d85..cb4bd797 100644 --- a/catchup/client/CatchupClientAgent.h +++ b/catchup/client/CatchupClientAgent.h @@ -23,17 +23,22 @@ #pragma once - class CommittedBlockList; class ClientSocket; class Schain; class CatchupClientThreadPool; class CatchupRequestHeader; class CatchupResponseHeader; +class PeerStateInfo; + class CatchupClientAgent : public Agent { + ptr< CatchupClientThreadPool > catchupClientThreadPool = nullptr; + vector> peerStateInfos; + recursive_mutex peerStateInfosMutex; + public: explicit CatchupClientAgent( Schain& _sChain ); diff --git a/datastructures/PeerStateInfo.cpp b/datastructures/PeerStateInfo.cpp new file mode 100644 index 00000000..c7ed9dff --- /dev/null +++ b/datastructures/PeerStateInfo.cpp @@ -0,0 +1,59 @@ +/* + Copyright (C) 2023- SKALE Labs + + This file is part of skale-consensus. + + skale-consensus is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + skale-consensus is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with skale-consensus. If not, see . + +*/ + +#include "thirdparty/json.hpp" +#include "SkaleCommon.h" +#include "PeerStateInfo.h" + +const block_id &PeerStateInfo::getLastBlockId() const { + return lastBlockId; +} + +uint64_t PeerStateInfo::getLastBlockTimestampS() const { + return lastBlockTimestampS; +} + +PeerStateInfo::PeerStateInfo(const block_id &lastBlockId, uint64_t lastBlockTimestampS) : lastBlockId(lastBlockId), + lastBlockTimestampS( + lastBlockTimestampS) { + +} + +// extract PeerStateInfo object from catchup response header +ptr PeerStateInfo::extract(nlohmann::json _catchupResponseHeasder) { + + uint64_t lastBid = 0; + uint64_t lastTs = 0; + + if (_catchupResponseHeasder.find("lastBid") != _catchupResponseHeasder.end()) { + lastBid = _catchupResponseHeasder.at("lastBid").get(); + } + + if (_catchupResponseHeasder.find("lastTs") != _catchupResponseHeasder.end()) { + lastTs = _catchupResponseHeasder.at("lastTs").get(); + } + + if (lastBid > 0 && lastTs > 0) { + return make_shared(block_id(lastBid), lastTs); + } else { + // the node did not provide info + return nullptr; + } +} diff --git a/datastructures/PeerStateInfo.h b/datastructures/PeerStateInfo.h new file mode 100644 index 00000000..1a08482c --- /dev/null +++ b/datastructures/PeerStateInfo.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2023- SKALE Labs + + This file is part of skale-consensus. + + skale-consensus is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + skale-consensus is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with skale-consensus. If not, see . + +*/ + + +#pragma once + + + +class PeerStateInfo { + + block_id lastBlockId = 0; + uint64_t lastBlockTimestampS = 0; + +public: + const block_id &getLastBlockId() const; + + uint64_t getLastBlockTimestampS() const; + + PeerStateInfo(const block_id &lastBlockId, uint64_t lastBlockTimestampS); + + static ptr extract(nlohmann::json _catchupResponseHeasder); + +}; + +