diff --git a/src/blockchain/BitcoinBlockchain.cpp b/src/blockchain/BitcoinBlockchain.cpp index e1f7a57..843f0e6 100644 --- a/src/blockchain/BitcoinBlockchain.cpp +++ b/src/blockchain/BitcoinBlockchain.cpp @@ -6,9 +6,9 @@ #include #include +#include "../transport/btcclient.h" #include "config/FbftConfig.h" #include "generate.h" -#include "../transport/btcclient.h" using namespace std; using namespace itcoin::blockchain; @@ -16,130 +16,83 @@ using namespace itcoin::blockchain; namespace itcoin { namespace blockchain { -BitcoinBlockchain::BitcoinBlockchain(const itcoin::FbftConfig& conf, transport::BtcClient& bitcoind): -Blockchain(conf), m_bitcoind(bitcoind) -{ +BitcoinBlockchain::BitcoinBlockchain(const itcoin::FbftConfig& conf, transport::BtcClient& bitcoind) + : Blockchain(conf), m_bitcoind(bitcoind) { m_reward_address = m_conf.replica_set_v().at(m_conf.id()).p2pkh(); - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% BitcoinBlockchain, using reward address %2%.") - % m_conf.id() - % m_reward_address - ); + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% BitcoinBlockchain, using reward address %2%.") % + m_conf.id() % m_reward_address); } -CBlock BitcoinBlockchain::GenerateBlock(uint32_t block_timestamp) -{ +CBlock BitcoinBlockchain::GenerateBlock(uint32_t block_timestamp) { return generateBlock(m_bitcoind, m_reward_address, block_timestamp); } -bool BitcoinBlockchain::TestBlockValidity(const uint32_t height, const CBlock& block, bool check_signet_solution) -{ +bool BitcoinBlockchain::TestBlockValidity(const uint32_t height, const CBlock& block, + bool check_signet_solution) { auto block_ser = HexSerializableCBlock(block); const uint32_t block_size_bytes = block_ser.GetHex().length() / 2; const std::string block_hash = block.GetBlockHeader().GetHash().ToString(); BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% BitcoinBlockchain::TestBlockValidity invoking for " - "candidate block at height %2%, blocksize %3% bytes, block hash: %4%") - % m_conf.id() - % height - % block_size_bytes - % block_hash - ); + boost::format("R%1% BitcoinBlockchain::TestBlockValidity invoking for " + "candidate block at height %2%, blocksize %3% bytes, block hash: %4%") % + m_conf.id() % height % block_size_bytes % block_hash); Json::Value result; - try - { + try { result = m_bitcoind.testblockvalidity(block_ser.GetHex(), check_signet_solution); - } - catch (jsonrpc::JsonRpcException& e) { - BOOST_LOG_TRIVIAL(warning) << str( - boost::format("R%1% BitcoinBlockchain::TestBlockValidity for candidate " - "block at height %2% with hash %3% raised %4%.") - % m_conf.id() - % height - % block_hash - % e.what() - ); + } catch (jsonrpc::JsonRpcException& e) { + BOOST_LOG_TRIVIAL(warning) << str(boost::format("R%1% BitcoinBlockchain::TestBlockValidity for candidate " + "block at height %2% with hash %3% raised %4%.") % + m_conf.id() % height % block_hash % e.what()); return false; } BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% BitcoinBlockchain::TestBlockValidity for candidate " - "block at height %2% with hash %3%. Result = %4% (null means ok).") - % m_conf.id() - % height - % block_hash - % result - ); + boost::format("R%1% BitcoinBlockchain::TestBlockValidity for candidate " + "block at height %2% with hash %3%. Result = %4% (null means ok).") % + m_conf.id() % height % block_hash % result); return true; } -void BitcoinBlockchain::SubmitBlock(const uint32_t height, const CBlock& block) -{ +void BitcoinBlockchain::SubmitBlock(const uint32_t height, const CBlock& block) { const auto block_ser = HexSerializableCBlock(block); const std::string block_hash = block.GetBlockHeader().GetHash().ToString(); try { const uint32_t block_size_bytes = block_ser.GetHex().length() / 2; BOOST_LOG_TRIVIAL(debug) << str( - boost::format( - "R%1% BitcoinBlockchain::SubmitBlock submitting block at height %2% " - "block size: %3% bytes, block hash: %4%" - ) - % m_conf.id() - % height - % block_size_bytes - % block_hash - ); + boost::format("R%1% BitcoinBlockchain::SubmitBlock submitting block at height %2% " + "block size: %3% bytes, block hash: %4%") % + m_conf.id() % height % block_size_bytes % block_hash); auto result = m_bitcoind.submitblock(block_ser.GetHex()); - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% BitcoinBlockchain::SubmitBlock for block at height " - "%2%, block hash: %3%. Result = %4% (null means ok).") - % m_conf.id() - % height - % block_hash - % result - ); - } - catch (const jsonrpc::JsonRpcException& e) - { - if (e.GetMessage() == "The response is invalid: \"duplicate\"\n") - { + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% BitcoinBlockchain::SubmitBlock for block at height " + "%2%, block hash: %3%. Result = %4% (null means ok).") % + m_conf.id() % height % block_hash % result); + } catch (const jsonrpc::JsonRpcException& e) { + if (e.GetMessage() == "The response is invalid: \"duplicate\"\n") { BOOST_LOG_TRIVIAL(warning) << str( - boost::format("R%1% BitcoinBlockchain::SubmitBlock the submitblock " - "invocation for block height %2% (hash %3%) failed because the block " - "was already in the blockchain. Most probably another replica already " - "submitted the same block and was propagated to the local node before " - "the submitblock call was attempted.") - % m_conf.id() - % height - % block_hash - ); - } - else if (e.GetMessage() == "The response is invalid: \"inconclusive\"\n") { + boost::format("R%1% BitcoinBlockchain::SubmitBlock the submitblock " + "invocation for block height %2% (hash %3%) failed because the block " + "was already in the blockchain. Most probably another replica already " + "submitted the same block and was propagated to the local node before " + "the submitblock call was attempted.") % + m_conf.id() % height % block_hash); + } else if (e.GetMessage() == "The response is invalid: \"inconclusive\"\n") { BOOST_LOG_TRIVIAL(warning) << str( - boost::format("R%1% BitcoinBlockchain::SubmitBlock the submitblock " - "invocation for height %2% (hash %3%) returned 'inconclusive'. This " - "problem is temporarily ignored.") - % m_conf.id() - % height - % block_hash - ); - } - else { + boost::format("R%1% BitcoinBlockchain::SubmitBlock the submitblock " + "invocation for height %2% (hash %3%) returned 'inconclusive'. This " + "problem is temporarily ignored.") % + m_conf.id() % height % block_hash); + } else { BOOST_LOG_TRIVIAL(error) << str( - boost::format("R%1% BitcoinBlockchain::SubmitBlock got exception " - "while trying to submit block at height %2% (hash %3%): %4%") - % m_conf.id() - % height - % block_hash - % e.what() - ); + boost::format("R%1% BitcoinBlockchain::SubmitBlock got exception " + "while trying to submit block at height %2% (hash %3%): %4%") % + m_conf.id() % height % block_hash % e.what()); throw e; } } } -} -} +} // namespace blockchain +} // namespace itcoin diff --git a/src/blockchain/Blockchain.cpp b/src/blockchain/Blockchain.cpp index 1813fa3..56a3e54 100644 --- a/src/blockchain/Blockchain.cpp +++ b/src/blockchain/Blockchain.cpp @@ -6,10 +6,7 @@ namespace itcoin { namespace blockchain { -Blockchain::Blockchain(const itcoin::FbftConfig& conf): -m_conf(conf) -{ -} +Blockchain::Blockchain(const itcoin::FbftConfig& conf) : m_conf(conf) {} -} -} +} // namespace blockchain +} // namespace itcoin diff --git a/src/blockchain/HexSerializableCBlock.cpp b/src/blockchain/HexSerializableCBlock.cpp index 5d507fb..eb997da 100644 --- a/src/blockchain/HexSerializableCBlock.cpp +++ b/src/blockchain/HexSerializableCBlock.cpp @@ -13,36 +13,22 @@ using namespace std; namespace itcoin { namespace blockchain { -HexSerializableCBlock::HexSerializableCBlock() -{ +HexSerializableCBlock::HexSerializableCBlock() {} -} - -HexSerializableCBlock::HexSerializableCBlock(CBlock block): -CBlock(block) -{ - -} +HexSerializableCBlock::HexSerializableCBlock(CBlock block) : CBlock(block) {} -HexSerializableCBlock::HexSerializableCBlock(std::string block_hex) -{ +HexSerializableCBlock::HexSerializableCBlock(std::string block_hex) { std::string block_str = utils::hexToString(block_hex); - Span block_span { - reinterpret_cast(&block_str[0]), - block_str.size() - }; - CDataStream dataStream { - block_span, SER_NETWORK, PROTOCOL_VERSION - }; + Span block_span{reinterpret_cast(&block_str[0]), block_str.size()}; + CDataStream dataStream{block_span, SER_NETWORK, PROTOCOL_VERSION}; this->Unserialize(dataStream); } -std::string HexSerializableCBlock::GetHex() const -{ +std::string HexSerializableCBlock::GetHex() const { CDataStream dataStream{SER_NETWORK, PROTOCOL_VERSION}; this->Serialize(dataStream); return utils::stringToHex(dataStream.str()); } -} -} +} // namespace blockchain +} // namespace itcoin diff --git a/src/blockchain/blockchain.h b/src/blockchain/blockchain.h index c54f2f7..cc9d744 100644 --- a/src/blockchain/blockchain.h +++ b/src/blockchain/blockchain.h @@ -7,53 +7,52 @@ #include namespace itcoin { - class FbftConfig; +class FbftConfig; } -namespace itcoin { namespace transport { - class BtcClient; -}} // namespace itcoin::transport +namespace itcoin { +namespace transport { +class BtcClient; +} +} // namespace itcoin namespace itcoin { namespace blockchain { -class HexSerializableCBlock: public CBlock -{ - public: - HexSerializableCBlock(); - HexSerializableCBlock(CBlock block); - HexSerializableCBlock(std::string block_hex); - std::string GetHex() const; +class HexSerializableCBlock : public CBlock { +public: + HexSerializableCBlock(); + HexSerializableCBlock(CBlock block); + HexSerializableCBlock(std::string block_hex); + std::string GetHex() const; }; -class Blockchain -{ - public: - Blockchain(const itcoin::FbftConfig& conf); +class Blockchain { +public: + Blockchain(const itcoin::FbftConfig& conf); - virtual CBlock GenerateBlock(uint32_t block_timestamp) = 0; - virtual bool TestBlockValidity(const uint32_t height, const CBlock&, bool check_signet_solution) = 0; - virtual void SubmitBlock(const uint32_t height, const CBlock&) = 0; + virtual CBlock GenerateBlock(uint32_t block_timestamp) = 0; + virtual bool TestBlockValidity(const uint32_t height, const CBlock&, bool check_signet_solution) = 0; + virtual void SubmitBlock(const uint32_t height, const CBlock&) = 0; - protected: - const itcoin::FbftConfig& m_conf; +protected: + const itcoin::FbftConfig& m_conf; }; -class BitcoinBlockchain: public Blockchain -{ - public: - BitcoinBlockchain(const itcoin::FbftConfig& conf, transport::BtcClient& bitcoind); +class BitcoinBlockchain : public Blockchain { +public: + BitcoinBlockchain(const itcoin::FbftConfig& conf, transport::BtcClient& bitcoind); - CBlock GenerateBlock(uint32_t block_timestamp); - bool TestBlockValidity(const uint32_t height, const CBlock& block, bool check_signet_solution); - void SubmitBlock(const uint32_t height, const CBlock& block); + CBlock GenerateBlock(uint32_t block_timestamp); + bool TestBlockValidity(const uint32_t height, const CBlock& block, bool check_signet_solution); + void SubmitBlock(const uint32_t height, const CBlock& block); - protected: - transport::BtcClient& m_bitcoind; - std::string m_reward_address; +protected: + transport::BtcClient& m_bitcoind; + std::string m_reward_address; }; -} -} +} // namespace blockchain +} // namespace itcoin #endif // ITCOIN_BLOCKCHAIN_BLOCKCHAIN_H diff --git a/src/blockchain/extract.cpp b/src/blockchain/extract.cpp index 6b834f9..48bcaf9 100644 --- a/src/blockchain/extract.cpp +++ b/src/blockchain/extract.cpp @@ -10,11 +10,10 @@ #include #include +namespace itcoin { +namespace blockchain { -namespace itcoin { namespace blockchain { - -void appendSignetSolution(CBlock *block, std::vector signetSolution) -{ +void appendSignetSolution(CBlock* block, std::vector signetSolution) { /* * Append the signet solution * @@ -51,9 +50,8 @@ void appendSignetSolution(CBlock *block, std::vector signetSoluti block->vtx[0] = MakeTransactionRef(tx); } - -std::pair signetTxs(const CBlock& block, const std::string& signetChallengeHex) -{ +std::pair signetTxs(const CBlock& block, + const std::string& signetChallengeHex) { // assumes signet solution has not been added yet so does not need to be removed // ITCOIN_SPECIFIC START // assumes SIGNET_HEADER has already been added so does not need to be added here @@ -112,5 +110,5 @@ std::pair signetTxs(const CBlock& bloc return std::make_pair(spend, to_spend); } // signetTxs() - -}} // namespace itcoin::blockchain +} // namespace blockchain +} // namespace itcoin diff --git a/src/blockchain/extract.h b/src/blockchain/extract.h index 392240d..30f123e 100644 --- a/src/blockchain/extract.h +++ b/src/blockchain/extract.h @@ -6,15 +6,20 @@ #include -namespace itcoin { namespace transport { - class BtcClient; -}} // namespace itcoin::transport +namespace itcoin { +namespace transport { +class BtcClient; +} +} // namespace itcoin -namespace itcoin { namespace blockchain { +namespace itcoin { +namespace blockchain { -void appendSignetSolution(CBlock *block, std::vector signetSolution); -std::pair signetTxs(const CBlock& block, const std::string& signetChallengeHex); +void appendSignetSolution(CBlock* block, std::vector signetSolution); +std::pair signetTxs(const CBlock& block, + const std::string& signetChallengeHex); -}} // namespace itcoin::blockchain +} // namespace blockchain +} // namespace itcoin #endif // ITCOIN_BLOCKCHAIN_EXTRACT_H diff --git a/src/blockchain/generate.cpp b/src/blockchain/generate.cpp index 39e590e..c2c809b 100644 --- a/src/blockchain/generate.cpp +++ b/src/blockchain/generate.cpp @@ -13,10 +13,11 @@ #include #include "../transport/btcclient.h" -#include "grind.h" #include "../utils/utils.h" +#include "grind.h" -namespace itcoin { namespace blockchain { +namespace itcoin { +namespace blockchain { const std::vector WITNESS_COMMITMENT_HEADER = {0xaa, 0x21, 0xa9, 0xed}; @@ -24,13 +25,13 @@ const std::vector WITNESS_COMMITMENT_HEADER = {0xaa, 0x21, 0xa9, * * Get block template from the Bitcoin node with Signet and SegWit rules. * - * This code mimics https://github.com/bancaditalia/itcoin-core/blob/2f37bb2000665da31e4f45ebcdbfd059b1f3b2df/contrib/signet/miner.py#L368 + * This code mimics + * https://github.com/bancaditalia/itcoin-core/blob/2f37bb2000665da31e4f45ebcdbfd059b1f3b2df/contrib/signet/miner.py#L368 * * @param bitcoindClient * @return the block template */ -Json::Value getSignetAndSegwitBlockTemplate(transport::BtcClient& bitcoindClient) -{ +Json::Value getSignetAndSegwitBlockTemplate(transport::BtcClient& bitcoindClient) { Json::Value root; Json::Value rules; @@ -45,10 +46,11 @@ Json::Value getSignetAndSegwitBlockTemplate(transport::BtcClient& bitcoindClient * Bitcoin script opcodes can represent numeric literals between 0 and 16 * inclusive (0 is a special case). This function performs the encoding. */ -uint64_t encodeOpN(uint64_t number) -{ - if (not (0 <= number && number <= 16)) { - throw std::runtime_error("Only numbers between 0 and 16 inclusive can be represented as OP_XX opcodes. Got " + std::to_string(number)); +uint64_t encodeOpN(uint64_t number) { + if (not(0 <= number && number <= 16)) { + throw std::runtime_error( + "Only numbers between 0 and 16 inclusive can be represented as OP_XX opcodes. Got " + + std::to_string(number)); } if (number == 0) { @@ -58,8 +60,7 @@ uint64_t encodeOpN(uint64_t number) return OP_1 + number - 1; } // encodeOpN() -CScript getScriptBIP34CoinbaseHeight(uint64_t height) -{ +CScript getScriptBIP34CoinbaseHeight(uint64_t height) { CScript result = CScript(); if (height <= 16) { @@ -78,8 +79,7 @@ CScript getScriptBIP34CoinbaseHeight(uint64_t height) return result; } // getScriptBIP34CoinbaseHeight() -CTransactionRef buildCoinbaseTransaction(uint64_t height, CAmount value, CScript scriptPubKey) -{ +CTransactionRef buildCoinbaseTransaction(uint64_t height, CAmount value, CScript scriptPubKey) { auto tx = CMutableTransaction(); tx.nVersion = 1; tx.vin.resize(1); @@ -95,8 +95,7 @@ CTransactionRef buildCoinbaseTransaction(uint64_t height, CAmount value, CScript return MakeTransactionRef(tx); } // buildCoinbaseTransaction() -CScript getScriptPubKey(transport::BtcClient& bitcoindClient, const std::string& address) -{ +CScript getScriptPubKey(transport::BtcClient& bitcoindClient, const std::string& address) { // TODO avoid 'getaddressinfo' request by adding scriptPubKey of address in the configuration file const Json::Value addressInfo = bitcoindClient.getaddressinfo(address); const std::string scriptPubKeyHex = addressInfo["scriptPubKey"].asString(); @@ -107,16 +106,14 @@ CScript getScriptPubKey(transport::BtcClient& bitcoindClient, const std::string& return scriptPubKey; } // getScriptPubKey() -CMutableTransaction TxFromHex(const std::string& str) -{ +CMutableTransaction TxFromHex(const std::string& str) { CMutableTransaction tx; SpanReader{SER_NETWORK, PROTOCOL_VERSION, ParseHex(str)} >> tx; return tx; } // TxFromHex() -CScript GetWitnessScript(uint256 witnessRoot, uint256 witnessNonce) -{ +CScript GetWitnessScript(uint256 witnessRoot, uint256 witnessNonce) { const std::vector witnessRootData(witnessRoot.begin(), witnessRoot.end()); const std::vector witnessNonceData(witnessNonce.begin(), witnessNonce.end()); std::vector concat; @@ -136,8 +133,8 @@ CScript GetWitnessScript(uint256 witnessRoot, uint256 witnessNonce) return CScript() << OP_RETURN << data; } // GetWitnessScript() -CBlock generateBlock(transport::BtcClient& bitcoindClient, const std::string& address, uint32_t block_timestamp) -{ +CBlock generateBlock(transport::BtcClient& bitcoindClient, const std::string& address, + uint32_t block_timestamp) { // create block template - START Json::Value blockTemplate; std::string previousBlockHash; @@ -181,22 +178,19 @@ CBlock generateBlock(transport::BtcClient& bitcoindClient, const std::string& ad "Network-adjusted time" is the median of the timestamps returned by all nodes connected to you. As a result block timestamps are not exactly accurate, and they do not need to be. Block times are accurate only to within an hour or two. - Whenever a node connects to another node, it gets a UTC timestamp from it, and stores its offset from node-local UTC. - The network-adjusted time is then the node-local UTC plus the median offset from all connected nodes. - Network time is never adjusted more than 70 minutes from local system time, however. + Whenever a node connects to another node, it gets a UTC timestamp from it, and stores its offset from + node-local UTC. The network-adjusted time is then the node-local UTC plus the median offset from all + connected nodes. Network time is never adjusted more than 70 minutes from local system time, however. WAS: const uint32_t curTime = blockTemplate["curtime"].asUInt(); block.nTime = curTime < minTime? minTime: curTime; */ - if (block_timestamp> newHeader; block.nNonce = newHeader.nNonce; - BOOST_LOG_TRIVIAL(trace) << "Block merkle root (function which includes signatures) after mining: " << BlockMerkleRoot(block).GetHex(); + BOOST_LOG_TRIVIAL(trace) << "Block merkle root (function which includes signatures) after mining: " + << BlockMerkleRoot(block).GetHex(); BOOST_LOG_TRIVIAL(trace) << "Grinded block: " << block.ToString(); } // mine block - END return block; } // generateBlock() -}} // namespace itcoin::blockchain +} // namespace blockchain +} // namespace itcoin diff --git a/src/blockchain/generate.h b/src/blockchain/generate.h index 2f4f862..42e14ee 100644 --- a/src/blockchain/generate.h +++ b/src/blockchain/generate.h @@ -6,11 +6,14 @@ #include -namespace itcoin { namespace transport { - class BtcClient; -}} // namespace itcoin::transport +namespace itcoin { +namespace transport { +class BtcClient; +} +} // namespace itcoin -namespace itcoin { namespace blockchain { +namespace itcoin { +namespace blockchain { const std::vector SIGNET_HEADER_VEC = std::vector{0xec, 0xc7, 0xda, 0xa2}; @@ -36,7 +39,8 @@ const std::vector SIGNET_HEADER_VEC = std::vector{ * @param address the reward address for the coinbase transaction * @return the generated block */ -CBlock generateBlock(transport::BtcClient& bitcoindClient, const std::string& address, uint32_t block_timestamp); +CBlock generateBlock(transport::BtcClient& bitcoindClient, const std::string& address, + uint32_t block_timestamp); /** * Get the scriptPubKey of a Bitcoin address. @@ -56,6 +60,7 @@ CScript getScriptPubKey(transport::BtcClient& bitcoindClient, const std::string& */ CScript GetWitnessScript(uint256 witnessRoot, uint256 witnessNonce); -}} // namespace itcoin::blockchain +} // namespace blockchain +} // namespace itcoin #endif // ITCOIN_BLOCKCHAIN_GENERATE_H diff --git a/src/blockchain/grind.cpp b/src/blockchain/grind.cpp index 0cc20ef..6e01517 100644 --- a/src/blockchain/grind.cpp +++ b/src/blockchain/grind.cpp @@ -9,50 +9,50 @@ #include #include -void grind_task(uint32_t nBits, CBlockHeader& header_orig, uint32_t offset, uint32_t step, std::atomic& found) -{ - arith_uint256 target; - bool neg, over; - target.SetCompact(nBits, &neg, &over); - if (target == 0 || neg || over) return; - CBlockHeader header = header_orig; // working copy - header.nNonce = offset; - - uint32_t finish = std::numeric_limits::max() - step; - finish = finish - (finish % step) + offset; - - while (!found && header.nNonce < finish) { - const uint32_t next = (finish - header.nNonce < 5000*step) ? finish : header.nNonce + 5000*step; - do { - if (UintToArith256(header.GetHash()) <= target) { - if (!found.exchange(true)) { - header_orig.nNonce = header.nNonce; - } - return; - } - header.nNonce += step; - } while(header.nNonce != next); - } +void grind_task(uint32_t nBits, CBlockHeader& header_orig, uint32_t offset, uint32_t step, + std::atomic& found) { + arith_uint256 target; + bool neg, over; + target.SetCompact(nBits, &neg, &over); + if (target == 0 || neg || over) + return; + CBlockHeader header = header_orig; // working copy + header.nNonce = offset; + + uint32_t finish = std::numeric_limits::max() - step; + finish = finish - (finish % step) + offset; + + while (!found && header.nNonce < finish) { + const uint32_t next = (finish - header.nNonce < 5000 * step) ? finish : header.nNonce + 5000 * step; + do { + if (UintToArith256(header.GetHash()) <= target) { + if (!found.exchange(true)) { + header_orig.nNonce = header.nNonce; + } + return; + } + header.nNonce += step; + } while (header.nNonce != next); + } } -std::string Grind(std::string hexHeader) -{ - CBlockHeader header; - if (!DecodeHexBlockHeader(header, hexHeader)) { - throw std::invalid_argument("Could not decode block header"); - } +std::string Grind(std::string hexHeader) { + CBlockHeader header; + if (!DecodeHexBlockHeader(header, hexHeader)) { + throw std::invalid_argument("Could not decode block header"); + } - uint32_t nBits = header.nBits; - std::atomic found{false}; + uint32_t nBits = header.nBits; + std::atomic found{false}; - grind_task(nBits, std::ref(header), 0, 1, std::ref(found)); + grind_task(nBits, std::ref(header), 0, 1, std::ref(found)); - if (!found) { - throw std::runtime_error("Could not satisfy difficulty target"); - } + if (!found) { + throw std::runtime_error("Could not satisfy difficulty target"); + } - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << header; + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << header; - return HexStr(ss); + return HexStr(ss); } diff --git a/src/blockchain/grind.h b/src/blockchain/grind.h index 8041107..60147ea 100644 --- a/src/blockchain/grind.h +++ b/src/blockchain/grind.h @@ -13,11 +13,12 @@ class CBlockHeader; * To check that the function stays consistent as bitcoin-core evolces, one can * run (for example in CI) scripts/check-code-consistency.py */ -void grind_task(uint32_t nBits, CBlockHeader& header_orig, uint32_t offset, uint32_t step, std::atomic& found); +void grind_task(uint32_t nBits, CBlockHeader& header_orig, uint32_t offset, uint32_t step, + std::atomic& found); /** * Loosely based on Grind() in bitcoin-util.cpp */ std::string Grind(std::string hexHeader); -#endif //ITCOIN_BITCOIN_CORE_GRIND_H +#endif // ITCOIN_BITCOIN_CORE_GRIND_H diff --git a/src/config/FbftConfig.cpp b/src/config/FbftConfig.cpp index 9a475b2..0192102 100644 --- a/src/config/FbftConfig.cpp +++ b/src/config/FbftConfig.cpp @@ -23,8 +23,7 @@ namespace itcoin { const string DEFAULT_MINER_CONF_FILENAME = "miner.conf.json"; const string DEFAULT_FBFT_DB_FILENAME = "miner.fbft.db"; -FbftConfig::FbftConfig(std::string datadir, std::string configFileName) -{ +FbftConfig::FbftConfig(std::string datadir, std::string configFileName) { string bitcoin_config_file = datadir + "/" + BITCOIN_CONF_FILENAME; string miner_config_file = datadir + "/" + DEFAULT_MINER_CONF_FILENAME; @@ -39,13 +38,22 @@ FbftConfig::FbftConfig(std::string datadir, std::string configFileName) gArgs.ClearArgs(); // Read bitcoind configuration - gArgs.AddArg("-datadir=", "Specify data directory. The miner will read its configuration from " + configFileName + ", and the bitcoind specific data from " + miner_config_file, ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + gArgs.AddArg("-datadir=", + "Specify data directory. The miner will read its configuration from " + configFileName + + ", and the bitcoind specific data from " + miner_config_file, + ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); SetupChainParamsBaseOptions(gArgs); - gArgs.AddArg("-rpcpassword=", "Password for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - gArgs.AddArg("-rpcport=", strprintf("Connect to JSON-RPC on "), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::OPTIONS); - gArgs.AddArg("-rpcuser=", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - gArgs.AddArg("-signetchallenge=", "The signet challenge.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - gArgs.AddArg("-zmqpubitcoinblock=
", "Enable publish hash block, height and time in
(ITCOIN_SPECIFIC)", ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ); + gArgs.AddArg("-rpcpassword=", "Password for JSON-RPC connections", ArgsManager::ALLOW_ANY, + OptionsCategory::OPTIONS); + gArgs.AddArg("-rpcport=", strprintf("Connect to JSON-RPC on "), + ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::OPTIONS); + gArgs.AddArg("-rpcuser=", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY, + OptionsCategory::OPTIONS); + gArgs.AddArg("-signetchallenge=", "The signet challenge.", ArgsManager::ALLOW_ANY, + OptionsCategory::OPTIONS); + gArgs.AddArg("-zmqpubitcoinblock=
", + "Enable publish hash block, height and time in
(ITCOIN_SPECIFIC)", + ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ); // Parse bitcoind config file gArgs.ForceSetArg("-datadir", datadir); @@ -57,7 +65,8 @@ FbftConfig::FbftConfig(std::string datadir, std::string configFileName) // Select the bitcoin config file section for the signet network string chain_name = gArgs.GetChainName(); if (chain_name != "signet") { - std::string msg = "chain_name's value is \"" + chain_name + "\", but the only allowed value is \"signet\""; + std::string msg = + "chain_name's value is \"" + chain_name + "\", but the only allowed value is \"signet\""; BOOST_LOG_TRIVIAL(error) << msg; throw std::runtime_error(msg); @@ -74,14 +83,16 @@ FbftConfig::FbftConfig(std::string datadir, std::string configFileName) // extract the TCP port from the zmqpubitcoinblock bind string in bitcoin.conf std::string itcoinblock_bind_string = gArgs.GetArg("-zmqpubitcoinblock", ""); if (itcoinblock_bind_string == "") { - std::string msg = "itcoin-core is not configured to send new blocks notifications via \"-zmqpubitcoinblock\" parameter. Please configure bitcoind.conf accordingly."; + std::string msg = "itcoin-core is not configured to send new blocks notifications via " + "\"-zmqpubitcoinblock\" parameter. Please configure bitcoind.conf accordingly."; BOOST_LOG_TRIVIAL(error) << msg; throw std::runtime_error(msg); } std::size_t colon_pos = itcoinblock_bind_string.find_last_of(":"); if (colon_pos == std::string::npos) { - std::string msg = "cannot find TCP port in \"-zmqpubitcoinblock\" parameter: \"" + itcoinblock_bind_string + "\" contains no \":\""; + std::string msg = "cannot find TCP port in \"-zmqpubitcoinblock\" parameter: \"" + + itcoinblock_bind_string + "\" contains no \":\""; BOOST_LOG_TRIVIAL(error) << msg; throw std::runtime_error(msg); } @@ -91,26 +102,30 @@ FbftConfig::FbftConfig(std::string datadir, std::string configFileName) long unsigned int itcoinblock_port = 0; try { itcoinblock_port = std::stoul(itcoinblock_bind_string.substr(colon_pos + 1), &consumed_chars); - } catch(std::invalid_argument const& e) { + } catch (std::invalid_argument const& e) { BOOST_LOG_TRIVIAL(error) << e.what(); consumed_chars = 0; - } catch(std::out_of_range const& e) { + } catch (std::out_of_range const& e) { BOOST_LOG_TRIVIAL(error) << e.what(); consumed_chars = 0; } - if ((consumed_chars == 0) || (consumed_chars < remaining_chars) || (itcoinblock_port > std::numeric_limits::max())) { - std::string msg = "cannot extract a meaningful TCP port from \"-zmqpubitcoinblock\" (" + itcoinblock_bind_string + ")"; + if ((consumed_chars == 0) || (consumed_chars < remaining_chars) || + (itcoinblock_port > std::numeric_limits::max())) { + std::string msg = "cannot extract a meaningful TCP port from \"-zmqpubitcoinblock\" (" + + itcoinblock_bind_string + ")"; BOOST_LOG_TRIVIAL(error) << msg; throw std::runtime_error(msg); } m_itcoinblock_connection_string = "tcp://" + itcoin_rpchost_ + ":" + std::to_string(itcoinblock_port); } - BOOST_LOG_TRIVIAL(debug) << "The value computed for connecting to the itcoinblock topic is " << m_itcoinblock_connection_string; + BOOST_LOG_TRIVIAL(debug) << "The value computed for connecting to the itcoinblock topic is " + << m_itcoinblock_connection_string; // Parse cookie file or rpcuser and pass if (gArgs.GetArg("-rpcpassword", "") == "") { - BOOST_LOG_TRIVIAL(info) << "No \"-rpcpassword\" parameter was given: falling back to cookie-based authentication"; + BOOST_LOG_TRIVIAL(info) + << "No \"-rpcpassword\" parameter was given: falling back to cookie-based authentication"; // Try fall back to cookie-based authentication if no password is provided // GetAuthCookieFile @@ -131,7 +146,8 @@ FbftConfig::FbftConfig(std::string datadir, std::string configFileName) BOOST_LOG_TRIVIAL(info) << "JSON-RPC auth data has been read from " + fs::PathToString(filepath); } else { itcoin_rpc_auth_ = gArgs.GetArg("-rpcuser", "") + ":" + gArgs.GetArg("-rpcpassword", ""); - BOOST_LOG_TRIVIAL(info) << "JSON-RPC auth data has been taken from command line parameters \"-rpcuser\" and \"-rpcpassword\""; + BOOST_LOG_TRIVIAL(info) + << "JSON-RPC auth data has been taken from command line parameters \"-rpcuser\" and \"-rpcpassword\""; } if ((itcoin_signet_challenge_ = gArgs.GetArg("-signetchallenge", "")) == "") { @@ -166,13 +182,13 @@ FbftConfig::FbftConfig(std::string datadir, std::string configFileName) BOOST_LOG_TRIVIAL(debug) << "This replica will not send its message to any sniffer."; } else { m_sniffer_dish_connection_string = config["sniffer_dish_connection_string"].asString(); - BOOST_LOG_TRIVIAL(warning) << "Messages from this replica will also be sent to " << m_sniffer_dish_connection_string.value(); + BOOST_LOG_TRIVIAL(warning) << "Messages from this replica will also be sent to " + << m_sniffer_dish_connection_string.value(); } // Read the replica config Json::Value replica_config_a = config["fbft_replica_set"]; - for ( unsigned int i = 0; i < replica_config_a.size(); ++i ) - { + for (unsigned int i = 0; i < replica_config_a.size(); ++i) { Json::Value replica_config_json = replica_config_a[i]; string host = replica_config_json["host"].asString(); string port = replica_config_json["port"].asString(); @@ -180,16 +196,15 @@ FbftConfig::FbftConfig(std::string datadir, std::string configFileName) string pubkey = replica_config_json["pubkey"].asString(); TransportConfig replica_config(i, host, port, p2pkh, pubkey); - BOOST_LOG_TRIVIAL(trace) << "Read replica #" << i << " - host: " << host << ", port: " << port << ", p2pkh: " << p2pkh; + BOOST_LOG_TRIVIAL(trace) << "Read replica #" << i << " - host: " << host << ", port: " << port + << ", p2pkh: " << p2pkh; replica_set_v_.push_back(replica_config); } m_cluster_size = replica_set_v_.size(); } -const unsigned int FbftConfig::cluster_size() const { - return m_cluster_size; -} +const unsigned int FbftConfig::cluster_size() const { return m_cluster_size; } std::string FbftConfig::getSignetChallenge() const { return this->itcoin_signet_challenge_; diff --git a/src/config/FbftConfig.h b/src/config/FbftConfig.h index ef9b5e7..ae94691 100644 --- a/src/config/FbftConfig.h +++ b/src/config/FbftConfig.h @@ -12,121 +12,115 @@ namespace itcoin { -class TransportConfig -{ - public: - TransportConfig(unsigned int id, std::string host, std::string port, std::string p2pkh, std::string pubkey): - id_(id), - host_(host), - port_(port), - p2pkh_(p2pkh), - pubkey_(pubkey) - {} - - const unsigned int id() const { return id_; } - const std::string host() const { return host_; } - const std::string port() const { return port_; } - const std::string p2pkh() const { return p2pkh_; } - const std::string pubkey() const { return pubkey_; } - - const std::string grpc_server_uri() const { return host_ + ":" + port_; } - - private: - unsigned int id_; - std::string host_; - std::string port_; - std::string p2pkh_; - std::string pubkey_; +class TransportConfig { +public: + TransportConfig(unsigned int id, std::string host, std::string port, std::string p2pkh, std::string pubkey) + : id_(id), host_(host), port_(port), p2pkh_(p2pkh), pubkey_(pubkey) {} + + const unsigned int id() const { return id_; } + const std::string host() const { return host_; } + const std::string port() const { return port_; } + const std::string p2pkh() const { return p2pkh_; } + const std::string pubkey() const { return pubkey_; } + + const std::string grpc_server_uri() const { return host_ + ":" + port_; } + +private: + unsigned int id_; + std::string host_; + std::string port_; + std::string p2pkh_; + std::string pubkey_; }; // class TransportConfig -class FbftConfig -{ - public: - FbftConfig(std::string datadir, std::string configFileName = "miner.conf.json"); - - const uint32_t id() const {return id_;} - const std::string genesis_block_hash() const {return m_genesis_block_hash;} - uint32_t genesis_block_timestamp() const {return m_genesis_block_timestamp;} - double target_block_time() const {return m_target_block_time;} - std::string group_public_key() const {return m_group_public_key;} - - // Timing constants - double C_REQUESTS_GENERATE_UNTIL_CURRENT_TIME_PLUS() const { return target_block_time(); } - double C_PRE_PREPARE_ACCEPT_UNTIL_CURRENT_TIME_PLUS() const { return target_block_time()/10; } - - // Setters - void set_replica_id(uint32_t replica_id){ id_ = replica_id; }; - void set_cluster_size(uint32_t cluster_size){ m_cluster_size = cluster_size; }; - void set_genesis_block_hash(std::string genesis_block_hash){m_genesis_block_hash = genesis_block_hash;} - void set_genesis_block_timestamp(uint32_t genesis_block_timestamp){m_genesis_block_timestamp = genesis_block_timestamp;} - void set_target_block_time(uint64_t target_block_time){m_target_block_time = target_block_time;} - void set_fbft_db_reset(bool reset){ m_fbft_db_reset=reset; } - void set_fbft_db_filename(std::string filename){ m_fbft_db_filename=filename; } - - // If set, zmq messages from this replica will also be sent to this dish - const std::optional sniffer_dish_connection_string() const { return m_sniffer_dish_connection_string; } - - const std::string bitcoindJsonRpcEndpoint() const { - return itcoin_rpchost_ + ":" + itcoin_rpcport_; - } - - const std::string itcoin_uri() const { - return "http://" + itcoin_rpc_auth_ + "@" + this->bitcoindJsonRpcEndpoint(); - } - - std::string getSignetChallenge() const; - - /** - * Connection string to the itcoinblock topic exposed by the itcoin-core - * process local to this replica. - * - * This value is computed from the bind string contained in the item - * zmqpubitcoinblock in bitcoind.conf. - * - * For reference, see the "-zmqpubitcoinblock" option in itcoin-core and the - * ZMQ_PUBITCOINBLOCK_PORT in the startup scripts initialize-itcoin-*.sh. - * - * See: - * http://api.zeromq.org/4-3:zmq-connect - * https://github.com/bancaditalia/itcoin-core/blob/itcoin/doc/zmq.md - * - * EXAMPLE: - * tcp://127.0.0.1:8080 - */ - std::string getItcoinblockConnectionString() const { return m_itcoinblock_connection_string; } - - const std::vector replica_set_v() const { return replica_set_v_; } - - const unsigned int cluster_size() const; - - std::string fbft_db_filename() const { return m_fbft_db_filename; } - bool fbft_db_reset() const { return m_fbft_db_reset; } - - private: - unsigned int id_; - uint32_t m_cluster_size; - std::string m_genesis_block_hash; - uint32_t m_genesis_block_timestamp; - double m_target_block_time; - std::string m_group_public_key; - - std::string itcoin_rpchost_; - std::string itcoin_rpcport_; - std::string itcoin_rpc_auth_; - std::string itcoin_signet_challenge_; - std::string m_itcoinblock_connection_string; - - std::vector replica_set_v_; - - // Fbft engine persistence - bool m_fbft_db_reset; - std::string m_fbft_db_filename; - - // If set, zmq messages from this replica will also be sent to this dish - std::optional m_sniffer_dish_connection_string; - +class FbftConfig { +public: + FbftConfig(std::string datadir, std::string configFileName = "miner.conf.json"); + + const uint32_t id() const { return id_; } + const std::string genesis_block_hash() const { return m_genesis_block_hash; } + uint32_t genesis_block_timestamp() const { return m_genesis_block_timestamp; } + double target_block_time() const { return m_target_block_time; } + std::string group_public_key() const { return m_group_public_key; } + + // Timing constants + double C_REQUESTS_GENERATE_UNTIL_CURRENT_TIME_PLUS() const { return target_block_time(); } + double C_PRE_PREPARE_ACCEPT_UNTIL_CURRENT_TIME_PLUS() const { return target_block_time() / 10; } + + // Setters + void set_replica_id(uint32_t replica_id) { id_ = replica_id; }; + void set_cluster_size(uint32_t cluster_size) { m_cluster_size = cluster_size; }; + void set_genesis_block_hash(std::string genesis_block_hash) { m_genesis_block_hash = genesis_block_hash; } + void set_genesis_block_timestamp(uint32_t genesis_block_timestamp) { + m_genesis_block_timestamp = genesis_block_timestamp; + } + void set_target_block_time(uint64_t target_block_time) { m_target_block_time = target_block_time; } + void set_fbft_db_reset(bool reset) { m_fbft_db_reset = reset; } + void set_fbft_db_filename(std::string filename) { m_fbft_db_filename = filename; } + + // If set, zmq messages from this replica will also be sent to this dish + const std::optional sniffer_dish_connection_string() const { + return m_sniffer_dish_connection_string; + } + + const std::string bitcoindJsonRpcEndpoint() const { return itcoin_rpchost_ + ":" + itcoin_rpcport_; } + + const std::string itcoin_uri() const { + return "http://" + itcoin_rpc_auth_ + "@" + this->bitcoindJsonRpcEndpoint(); + } + + std::string getSignetChallenge() const; + + /** + * Connection string to the itcoinblock topic exposed by the itcoin-core + * process local to this replica. + * + * This value is computed from the bind string contained in the item + * zmqpubitcoinblock in bitcoind.conf. + * + * For reference, see the "-zmqpubitcoinblock" option in itcoin-core and the + * ZMQ_PUBITCOINBLOCK_PORT in the startup scripts initialize-itcoin-*.sh. + * + * See: + * http://api.zeromq.org/4-3:zmq-connect + * https://github.com/bancaditalia/itcoin-core/blob/itcoin/doc/zmq.md + * + * EXAMPLE: + * tcp://127.0.0.1:8080 + */ + std::string getItcoinblockConnectionString() const { return m_itcoinblock_connection_string; } + + const std::vector replica_set_v() const { return replica_set_v_; } + + const unsigned int cluster_size() const; + + std::string fbft_db_filename() const { return m_fbft_db_filename; } + bool fbft_db_reset() const { return m_fbft_db_reset; } + +private: + unsigned int id_; + uint32_t m_cluster_size; + std::string m_genesis_block_hash; + uint32_t m_genesis_block_timestamp; + double m_target_block_time; + std::string m_group_public_key; + + std::string itcoin_rpchost_; + std::string itcoin_rpcport_; + std::string itcoin_rpc_auth_; + std::string itcoin_signet_challenge_; + std::string m_itcoinblock_connection_string; + + std::vector replica_set_v_; + + // Fbft engine persistence + bool m_fbft_db_reset; + std::string m_fbft_db_filename; + + // If set, zmq messages from this replica will also be sent to this dish + std::optional m_sniffer_dish_connection_string; }; } // namespace itcoin -#endif //FBFT_CONFIG_H_ +#endif // FBFT_CONFIG_H_ diff --git a/src/fbft/Replica2.cpp b/src/fbft/Replica2.cpp index f2ef6e1..c19324f 100644 --- a/src/fbft/Replica2.cpp +++ b/src/fbft/Replica2.cpp @@ -3,9 +3,9 @@ #include "Replica2.h" -#include #include #include +#include using namespace std; using namespace itcoin::blockchain; @@ -16,29 +16,17 @@ using namespace itcoin::fbft::messages; namespace itcoin { namespace fbft { -Replica2::Replica2( - const itcoin::FbftConfig& config, - Blockchain& blockchain, - RoastWallet& wallet, - NetworkTransport& transport, - uint32_t start_height, - std::string start_hash, - uint32_t start_time -): -ReplicaState(config, blockchain, wallet, start_height, start_hash, start_time), -m_transport(transport) -{ +Replica2::Replica2(const itcoin::FbftConfig& config, Blockchain& blockchain, RoastWallet& wallet, + NetworkTransport& transport, uint32_t start_height, std::string start_hash, + uint32_t start_time) + : ReplicaState(config, blockchain, wallet, start_height, start_hash, start_time), m_transport(transport) { // use current time as seed for random generator std::srand(std::time(nullptr)); } -const uint32_t Replica2::id() const -{ - return m_conf.id(); -} +const uint32_t Replica2::id() const { return m_conf.id(); } -void Replica2::GenerateRequests() -{ +void Replica2::GenerateRequests() { // Constants uint32_t genesis_block_time = m_conf.genesis_block_timestamp(); uint32_t target_block_time = m_conf.target_block_time(); @@ -52,102 +40,79 @@ void Replica2::GenerateRequests() // This number may need to become adaptive uint32_t MAX_NUM_GENERATED_REQUESTS = 5; - while( - last_req_time < current_time + MAX_NUM_GENERATED_REQUESTS*target_block_time && - last_req_time < last_rep_time + MAX_NUM_GENERATED_REQUESTS*target_block_time - ) - { + while (last_req_time < current_time + MAX_NUM_GENERATED_REQUESTS * target_block_time && + last_req_time < last_rep_time + MAX_NUM_GENERATED_REQUESTS * target_block_time) { uint32_t req_timestamp = last_req_time + target_block_time; BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% last_req_time=%2% < current_time + delta = %3% and < last_rep_time + delta = %4%, creating request with H=%5% and T=%6%.") - % m_conf.id() - % last_req_time - % (current_time + MAX_NUM_GENERATED_REQUESTS*target_block_time) - % (last_rep_time + MAX_NUM_GENERATED_REQUESTS*target_block_time) - % ((req_timestamp-genesis_block_time) / target_block_time) - % req_timestamp - ); + boost::format("R%1% last_req_time=%2% < current_time + delta = %3% and < last_rep_time + delta = " + "%4%, creating request with H=%5% and T=%6%.") % + m_conf.id() % last_req_time % (current_time + MAX_NUM_GENERATED_REQUESTS * target_block_time) % + (last_rep_time + MAX_NUM_GENERATED_REQUESTS * target_block_time) % + ((req_timestamp - genesis_block_time) / target_block_time) % req_timestamp); messages::Request req = messages::Request(genesis_block_time, target_block_time, req_timestamp); actions::ReceiveRequest receive_req(m_conf.id(), req); this->Apply(receive_req); last_req_time = this->latest_request_time(); } - if (last_req_time >= current_time + MAX_NUM_GENERATED_REQUESTS*target_block_time) - { + if (last_req_time >= current_time + MAX_NUM_GENERATED_REQUESTS * target_block_time) { BOOST_LOG_TRIVIAL(trace) << str( - boost::format("R%1% last_req_time=%2% >= current_time + delta = %3%, stop creating requests.") - % m_conf.id() - % last_req_time - % (current_time + MAX_NUM_GENERATED_REQUESTS*target_block_time) - ); - } - else - { + boost::format("R%1% last_req_time=%2% >= current_time + delta = %3%, stop creating requests.") % + m_conf.id() % last_req_time % (current_time + MAX_NUM_GENERATED_REQUESTS * target_block_time)); + } else { BOOST_LOG_TRIVIAL(trace) << str( - boost::format("R%1% last_req_time=%2% >= last_rep_time + delta = %3%, stop creating requests.") - % m_conf.id() - % last_req_time - % (last_rep_time + MAX_NUM_GENERATED_REQUESTS*target_block_time) - ); + boost::format("R%1% last_req_time=%2% >= last_rep_time + delta = %3%, stop creating requests.") % + m_conf.id() % last_req_time % (last_rep_time + MAX_NUM_GENERATED_REQUESTS * target_block_time)); } } -void Replica2::ApplyActiveActions() -{ +void Replica2::ApplyActiveActions() { // We execute an active action - uint32_t num_applied_actions = 0; uint32_t MAX_NUM_APPLIED_ACTIONS = 11; - while (!m_active_actions.empty() && num_applied_actions action_to_apply= move(m_active_actions.at(index_random)); - this->Apply( *action_to_apply ); + std::unique_ptr action_to_apply = move(m_active_actions.at(index_random)); + this->Apply(*action_to_apply); num_applied_actions += 1; // We broadcast all messages in the output buffer - if (!m_out_msg_buffer.empty()) - { + if (!m_out_msg_buffer.empty()) { std::vector> ready_to_be_sent{}; - for (auto& p_msg: m_out_msg_buffer) - { + for (auto& p_msg : m_out_msg_buffer) { // i-th element in out_msg_buffer is nullptr after move, but still present ready_to_be_sent.emplace_back(move(p_msg)); } this->ClearOutMessageBuffer(); - for (auto& p_msg: ready_to_be_sent) - { + for (auto& p_msg : ready_to_be_sent) { p_msg->Sign(m_wallet); // A special trick needs to be applied for ROAST_PRE_SIGNATURE message // This message is sent by the ROAST coordinator to all the candidate signers of the signature session // In 5FBFT the Primary may be both the ROAST coordinator and signer for that specific session // In that special case, we need to inject the message in the input buffer of the coordinator - if (p_msg->type()==MSG_TYPE::ROAST_PRE_SIGNATURE) - { - unique_ptr typed_msg = make_unique( dynamic_cast(*p_msg) ); + if (p_msg->type() == MSG_TYPE::ROAST_PRE_SIGNATURE) { + unique_ptr typed_msg = + make_unique(dynamic_cast(*p_msg)); bool replica_id_found = false; - for (uint32_t signer_id : typed_msg->signers()) - { - if (signer_id == m_conf.id()) - { + for (uint32_t signer_id : typed_msg->signers()) { + if (signer_id == m_conf.id()) { replica_id_found = true; break; } } - if (replica_id_found) - { + if (replica_id_found) { this->m_in_msg_buffer.emplace_back(std::move(typed_msg)); } - } - else if (p_msg->type()==MSG_TYPE::ROAST_SIGNATURE_SHARE) - { + } else if (p_msg->type() == MSG_TYPE::ROAST_SIGNATURE_SHARE) { // Similarly, the ROAST_SIGNATURE_SHARE should be sent to the coordinator only // Here we ship the signature share also to current replica, in case it's the coordinator - unique_ptr typed_msg = make_unique( dynamic_cast(*p_msg) ); + unique_ptr typed_msg = make_unique( + dynamic_cast(*p_msg)); this->m_in_msg_buffer.emplace_back(std::move(typed_msg)); } @@ -156,27 +121,17 @@ void Replica2::ApplyActiveActions() } } } - if (num_applied_actions == MAX_NUM_APPLIED_ACTIONS) - { - string error_msg = str( - boost::format("R%1% exceeded the number of applied actions!") - % id() - ); + if (num_applied_actions == MAX_NUM_APPLIED_ACTIONS) { + string error_msg = str(boost::format("R%1% exceeded the number of applied actions!") % id()); // throw(std::runtime_error(error_msg)); BOOST_LOG_TRIVIAL(error) << error_msg; } - BOOST_LOG_TRIVIAL(trace) << str( - boost::format("R%1% does not have further active actions to apply.") - % m_conf.id() - ); + BOOST_LOG_TRIVIAL(trace) << str(boost::format("R%1% does not have further active actions to apply.") % + m_conf.id()); } -void Replica2::CheckTimedActions() -{ - BOOST_LOG_TRIVIAL(trace) << str( - boost::format("R%1% cycle start.") - % m_conf.id() - ); +void Replica2::CheckTimedActions() { + BOOST_LOG_TRIVIAL(trace) << str(boost::format("R%1% cycle start.") % m_conf.id()); // Generate requests this->GenerateRequests(); @@ -188,29 +143,20 @@ void Replica2::CheckTimedActions() // Apply active actions resulting from timeout expired this->ApplyActiveActions(); - BOOST_LOG_TRIVIAL(trace) << str( - boost::format("R%1% cycle end.") - % m_conf.id() - ); + BOOST_LOG_TRIVIAL(trace) << str(boost::format("R%1% cycle end.") % m_conf.id()); } -void Replica2::ReceiveIncomingMessage(std::unique_ptr msg) -{ - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% receiving %2% from %3%.") - % m_conf.id() - % msg->identify() - % msg->sender_id() - ); +void Replica2::ReceiveIncomingMessage(std::unique_ptr msg) { + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% receiving %2% from %3%.") % m_conf.id() % + msg->identify() % msg->sender_id()); // Generate requests this->GenerateRequests(); - if( msg->type()==messages::MSG_TYPE::BLOCK ) - { + if (msg->type() == messages::MSG_TYPE::BLOCK) { // Checkpoint messages are not signed, since they are received upon // receipt of a valid (hence signed) block. - messages::Block typed_msg{ dynamic_cast(*msg) }; + messages::Block typed_msg{dynamic_cast(*msg)}; actions::ReceiveBlock receive_block(m_conf.id(), typed_msg); this->Apply(receive_block); @@ -218,27 +164,18 @@ void Replica2::ReceiveIncomingMessage(std::unique_ptr msg) // to trigger view changes } // Here the message is not a block, we check signature - else if ( msg->VerifySignatures(m_wallet) ) - { + else if (msg->VerifySignatures(m_wallet)) { ReplicaState::ReceiveIncomingMessage(move(msg)); // Apply active actions resulting from the received, non-block message this->ApplyActiveActions(); - } - else - { + } else { BOOST_LOG_TRIVIAL(error) << str( - boost::format("R%1% received message %2% from R%3% with invalid signature, discarding.") - % m_conf.id() - % msg->name() - % msg->sender_id() - ); + boost::format("R%1% received message %2% from R%3% with invalid signature, discarding.") % + m_conf.id() % msg->name() % msg->sender_id()); } - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% receive message end.") - % m_conf.id() - ); + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% receive message end.") % m_conf.id()); } -} -} +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/Replica2.h b/src/fbft/Replica2.h index 5255e82..d92ac75 100644 --- a/src/fbft/Replica2.h +++ b/src/fbft/Replica2.h @@ -18,34 +18,27 @@ namespace state = itcoin::fbft::state; namespace itcoin { namespace fbft { -class Replica2: public network::NetworkListener, public state::ReplicaState -{ - public: - Replica2( - const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, - wallet::RoastWallet& wallet, - network::NetworkTransport& transport, - uint32_t start_height, - std::string start_hash, - uint32_t start_time - ); - - // Getters - const uint32_t id() const; - - // Operations - void ReceiveIncomingMessage(std::unique_ptr msg); - void CheckTimedActions(); - - private: - network::NetworkTransport& m_transport; - - void GenerateRequests(); - void ApplyActiveActions(); +class Replica2 : public network::NetworkListener, public state::ReplicaState { +public: + Replica2(const itcoin::FbftConfig& config, blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet, + network::NetworkTransport& transport, uint32_t start_height, std::string start_hash, + uint32_t start_time); + + // Getters + const uint32_t id() const; + + // Operations + void ReceiveIncomingMessage(std::unique_ptr msg); + void CheckTimedActions(); + +private: + network::NetworkTransport& m_transport; + + void GenerateRequests(); + void ApplyActiveActions(); }; -} -} +} // namespace fbft +} // namespace itcoin #endif // ITCOIN_FBFT_REPLICA_2_H diff --git a/src/fbft/actions/Action.cpp b/src/fbft/actions/Action.cpp index 6b59de3..8306bcb 100644 --- a/src/fbft/actions/Action.cpp +++ b/src/fbft/actions/Action.cpp @@ -9,34 +9,23 @@ namespace itcoin { namespace fbft { namespace actions { -Action::Action(uint32_t replica_id): m_replica_id(replica_id) -{ +Action::Action(uint32_t replica_id) : m_replica_id(replica_id) {} -} - -Action::Action(PlTerm Replica_id): m_replica_id((long) Replica_id) -{ - -} +Action::Action(PlTerm Replica_id) : m_replica_id((long)Replica_id) {} -std::string Action::name() const -{ - return ACTION_TYPE_TYPE_AS_STRING[static_cast(this->type())]; -} +std::string Action::name() const { return ACTION_TYPE_TYPE_AS_STRING[static_cast(this->type())]; } -std::optional> Action::message() const -{ +std::optional> Action::message() const { return std::nullopt; } -std::ostream& operator<<(std::ostream& Str, const Action& action) -{ +std::ostream& operator<<(std::ostream& Str, const Action& action) { // print something from v to str, e.g: Str << v.getX(); string action_str = action.identify(); Str << action_str; return Str; } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/Execute.cpp b/src/fbft/actions/Execute.cpp index d5b34a6..a93301f 100644 --- a/src/fbft/actions/Execute.cpp +++ b/src/fbft/actions/Execute.cpp @@ -3,9 +3,9 @@ #include "actions.h" +#include #include #include -#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -20,33 +20,25 @@ namespace itcoin { namespace fbft { namespace actions { -Execute::Execute( - Blockchain& blockchain, RoastWallet& wallet, - PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N): -Action(Replica_id), -m_blockchain(blockchain), -m_wallet(wallet) -{ - m_view = (long) V; - m_seq_number = (long) N; +Execute::Execute(Blockchain& blockchain, RoastWallet& wallet, PlTerm Replica_id, PlTerm Req_digest, PlTerm V, + PlTerm N) + : Action(Replica_id), m_blockchain(blockchain), m_wallet(wallet) { + m_view = (long)V; + m_seq_number = (long)N; // Retrieve payload from the msg store - std::string req_digest = (char*) Req_digest; + std::string req_digest = (char*)Req_digest; Request r = Request::FindByDigest(m_replica_id, req_digest); m_request = r; } -std::vector> Execute::BuildActives( - const itcoin::FbftConfig& config, Blockchain& blockchain, - RoastWallet& wallet -) -{ +std::vector> +Execute::BuildActives(const itcoin::FbftConfig& config, Blockchain& blockchain, RoastWallet& wallet) { std::vector> results{}; - PlTerm Req_digest, V, N, Replica_id{(long) config.id()}; + PlTerm Req_digest, V, N, Replica_id{(long)config.id()}; PlQuery query("pre_EXECUTE", PlTermv(Req_digest, V, N, Replica_id)); - while ( query.next_solution() ) - { + while (query.next_solution()) { actions::Execute action{blockchain, wallet, Replica_id, Req_digest, V, N}; std::unique_ptr p_action = std::make_unique(action); results.emplace_back(move(p_action)); @@ -54,8 +46,7 @@ std::vector> Execute::BuildActives( return results; } -int Execute::effect() const -{ +int Execute::effect() const { std::vector signers; std::vector signatures; @@ -63,36 +54,30 @@ int Execute::effect() const string pre_signature; // We need to find out the block to signatures - PlTerm Replica_id{(long) m_replica_id}, Session_id, Signers, Pre_signature, Signature_shares; - PlQuery query{"roast_final_signature_session", PlTermv(Replica_id, Session_id, Signers, Pre_signature, Signature_shares)}; - while ( query.next_solution() ) - { - PlTail SignersTail{Signers}; PlTerm SignerElem; - while(SignersTail.next(SignerElem)) - { - signers.emplace_back((long) SignerElem); + PlTerm Replica_id{(long)m_replica_id}, Session_id, Signers, Pre_signature, Signature_shares; + PlQuery query{"roast_final_signature_session", + PlTermv(Replica_id, Session_id, Signers, Pre_signature, Signature_shares)}; + while (query.next_solution()) { + PlTail SignersTail{Signers}; + PlTerm SignerElem; + while (SignersTail.next(SignerElem)) { + signers.emplace_back((long)SignerElem); } - PlTail SigShareTail{Signature_shares}; PlTerm SigShareElem; - while(SigShareTail.next(SigShareElem)) - { - string sig_share = (const char *) SigShareElem; + PlTail SigShareTail{Signature_shares}; + PlTerm SigShareElem; + while (SigShareTail.next(SigShareElem)) { + string sig_share = (const char*)SigShareElem; signatures.emplace_back(sig_share); } - pre_signature = (const char *) Pre_signature; + pre_signature = (const char*)Pre_signature; } - BOOST_LOG_TRIVIAL(trace) << str( - boost::format( "%1% effect(), Aggregating the following signatures:" ) - % this->identify() - ); - for (int i=0; iidentify()); + for (int i = 0; i < signers.size(); i++) // access by reference to avoid copying { - BOOST_LOG_TRIVIAL(trace) << str( - boost::format( "%1% effect(), signature from R%2% = %3%" ) - % this->identify() - % signers.at(i) - % signatures.at(i) - ); + BOOST_LOG_TRIVIAL(trace) << str(boost::format("%1% effect(), signature from R%2% = %3%") % + this->identify() % signers.at(i) % signatures.at(i)); } // Retrieve thre proposed block @@ -104,53 +89,32 @@ int Execute::effect() const RoastWallet& wallet = dynamic_cast(m_wallet); final_block = wallet.FinalizeBlock(proposed_block, pre_signature, signatures); - if(final_block.GetHash() != proposed_block.GetHash()) - { + if (final_block.GetHash() != proposed_block.GetHash()) { BOOST_LOG_TRIVIAL(error) << "The executed block has mismatching hash, and will be ignored."; return 0; } - BOOST_LOG_TRIVIAL(trace) << str( - boost::format( "%1% effect(), Proposed/Final block hash = %2%>" ) - % this->identify() - % final_block.GetHash().GetHex() - ); + BOOST_LOG_TRIVIAL(trace) << str(boost::format("%1% effect(), Proposed/Final block hash = %2%>") % + this->identify() % final_block.GetHash().GetHex()); - BOOST_LOG_TRIVIAL(trace) << str( - boost::format( "%1% effect(), Proposed block = %2%>" ) - % this->identify() - % HexSerializableCBlock(proposed_block).GetHex() - ); + BOOST_LOG_TRIVIAL(trace) << str(boost::format("%1% effect(), Proposed block = %2%>") % this->identify() % + HexSerializableCBlock(proposed_block).GetHex()); - BOOST_LOG_TRIVIAL(trace) << str( - boost::format( "%1% effect(), Final block = %2%>" ) - % this->identify() - % HexSerializableCBlock(final_block).GetHex() - ); + BOOST_LOG_TRIVIAL(trace) << str(boost::format("%1% effect(), Final block = %2%>") % this->identify() % + HexSerializableCBlock(final_block).GetHex()); m_blockchain.SubmitBlock(m_seq_number, final_block); - PlTermv args( - PlString((const char*) m_request.digest().c_str()), - PlTerm((long) m_seq_number), - PlString((const char*) proposed_block.GetHash().GetHex().c_str()), - PlTerm((long) m_replica_id) - ); + PlTermv args(PlString((const char*)m_request.digest().c_str()), PlTerm((long)m_seq_number), + PlString((const char*)proposed_block.GetHash().GetHex().c_str()), PlTerm((long)m_replica_id)); return PlCall("effect_EXECUTE", args); } -std::string Execute::identify() const -{ - return str( - boost::format( "<%1%, Request=%2%, V=%3%, N=%4%, R=%5%>" ) - % name() - % m_request.digest() - % m_view - % m_seq_number - % m_replica_id - ); +std::string Execute::identify() const { + return str(boost::format("<%1%, Request=%2%, V=%3%, N=%4%, R=%5%>") % name() % m_request.digest() % m_view % + m_seq_number % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/ProcessNewView.cpp b/src/fbft/actions/ProcessNewView.cpp index e11aee3..e67e63f 100644 --- a/src/fbft/actions/ProcessNewView.cpp +++ b/src/fbft/actions/ProcessNewView.cpp @@ -3,8 +3,8 @@ #include "actions.h" -#include #include +#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -19,55 +19,36 @@ namespace itcoin { namespace fbft { namespace actions { -ProcessNewView::ProcessNewView(PlTerm Replica_id, PlTerm Hi, PlTerm Nu, PlTerm Chi) -:Action(Replica_id) -{ - m_hi = (long) Hi; +ProcessNewView::ProcessNewView(PlTerm Replica_id, PlTerm Hi, PlTerm Nu, PlTerm Chi) : Action(Replica_id) { + m_hi = (long)Hi; m_nu = NewView::nu_from_plterm(Nu); m_chi = NewView::chi_from_plterm(Chi); }; -std::vector> ProcessNewView::BuildActives( - const itcoin::FbftConfig& config, - Blockchain& blockchain, - RoastWallet& wallet -) -{ +std::vector> +ProcessNewView::BuildActives(const itcoin::FbftConfig& config, Blockchain& blockchain, RoastWallet& wallet) { std::vector> results{}; - PlTerm Hi, Nu, Chi, Replica_id{(long) config.id()}; + PlTerm Hi, Nu, Chi, Replica_id{(long)config.id()}; PlQuery query("pre_PROCESS_NEW_VIEW", PlTermv(Hi, Nu, Chi, Replica_id)); - while ( query.next_solution() ) - { + while (query.next_solution()) { unique_ptr action = - std::make_unique(Replica_id, Hi, Nu, Chi); + std::make_unique(Replica_id, Hi, Nu, Chi); results.emplace_back(std::move(action)); } return results; } -int ProcessNewView::effect() const -{ - PlTermv args( - PlTerm((long) m_hi), - NewView::chi_as_plterm(m_chi), - PlTerm((long) m_replica_id) - ); +int ProcessNewView::effect() const { + PlTermv args(PlTerm((long)m_hi), NewView::chi_as_plterm(m_chi), PlTerm((long)m_replica_id)); return PlCall("effect_PROCESS_NEW_VIEW", args); } -std::string ProcessNewView::identify() const -{ - return str( - boost::format( "<%1%, Hi=%2%, Nu=%3%, Chi=%4%, R=%5%>" ) - % name() - % m_hi - % "m_nu" - % "m_chi" - % m_replica_id - ); +std::string ProcessNewView::identify() const { + return str(boost::format("<%1%, Hi=%2%, Nu=%3%, Chi=%4%, R=%5%>") % name() % m_hi % "m_nu" % "m_chi" % + m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/ReceiveBlock.cpp b/src/fbft/actions/ReceiveBlock.cpp index d406b82..7ebc680 100644 --- a/src/fbft/actions/ReceiveBlock.cpp +++ b/src/fbft/actions/ReceiveBlock.cpp @@ -3,34 +3,23 @@ #include "actions.h" -#include #include +#include namespace itcoin { namespace fbft { namespace actions { -int ReceiveBlock::effect() const -{ - PlTermv args( - PlTerm((long) m_replica_id), - PlTerm((long) m_msg.block_height()), - PlTerm((long) m_msg.block_time()), - PlString((const char*) m_msg.block_hash().c_str()) - ); +int ReceiveBlock::effect() const { + PlTermv args(PlTerm((long)m_replica_id), PlTerm((long)m_msg.block_height()), + PlTerm((long)m_msg.block_time()), PlString((const char*)m_msg.block_hash().c_str())); return PlCall("effect_RECEIVE_BLOCK", args); } -std::string ReceiveBlock::identify() const -{ - return str( - boost::format( "<%1%, H=%2%, R=%3%>" ) - % name() - % m_msg.block_height() - % m_replica_id - ); +std::string ReceiveBlock::identify() const { + return str(boost::format("<%1%, H=%2%, R=%3%>") % name() % m_msg.block_height() % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/ReceiveCommit.cpp b/src/fbft/actions/ReceiveCommit.cpp index 8ae917a..ec2cce2 100644 --- a/src/fbft/actions/ReceiveCommit.cpp +++ b/src/fbft/actions/ReceiveCommit.cpp @@ -3,39 +3,26 @@ #include "actions.h" -#include #include +#include namespace itcoin { namespace fbft { namespace actions { -int ReceiveCommit::effect() const -{ - PlTermv args( - PlTerm((long) m_msg.view()), - PlTerm((long) m_msg.seq_number()), - PlString((const char*) m_msg.pre_signature().c_str()), - PlTerm((long) m_msg.sender_id()), - PlString((const char*) m_msg.signature().c_str()), - PlTerm((long) m_replica_id) - ); +int ReceiveCommit::effect() const { + PlTermv args(PlTerm((long)m_msg.view()), PlTerm((long)m_msg.seq_number()), + PlString((const char*)m_msg.pre_signature().c_str()), PlTerm((long)m_msg.sender_id()), + PlString((const char*)m_msg.signature().c_str()), PlTerm((long)m_replica_id)); return PlCall("effect_RECEIVE_COMMIT", args); } -std::string ReceiveCommit::identify() const -{ - return str( - boost::format( "<%1%, V=%2%, N=%3%, Data=%4% R=%5%>" ) - % name() - % m_msg.view() - % m_msg.seq_number() - % m_msg.pre_signature().substr(0,5) - % m_replica_id - ); +std::string ReceiveCommit::identify() const { + return str(boost::format("<%1%, V=%2%, N=%3%, Data=%4% R=%5%>") % name() % m_msg.view() % + m_msg.seq_number() % m_msg.pre_signature().substr(0, 5) % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/ReceiveNewView.cpp b/src/fbft/actions/ReceiveNewView.cpp index 6da6593..ae007f4 100644 --- a/src/fbft/actions/ReceiveNewView.cpp +++ b/src/fbft/actions/ReceiveNewView.cpp @@ -3,9 +3,9 @@ #include "actions.h" +#include #include #include -#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -19,39 +19,23 @@ namespace itcoin { namespace fbft { namespace actions { -ReceiveNewView::ReceiveNewView(RoastWallet& wallet, uint32_t replica_id, messages::NewView msg): -Action(replica_id), -m_wallet(wallet), -m_msg(msg) -{ -}; - -int ReceiveNewView::effect() const -{ - - PlTermv args( - PlTerm((long) m_msg.view()), - NewView::nu_as_plterm(m_msg.nu()), - NewView::chi_as_plterm(m_msg.chi()), - PlTerm((long) m_msg.sender_id()), - PlString((const char*) m_msg.signature().c_str()), - PlTerm((long) m_replica_id) - ); +ReceiveNewView::ReceiveNewView(RoastWallet& wallet, uint32_t replica_id, messages::NewView msg) + : Action(replica_id), m_wallet(wallet), m_msg(msg){}; + +int ReceiveNewView::effect() const { + + PlTermv args(PlTerm((long)m_msg.view()), NewView::nu_as_plterm(m_msg.nu()), + NewView::chi_as_plterm(m_msg.chi()), PlTerm((long)m_msg.sender_id()), + PlString((const char*)m_msg.signature().c_str()), PlTerm((long)m_replica_id)); return PlCall("effect_RECEIVE_NEW_VIEW", args); } -std::string ReceiveNewView::identify() const -{ - return str( - boost::format( "<%1%, V=%2%, Sender=%3%, R=%4%>" ) - % name() - % m_msg.view() - % m_msg.sender_id() - % m_replica_id - ); +std::string ReceiveNewView::identify() const { + return str(boost::format("<%1%, V=%2%, Sender=%3%, R=%4%>") % name() % m_msg.view() % m_msg.sender_id() % + m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/ReceivePrePrepare.cpp b/src/fbft/actions/ReceivePrePrepare.cpp index 8ac07c4..82ddb3a 100644 --- a/src/fbft/actions/ReceivePrePrepare.cpp +++ b/src/fbft/actions/ReceivePrePrepare.cpp @@ -3,9 +3,9 @@ #include "actions.h" +#include #include #include -#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -20,82 +20,60 @@ namespace itcoin { namespace fbft { namespace actions { -ReceivePrePrepare::ReceivePrePrepare(uint32_t replica_id, Blockchain& blockchain, - double current_time, double pre_prepare_time_tolerance_delta, - PrePrepare msg) -: -Action(replica_id), -m_current_time(current_time), -m_pre_prepare_time_tolerance_delta(pre_prepare_time_tolerance_delta), -m_blockchain(blockchain), -m_msg(msg) -{ +ReceivePrePrepare::ReceivePrePrepare(uint32_t replica_id, Blockchain& blockchain, double current_time, + double pre_prepare_time_tolerance_delta, PrePrepare msg) + : Action(replica_id), m_current_time(current_time), + m_pre_prepare_time_tolerance_delta(pre_prepare_time_tolerance_delta), m_blockchain(blockchain), + m_msg(msg){ -}; + }; -int ReceivePrePrepare::effect() const -{ +int ReceivePrePrepare::effect() const { /* * Here we check that the block proposed by the primary is valid. We exclude * the signet solution from the check (hence the third parameter set to * "false"). */ - if(!m_blockchain.TestBlockValidity(m_msg.seq_number(), m_msg.proposed_block(), false)) - { + if (!m_blockchain.TestBlockValidity(m_msg.seq_number(), m_msg.proposed_block(), false)) { BOOST_LOG_TRIVIAL(error) << "A received PRE_PREPARE contains an invalid block, and will be ignored!"; return 0; } // Check that the block has the expected timestamp messages::Request req; - if (!messages::Request::TryFindByDigest(m_replica_id, m_msg.req_digest(), req)) - { + if (!messages::Request::TryFindByDigest(m_replica_id, m_msg.req_digest(), req)) { BOOST_LOG_TRIVIAL(error) << "A received PRE_PREPARE references an unknown request, and will be ignored."; return 0; } - if (!m_msg.proposed_block().nTime == req.timestamp()) - { - BOOST_LOG_TRIVIAL(error) << "A received PRE_PREPARE has mismatching block and request timestamp, and will be ignored."; + if (!m_msg.proposed_block().nTime == req.timestamp()) { + BOOST_LOG_TRIVIAL(error) + << "A received PRE_PREPARE has mismatching block and request timestamp, and will be ignored."; return 0; } - if (req.timestamp() > m_current_time + m_pre_prepare_time_tolerance_delta) - { + if (req.timestamp() > m_current_time + m_pre_prepare_time_tolerance_delta) { string error_msg = str( - boost::format("R%1% PRE_PREPARE received for a future request (request time = %2%) has been received too early (current time = %3%, max timestamp accepted = %4%), and will be ignored.") - % m_replica_id - % req.timestamp() - % m_current_time - % (m_current_time + m_pre_prepare_time_tolerance_delta) - ); + boost::format("R%1% PRE_PREPARE received for a future request (request time = %2%) has been received " + "too early (current time = %3%, max timestamp accepted = %4%), and will be ignored.") % + m_replica_id % req.timestamp() % m_current_time % + (m_current_time + m_pre_prepare_time_tolerance_delta)); BOOST_LOG_TRIVIAL(error) << error_msg; return 0; } - PlTermv args( - PlTerm((long) m_msg.view()), - PlTerm((long) m_msg.seq_number()), - PlString((const char*) m_msg.req_digest().c_str()), - PlString((const char*) m_msg.proposed_block_hex().c_str() ), - PlTerm((long) m_msg.sender_id()), - PlString((const char*) m_msg.signature().c_str()), - PlTerm((long) m_replica_id) - ); + PlTermv args(PlTerm((long)m_msg.view()), PlTerm((long)m_msg.seq_number()), + PlString((const char*)m_msg.req_digest().c_str()), + PlString((const char*)m_msg.proposed_block_hex().c_str()), PlTerm((long)m_msg.sender_id()), + PlString((const char*)m_msg.signature().c_str()), PlTerm((long)m_replica_id)); return PlCall("effect_RECEIVE_PRE_PREPARE", args); } -std::string ReceivePrePrepare::identify() const -{ - return str( - boost::format( "<%1%, V=%2%, N=%3%, R=%4%>" ) - % name() - % m_msg.view() - % m_msg.seq_number() - % m_replica_id - ); +std::string ReceivePrePrepare::identify() const { + return str(boost::format("<%1%, V=%2%, N=%3%, R=%4%>") % name() % m_msg.view() % m_msg.seq_number() % + m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/ReceivePrepare.cpp b/src/fbft/actions/ReceivePrepare.cpp index 2ea7060..e4b036e 100644 --- a/src/fbft/actions/ReceivePrepare.cpp +++ b/src/fbft/actions/ReceivePrepare.cpp @@ -3,36 +3,25 @@ #include "actions.h" -#include #include +#include namespace itcoin { namespace fbft { namespace actions { -int ReceivePrepare::effect() const -{ - PlTermv args( - PlTerm((long) m_msg.view()), - PlTerm((long) m_msg.seq_number()), - PlString((const char*) m_msg.req_digest().c_str()), - PlTerm((long) m_msg.sender_id()), - PlString((const char*) m_msg.signature().c_str()), - PlTerm((long) m_replica_id) - ); +int ReceivePrepare::effect() const { + PlTermv args(PlTerm((long)m_msg.view()), PlTerm((long)m_msg.seq_number()), + PlString((const char*)m_msg.req_digest().c_str()), PlTerm((long)m_msg.sender_id()), + PlString((const char*)m_msg.signature().c_str()), PlTerm((long)m_replica_id)); return PlCall("effect_RECEIVE_PREPARE", args); } -std::string ReceivePrepare::identify() const -{ - return str( - boost::format( "<%1%, R=%2%>" ) - % name() - % m_replica_id - ); +std::string ReceivePrepare::identify() const { + return str(boost::format("<%1%, R=%2%>") % name() % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/ReceiveRequest.cpp b/src/fbft/actions/ReceiveRequest.cpp index 8d85611..037090a 100644 --- a/src/fbft/actions/ReceiveRequest.cpp +++ b/src/fbft/actions/ReceiveRequest.cpp @@ -3,37 +3,27 @@ #include "actions.h" -#include #include +#include -namespace messages=itcoin::fbft::messages; +namespace messages = itcoin::fbft::messages; namespace itcoin { namespace fbft { namespace actions { -int ReceiveRequest::effect() const -{ - PlTermv args( - PlString((const char*) m_msg.digest().c_str()), - PlTerm((long) m_msg.timestamp()), - PlTerm((long) m_replica_id) - ); +int ReceiveRequest::effect() const { + PlTermv args(PlString((const char*)m_msg.digest().c_str()), PlTerm((long)m_msg.timestamp()), + PlTerm((long)m_replica_id)); return PlCall("effect_RECEIVE_REQUEST", args); } -std::string ReceiveRequest::identify() const -{ - return str( - boost::format( "<%1%, T=%2%, H=%3%, R=%4%>" ) - % name() - % m_msg.timestamp() - % m_msg.height() - % m_replica_id - ); +std::string ReceiveRequest::identify() const { + return str(boost::format("<%1%, T=%2%, H=%3%, R=%4%>") % name() % m_msg.timestamp() % m_msg.height() % + m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/ReceiveViewChange.cpp b/src/fbft/actions/ReceiveViewChange.cpp index dc70bf5..9273ebf 100644 --- a/src/fbft/actions/ReceiveViewChange.cpp +++ b/src/fbft/actions/ReceiveViewChange.cpp @@ -3,44 +3,30 @@ #include "actions.h" -#include #include +#include using namespace std; -namespace messages=itcoin::fbft::messages; +namespace messages = itcoin::fbft::messages; namespace itcoin { namespace fbft { namespace actions { -int ReceiveViewChange::effect() const -{ - PlTermv args( - PlTerm((long) m_msg.view()), - PlTerm((long) m_msg.hi()), - PlString((const char*) m_msg.c().c_str()), - m_msg.pi_as_plterm(), - m_msg.qi_as_plterm(), - PlTerm((long) m_msg.sender_id()), - PlString((const char*) m_msg.signature().c_str()), - PlTerm((long) m_replica_id) - ); +int ReceiveViewChange::effect() const { + PlTermv args(PlTerm((long)m_msg.view()), PlTerm((long)m_msg.hi()), PlString((const char*)m_msg.c().c_str()), + m_msg.pi_as_plterm(), m_msg.qi_as_plterm(), PlTerm((long)m_msg.sender_id()), + PlString((const char*)m_msg.signature().c_str()), PlTerm((long)m_replica_id)); return PlCall("effect_RECEIVE_VIEW_CHANGE", args); } -std::string ReceiveViewChange::identify() const -{ - return str( - boost::format( "<%1%, S=%2%, V=%3%, R=%4%>" ) - % name() - % m_msg.sender_id() - % m_msg.view() - % m_replica_id - ); +std::string ReceiveViewChange::identify() const { + return str(boost::format("<%1%, S=%2%, V=%3%, R=%4%>") % name() % m_msg.sender_id() % m_msg.view() % + m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/RecoverView.cpp b/src/fbft/actions/RecoverView.cpp index 92285b2..c198955 100644 --- a/src/fbft/actions/RecoverView.cpp +++ b/src/fbft/actions/RecoverView.cpp @@ -3,9 +3,9 @@ #include "actions.h" +#include #include #include -#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -20,55 +20,32 @@ namespace itcoin { namespace fbft { namespace actions { -RecoverView::RecoverView(uint32_t replica_id, uint32_t view): -Action(replica_id), m_view(view) -{ +RecoverView::RecoverView(uint32_t replica_id, uint32_t view) : Action(replica_id), m_view(view) {} -} +RecoverView::~RecoverView() {} -RecoverView::~RecoverView() -{ - -} - -std::vector> RecoverView::BuildActives( - const itcoin::FbftConfig& config, - Blockchain& blockchain, - RoastWallet& wallet -) -{ +std::vector> +RecoverView::BuildActives(const itcoin::FbftConfig& config, Blockchain& blockchain, RoastWallet& wallet) { std::vector> results{}; - PlTerm V, Replica_id{(long) config.id()}; + PlTerm V, Replica_id{(long)config.id()}; PlQuery query("pre_RECOVER_VIEW", PlTermv(Replica_id, V)); - while ( query.next_solution() ) - { - uint32_t v = (long) V; - std::unique_ptr action = - std::make_unique(config.id(), v); + while (query.next_solution()) { + uint32_t v = (long)V; + std::unique_ptr action = std::make_unique(config.id(), v); results.emplace_back(std::move(action)); } return results; } -int RecoverView::effect() const -{ - PlTermv args( - PlTerm((long) m_replica_id), - PlTerm((long) m_view) - ); +int RecoverView::effect() const { + PlTermv args(PlTerm((long)m_replica_id), PlTerm((long)m_view)); return PlCall("effect_RECOVER_VIEW", args); } -std::string RecoverView::identify() const -{ - return str( - boost::format( "<%1%, V=%2%, R=%3%>" ) - % name() - % m_view - % m_replica_id - ); +std::string RecoverView::identify() const { + return str(boost::format("<%1%, V=%2%, R=%3%>") % name() % m_view % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/RoastInit.cpp b/src/fbft/actions/RoastInit.cpp index ab68fca..f2c9b86 100644 --- a/src/fbft/actions/RoastInit.cpp +++ b/src/fbft/actions/RoastInit.cpp @@ -15,57 +15,36 @@ namespace itcoin { namespace fbft { namespace actions { -RoastInit::RoastInit(PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N): -Action(Replica_id) -{ +RoastInit::RoastInit(PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N) : Action(Replica_id) { // Retrieve payload from the msg store - std::string req_digest = (char*) Req_digest; + std::string req_digest = (char*)Req_digest; m_request = Request::FindByDigest(m_replica_id, req_digest); - m_view = (long) V; + m_view = (long)V; - m_seq_number = (long) N; + m_seq_number = (long)N; } -RoastInit::~RoastInit() -{ +RoastInit::~RoastInit() {} +std::string RoastInit::identify() const { + return str(boost::format("<%1%, Request=%2%, V=%3%, N=%4%, R=%5%>") % name() % m_request.digest() % m_view % + m_seq_number % m_replica_id); } -std::string RoastInit::identify() const -{ - return str( - boost::format( "<%1%, Request=%2%, V=%3%, N=%4%, R=%5%>" ) - % name() - % m_request.digest() - % m_view - % m_seq_number - % m_replica_id - ); -} - -int RoastInit::effect() const -{ - PlTermv args( - PlTerm((long) m_replica_id), - PlTerm((long) m_view), - PlTerm((long) m_seq_number), - PlString((const char*) m_request.digest().c_str()) - ); +int RoastInit::effect() const { + PlTermv args(PlTerm((long)m_replica_id), PlTerm((long)m_view), PlTerm((long)m_seq_number), + PlString((const char*)m_request.digest().c_str())); return PlCall("effect_ROAST_INIT", args); } -std::vector> RoastInit::BuildActives( - const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, - wallet::RoastWallet& wallet -) -{ +std::vector> RoastInit::BuildActives(const itcoin::FbftConfig& config, + blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet) { std::vector> results{}; - PlTerm Req_digest, V, N, Replica_id{(long) config.id()}; + PlTerm Req_digest, V, N, Replica_id{(long)config.id()}; PlQuery query("pre_ROAST_INIT", PlTermv(Replica_id, Req_digest, V, N)); - while ( query.next_solution() ) - { + while (query.next_solution()) { actions::RoastInit action{Replica_id, Req_digest, V, N}; std::unique_ptr p_action = std::make_unique(action); results.emplace_back(move(p_action)); @@ -73,6 +52,6 @@ std::vector> RoastInit::BuildActives( return results; } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/RoastReceivePreSignature.cpp b/src/fbft/actions/RoastReceivePreSignature.cpp index 5dd20c4..9951ad5 100644 --- a/src/fbft/actions/RoastReceivePreSignature.cpp +++ b/src/fbft/actions/RoastReceivePreSignature.cpp @@ -5,9 +5,9 @@ #include +#include #include #include -#include #include "../../wallet/wallet.h" @@ -19,84 +19,65 @@ namespace itcoin { namespace fbft { namespace actions { -RoastReceivePreSignature::RoastReceivePreSignature(wallet::RoastWallet& wallet, uint32_t replica_id, messages::RoastPreSignature msg): -Action(replica_id), m_wallet(wallet), m_msg(msg) -{ +RoastReceivePreSignature::RoastReceivePreSignature(wallet::RoastWallet& wallet, uint32_t replica_id, + messages::RoastPreSignature msg) + : Action(replica_id), m_wallet(wallet), m_msg(msg){ -}; + }; -RoastReceivePreSignature::~RoastReceivePreSignature() -{ +RoastReceivePreSignature::~RoastReceivePreSignature(){ }; -int RoastReceivePreSignature::effect() const -{ +int RoastReceivePreSignature::effect() const { CBlock block_to_sign; - PlTerm Replica_id{(long) m_replica_id}, V, N, Req_digest; + PlTerm Replica_id{(long)m_replica_id}, V, N, Req_digest; int result = PlCall("roast_active", PlTermv(Replica_id, V, N, Req_digest)); - if (result) - { - uint32_t v = (long) V; - uint32_t n = (long) N; - string req_digest = (const char*) Req_digest; + if (result) { + uint32_t v = (long)V; + uint32_t n = (long)N; + string req_digest = (const char*)Req_digest; PrePrepare ppp_msg = PrePrepare::FindByV_N_Req(m_replica_id, v, n, req_digest); block_to_sign = ppp_msg.proposed_block(); - } - else - { - string error_msg = str( - boost::format("R%1% received PRE_SIGNATURE but ROAST is not active, it will be ignored.") - % m_replica_id - ); + } else { + string error_msg = + str(boost::format("R%1% received PRE_SIGNATURE but ROAST is not active, it will be ignored.") % + m_replica_id); BOOST_LOG_TRIVIAL(error) << error_msg; return 0; } bool replica_id_found = false; - for (uint32_t signer_id : m_msg.signers()) - { - if (signer_id == m_replica_id) - { + for (uint32_t signer_id : m_msg.signers()) { + if (signer_id == m_replica_id) { replica_id_found = true; break; } } - if ( replica_id_found ) { - string signature_share = m_wallet.GetSignatureShare(m_msg.signers(), m_msg.pre_signature(), block_to_sign); + if (replica_id_found) { + string signature_share = + m_wallet.GetSignatureShare(m_msg.signers(), m_msg.pre_signature(), block_to_sign); string next_pre_sig_share = m_wallet.GetPreSignatureShare(); - PlTermv args( - PlTerm((long) m_replica_id), - m_msg.signers_as_plterm(), - PlString((const char*) m_msg.pre_signature().c_str()), - PlString((const char*) signature_share.c_str()), - PlString((const char*) next_pre_sig_share.c_str()) - ); + PlTermv args(PlTerm((long)m_replica_id), m_msg.signers_as_plterm(), + PlString((const char*)m_msg.pre_signature().c_str()), + PlString((const char*)signature_share.c_str()), + PlString((const char*)next_pre_sig_share.c_str())); return PlCall("effect_RECEIVE_PRE_SIGNATURE", args); - } - else { + } else { BOOST_LOG_TRIVIAL(info) << str( - boost::format("R%1% received PRE_SIGNATURE but it is not part of the selected signers, it will be ignored.") - % m_replica_id - ); + boost::format( + "R%1% received PRE_SIGNATURE but it is not part of the selected signers, it will be ignored.") % + m_replica_id); return 0; } - - } -std::string RoastReceivePreSignature::identify() const -{ - return str( - boost::format( "<%1%, msg=%2%, R=%3%>" ) - % name() - % m_msg.identify() - % m_replica_id - ); +std::string RoastReceivePreSignature::identify() const { + return str(boost::format("<%1%, msg=%2%, R=%3%>") % name() % m_msg.identify() % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/RoastReceiveSignatureShare.cpp b/src/fbft/actions/RoastReceiveSignatureShare.cpp index 472f874..0d70006 100644 --- a/src/fbft/actions/RoastReceiveSignatureShare.cpp +++ b/src/fbft/actions/RoastReceiveSignatureShare.cpp @@ -3,34 +3,24 @@ #include "actions.h" -#include #include +#include namespace itcoin { namespace fbft { namespace actions { -int RoastReceiveSignatureShare::effect() const -{ - PlTermv args( - PlTerm((long) m_replica_id), - PlTerm((long) m_msg.sender_id()), - PlString((const char*) m_msg.signature_share().c_str()), - PlString((const char*) m_msg.next_pre_signature_share().c_str()) - ); +int RoastReceiveSignatureShare::effect() const { + PlTermv args(PlTerm((long)m_replica_id), PlTerm((long)m_msg.sender_id()), + PlString((const char*)m_msg.signature_share().c_str()), + PlString((const char*)m_msg.next_pre_signature_share().c_str())); return PlCall("effect_RECEIVE_SIG_SHARE", args); } -std::string RoastReceiveSignatureShare::identify() const -{ - return str( - boost::format( "<%1%, msg=%2%, R=%3%>" ) - % name() - % m_msg.identify() - % m_replica_id - ); +std::string RoastReceiveSignatureShare::identify() const { + return str(boost::format("<%1%, msg=%2%, R=%3%>") % name() % m_msg.identify() % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/SendCommit.cpp b/src/fbft/actions/SendCommit.cpp index 231007e..184a43d 100644 --- a/src/fbft/actions/SendCommit.cpp +++ b/src/fbft/actions/SendCommit.cpp @@ -3,9 +3,9 @@ #include "actions.h" +#include #include #include -#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -20,73 +20,49 @@ namespace itcoin { namespace fbft { namespace actions { -SendCommit::SendCommit(RoastWallet& wallet, - PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N) -:Action(Replica_id), m_wallet(wallet) -{ - m_view = (long) V; - m_seq_number = (long) N; +SendCommit::SendCommit(RoastWallet& wallet, PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N) + : Action(Replica_id), m_wallet(wallet) { + m_view = (long)V; + m_seq_number = (long)N; // Retrieve payload from the msg store - std::string req_digest = (const char*) Req_digest; + std::string req_digest = (const char*)Req_digest; m_request = Request::FindByDigest(m_replica_id, req_digest); } -std::vector> SendCommit::BuildActives( - const itcoin::FbftConfig& config, - Blockchain& blockchain, - RoastWallet& wallet -) -{ +std::vector> +SendCommit::BuildActives(const itcoin::FbftConfig& config, Blockchain& blockchain, RoastWallet& wallet) { std::vector> results{}; - PlTerm Req_digest, V, N, Replica_id{(long) config.id()}; + PlTerm Req_digest, V, N, Replica_id{(long)config.id()}; PlQuery query("pre_SEND_COMMIT", PlTermv(Req_digest, V, N, Replica_id)); - while ( query.next_solution() ) - { + while (query.next_solution()) { std::unique_ptr p_action = - std::make_unique(wallet, Replica_id, Req_digest, V, N); + std::make_unique(wallet, Replica_id, Req_digest, V, N); results.emplace_back(move(p_action)); } return results; } -int SendCommit::effect() const -{ +int SendCommit::effect() const { std::string pre_signature = m_wallet.GetPreSignatureShare(); BOOST_LOG_TRIVIAL(debug) << str( - boost::format( "%1% effect(), pre_signature that will be sent by R%2% = %3%" ) - % this->identify() - % m_replica_id - % pre_signature.substr(0,5) - ); + boost::format("%1% effect(), pre_signature that will be sent by R%2% = %3%") % this->identify() % + m_replica_id % pre_signature.substr(0, 5)); // We build the commit to send - Commit msg{ m_replica_id, - m_view, m_seq_number, pre_signature - }; + Commit msg{m_replica_id, m_view, m_seq_number, pre_signature}; - PlTermv args( - PlTerm((long) m_view), - PlTerm((long) m_seq_number), - PlString((const char*) msg.pre_signature().c_str()), - PlTerm((long) m_replica_id) - ); + PlTermv args(PlTerm((long)m_view), PlTerm((long)m_seq_number), + PlString((const char*)msg.pre_signature().c_str()), PlTerm((long)m_replica_id)); return PlCall("effect_SEND_COMMIT", args); } -std::string SendCommit::identify() const -{ - return str( - boost::format( "<%1%, Req=%2%, V=%3%, N=%4%, R=%5%>" ) - % name() - % m_request.digest() - % m_view - % m_seq_number - % m_replica_id - ); +std::string SendCommit::identify() const { + return str(boost::format("<%1%, Req=%2%, V=%3%, N=%4%, R=%5%>") % name() % m_request.digest() % m_view % + m_seq_number % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/SendNewView.cpp b/src/fbft/actions/SendNewView.cpp index b276f07..b073aa0 100644 --- a/src/fbft/actions/SendNewView.cpp +++ b/src/fbft/actions/SendNewView.cpp @@ -3,9 +3,9 @@ #include "actions.h" +#include #include #include -#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -20,47 +20,33 @@ namespace itcoin { namespace fbft { namespace actions { -std::vector> SendNewView::BuildActives( - const itcoin::FbftConfig& config, - Blockchain& blockchain, - RoastWallet& wallet -) -{ +std::vector> +SendNewView::BuildActives(const itcoin::FbftConfig& config, Blockchain& blockchain, RoastWallet& wallet) { std::vector> results{}; - PlTerm Nu, Chi, Replica_id{(long) config.id()}; + PlTerm Nu, Chi, Replica_id{(long)config.id()}; PlQuery query("pre_SEND_NEW_VIEW", PlTermv(Nu, Chi, Replica_id)); - while ( query.next_solution() ) - { + while (query.next_solution()) { auto nu = NewView::nu_from_plterm(Nu); auto chi = NewView::chi_from_plterm(Chi); - unique_ptr action = - std::make_unique(config.id(), nu, chi); + unique_ptr action = std::make_unique(config.id(), nu, chi); results.emplace_back(std::move(action)); } return results; } -int SendNewView::effect() const -{ - PlTermv args( - NewView::nu_as_plterm(m_nu), // Nu - NewView::chi_as_plterm(m_chi), // Chi - PlTerm((long) m_replica_id) - ); +int SendNewView::effect() const { + PlTermv args(NewView::nu_as_plterm(m_nu), // Nu + NewView::chi_as_plterm(m_chi), // Chi + PlTerm((long)m_replica_id)); return PlCall("effect_SEND_NEW_VIEW", args); } -std::string SendNewView::identify() const -{ - return str( - boost::format( "<%1%, R=%2%>" ) - % name() - % m_replica_id - ); +std::string SendNewView::identify() const { + return str(boost::format("<%1%, R=%2%>") % name() % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/SendPrePrepare.cpp b/src/fbft/actions/SendPrePrepare.cpp index c753d7b..1a749c3 100644 --- a/src/fbft/actions/SendPrePrepare.cpp +++ b/src/fbft/actions/SendPrePrepare.cpp @@ -3,9 +3,9 @@ #include "actions.h" +#include #include #include -#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -20,52 +20,39 @@ namespace itcoin { namespace fbft { namespace actions { -SendPrePrepare::SendPrePrepare(Blockchain& blockchain, -PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N) -: Action(Replica_id), m_blockchain(blockchain) -{ - m_view = (long) V; - m_seq_number = (long) N; +SendPrePrepare::SendPrePrepare(Blockchain& blockchain, PlTerm Replica_id, PlTerm Req_digest, PlTerm V, + PlTerm N) + : Action(Replica_id), m_blockchain(blockchain) { + m_view = (long)V; + m_seq_number = (long)N; // Retrieve request - std::string req_digest = (char*) Req_digest; + std::string req_digest = (char*)Req_digest; m_request = messages::Request::FindByDigest(m_replica_id, req_digest); } -std::vector> SendPrePrepare::BuildActives( - const itcoin::FbftConfig& config, - Blockchain& blockchain, - RoastWallet& wallet -) -{ +std::vector> +SendPrePrepare::BuildActives(const itcoin::FbftConfig& config, Blockchain& blockchain, RoastWallet& wallet) { std::vector> results{}; - PlTerm Req_digest, V, N, Replica_id{(long) config.id()}; + PlTerm Req_digest, V, N, Replica_id{(long)config.id()}; PlQuery query("pre_SEND_PRE_PREPARE", PlTermv(Req_digest, V, N, Replica_id)); - while ( query.next_solution() ) - { + while (query.next_solution()) { std::unique_ptr action = - std::make_unique(blockchain, - Replica_id, Req_digest, V, N); + std::make_unique(blockchain, Replica_id, Req_digest, V, N); results.emplace_back(std::move(action)); } return results; } -int SendPrePrepare::effect() const -{ +int SendPrePrepare::effect() const { // We create the block to propose CBlock proposed_block; - try - { - proposed_block = m_blockchain.GenerateBlock( m_request.timestamp() ); - } - catch(const std::runtime_error& e) - { + try { + proposed_block = m_blockchain.GenerateBlock(m_request.timestamp()); + } catch (const std::runtime_error& e) { BOOST_LOG_TRIVIAL(error) << str( - boost::format( "%1% effect(), GenerateBlock raised runtime exception = %2%" ) - % this->identify() - % e.what() - ); + boost::format("%1% effect(), GenerateBlock raised runtime exception = %2%") % this->identify() % + e.what()); return 0; } @@ -73,40 +60,23 @@ int SendPrePrepare::effect() const const uint32_t block_size_bytes = block_ser.GetHex().length() / 2; const std::string block_hash = proposed_block.GetBlockHeader().GetHash().ToString(); - BOOST_LOG_TRIVIAL(debug) << str( - boost::format( "%1% effect(), Proposed block size: %2% bytes, hash: %3%" ) - % this->identify() - % block_size_bytes - % block_hash - ); + BOOST_LOG_TRIVIAL(debug) << str(boost::format("%1% effect(), Proposed block size: %2% bytes, hash: %3%") % + this->identify() % block_size_bytes % block_hash); // Now the PrePrepare is ready to be sent, we can save it into the message store - messages::PrePrepare msg(m_replica_id, - m_view, m_seq_number, m_request.digest().c_str(), - proposed_block); + messages::PrePrepare msg(m_replica_id, m_view, m_seq_number, m_request.digest().c_str(), proposed_block); - PlTermv args( - PlString((const char*) m_request.digest().c_str()), - PlString((const char*) msg.proposed_block_hex().c_str()), - PlTerm((long) m_view), - PlTerm((long) m_seq_number), - PlTerm((long) m_replica_id) - ); + PlTermv args(PlString((const char*)m_request.digest().c_str()), + PlString((const char*)msg.proposed_block_hex().c_str()), PlTerm((long)m_view), + PlTerm((long)m_seq_number), PlTerm((long)m_replica_id)); return PlCall("effect_SEND_PRE_PREPARE", args); } -std::string SendPrePrepare::identify() const -{ - return str( - boost::format( "<%1%, Request=%2%, V=%3%, N=%4%, R=%5%>" ) - % name() - % m_request.digest() - % m_view - % m_seq_number - % m_replica_id - ); +std::string SendPrePrepare::identify() const { + return str(boost::format("<%1%, Request=%2%, V=%3%, N=%4%, R=%5%>") % name() % m_request.digest() % m_view % + m_seq_number % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/SendPrepare.cpp b/src/fbft/actions/SendPrepare.cpp index 13a63d3..559b736 100644 --- a/src/fbft/actions/SendPrepare.cpp +++ b/src/fbft/actions/SendPrepare.cpp @@ -3,9 +3,9 @@ #include "actions.h" +#include #include #include -#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -20,58 +20,39 @@ namespace itcoin { namespace fbft { namespace actions { -SendPrepare::SendPrepare(PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N) -: Action(Replica_id) -{ - m_view = (long) V; - m_seq_number = (long) N; +SendPrepare::SendPrepare(PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N) : Action(Replica_id) { + m_view = (long)V; + m_seq_number = (long)N; // Retrieve payload from the msg store - std::string req_digest = (char*) Req_digest; + std::string req_digest = (char*)Req_digest; m_request = messages::Request::FindByDigest(m_replica_id, req_digest); } -std::vector> SendPrepare::BuildActives( - const itcoin::FbftConfig& config, - Blockchain& blockchain, - RoastWallet& wallet -) -{ +std::vector> +SendPrepare::BuildActives(const itcoin::FbftConfig& config, Blockchain& blockchain, RoastWallet& wallet) { std::vector> results{}; - PlTerm Req_digest, V, N, Replica_id{(long) config.id()}; + PlTerm Req_digest, V, N, Replica_id{(long)config.id()}; PlQuery query("pre_SEND_PREPARE", PlTermv(Req_digest, V, N, Replica_id)); - while ( query.next_solution() ) - { + while (query.next_solution()) { std::unique_ptr action = - std::make_unique(Replica_id, Req_digest, V, N); + std::make_unique(Replica_id, Req_digest, V, N); results.emplace_back(std::move(action)); } return results; } -int SendPrepare::effect() const -{ - PlTermv args( - PlString((const char*) m_request.digest().c_str()), - PlTerm((long) m_view), - PlTerm((long) m_seq_number), - PlTerm((long) m_replica_id) - ); +int SendPrepare::effect() const { + PlTermv args(PlString((const char*)m_request.digest().c_str()), PlTerm((long)m_view), + PlTerm((long)m_seq_number), PlTerm((long)m_replica_id)); return PlCall("effect_SEND_PREPARE", args); } -std::string SendPrepare::identify() const -{ - return str( - boost::format( "<%1%, Request=%2%, V=%3%, N=%4%, R=%5%>" ) - % name() - % m_request.digest() - % m_view - % m_seq_number - % m_replica_id - ); +std::string SendPrepare::identify() const { + return str(boost::format("<%1%, Request=%2%, V=%3%, N=%4%, R=%5%>") % name() % m_request.digest() % m_view % + m_seq_number % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/SendViewChange.cpp b/src/fbft/actions/SendViewChange.cpp index b6c79d9..d49d9e1 100644 --- a/src/fbft/actions/SendViewChange.cpp +++ b/src/fbft/actions/SendViewChange.cpp @@ -3,9 +3,9 @@ #include "actions.h" +#include #include #include -#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -20,44 +20,29 @@ namespace itcoin { namespace fbft { namespace actions { -std::vector> SendViewChange::BuildActives( - const itcoin::FbftConfig& config, - Blockchain& blockchain, - RoastWallet& wallet -) -{ +std::vector> +SendViewChange::BuildActives(const itcoin::FbftConfig& config, Blockchain& blockchain, RoastWallet& wallet) { std::vector> results{}; - PlTerm V, Replica_id{(long) config.id()}; + PlTerm V, Replica_id{(long)config.id()}; PlQuery query("pre_SEND_VIEW_CHANGE", PlTermv(V, Replica_id)); - while ( query.next_solution() ) - { - uint32_t v = (long) V; + while (query.next_solution()) { + uint32_t v = (long)V; std::unique_ptr action = - std::make_unique(config.id(), v); + std::make_unique(config.id(), v); results.emplace_back(std::move(action)); } return results; } -int SendViewChange::effect() const -{ - PlTermv args( - PlTerm((long) m_view), - PlTerm((long) m_replica_id) - ); +int SendViewChange::effect() const { + PlTermv args(PlTerm((long)m_view), PlTerm((long)m_replica_id)); return PlCall("effect_SEND_VIEW_CHANGE", args); } -std::string SendViewChange::identify() const -{ - return str( - boost::format( "<%1%, V=%2%, R=%3%>" ) - % name() - % m_view - % m_replica_id - ); +std::string SendViewChange::identify() const { + return str(boost::format("<%1%, V=%2%, R=%3%>") % name() % m_view % m_replica_id); } -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/actions/actions.h b/src/fbft/actions/actions.h index 0ca3d55..65b27c1 100644 --- a/src/fbft/actions/actions.h +++ b/src/fbft/actions/actions.h @@ -9,21 +9,25 @@ #include "../messages/messages.h" namespace itcoin { - enum SIGNATURE_ALGO_TYPE : unsigned int; - class FbftConfig; -} +enum SIGNATURE_ALGO_TYPE : unsigned int; +class FbftConfig; +} // namespace itcoin -namespace itcoin { namespace blockchain { - class Blockchain; -}} +namespace itcoin { +namespace blockchain { +class Blockchain; +} +} // namespace itcoin -namespace itcoin { namespace wallet { - class RoastWallet; -}} +namespace itcoin { +namespace wallet { +class RoastWallet; +} +} // namespace itcoin -namespace blockchain=itcoin::blockchain; -namespace wallet=itcoin::wallet; -namespace messages=itcoin::fbft::messages; +namespace blockchain = itcoin::blockchain; +namespace wallet = itcoin::wallet; +namespace messages = itcoin::fbft::messages; namespace itcoin { namespace fbft { @@ -52,317 +56,337 @@ enum class ACTION_TYPE { }; const std::string ACTION_TYPE_TYPE_AS_STRING[] = { - "INVALID", - "EXECUTE", - "PROCESS_NEW_VIEW", - "RECEIVE_BLOCK", - "RECEIVE_COMMIT", - "RECEIVE_NEW_VIEW", - "RECEIVE_PREPARE", - "RECEIVE_PRE_PREPARE", - "RECEIVE_REQUEST", - "RECEIVE_VIEW_CHANGE", - "RECOVER_VIEW", - "SEND_COMMIT", - "SEND_NEW_VIEW", - "SEND_PREPARE", - "SEND_PRE_PREPARE", - "SEND_VIEW_CHANGE", - "ROAST_INIT", - "ROAST_RECEIVE_PRE_SIGNATURE", - "ROAST_RECEIVE_SIGNATURE_SHARE", + "INVALID", + "EXECUTE", + "PROCESS_NEW_VIEW", + "RECEIVE_BLOCK", + "RECEIVE_COMMIT", + "RECEIVE_NEW_VIEW", + "RECEIVE_PREPARE", + "RECEIVE_PRE_PREPARE", + "RECEIVE_REQUEST", + "RECEIVE_VIEW_CHANGE", + "RECOVER_VIEW", + "SEND_COMMIT", + "SEND_NEW_VIEW", + "SEND_PREPARE", + "SEND_PRE_PREPARE", + "SEND_VIEW_CHANGE", + "ROAST_INIT", + "ROAST_RECEIVE_PRE_SIGNATURE", + "ROAST_RECEIVE_SIGNATURE_SHARE", }; class Action { - public: - Action(uint32_t replica_id); - Action(PlTerm Replica_id); - virtual ~Action() {}; +public: + Action(uint32_t replica_id); + Action(PlTerm Replica_id); + virtual ~Action(){}; - // Getters - virtual std::string identify() const = 0; - virtual std::optional> message() const; - std::string name() const; - virtual ACTION_TYPE type() const = 0; + // Getters + virtual std::string identify() const = 0; + virtual std::optional> message() const; + std::string name() const; + virtual ACTION_TYPE type() const = 0; - // Operations - virtual int effect() const = 0; + // Operations + virtual int effect() const = 0; - // Operators - friend std::ostream& operator<<(std::ostream& Str, const Action& action); + // Operators + friend std::ostream& operator<<(std::ostream& Str, const Action& action); - protected: - uint32_t m_replica_id; +protected: + uint32_t m_replica_id; }; class Execute : public Action { - public: - Execute(blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet, - PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N); - ~Execute() {}; +public: + Execute(blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet, PlTerm Replica_id, + PlTerm Req_digest, PlTerm V, PlTerm N); + ~Execute(){}; - std::string identify() const; - ACTION_TYPE type() const { return ACTION_TYPE::EXECUTE; } + std::string identify() const; + ACTION_TYPE type() const { return ACTION_TYPE::EXECUTE; } - int effect() const; + int effect() const; - static std::vector> BuildActives(const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet); + static std::vector> BuildActives(const itcoin::FbftConfig& config, + blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet); - private: - blockchain::Blockchain& m_blockchain; - wallet::RoastWallet& m_wallet; +private: + blockchain::Blockchain& m_blockchain; + wallet::RoastWallet& m_wallet; - messages::Request m_request; - uint32_t m_view; - uint32_t m_seq_number; + messages::Request m_request; + uint32_t m_view; + uint32_t m_seq_number; }; -class ProcessNewView: public Action { - public: - ProcessNewView(PlTerm Replica_id, PlTerm Hi, PlTerm Nu, PlTerm Chi); - ~ProcessNewView() {}; +class ProcessNewView : public Action { +public: + ProcessNewView(PlTerm Replica_id, PlTerm Hi, PlTerm Nu, PlTerm Chi); + ~ProcessNewView(){}; - std::string identify() const; - ACTION_TYPE type() const { return ACTION_TYPE::PROCESS_NEW_VIEW; } + std::string identify() const; + ACTION_TYPE type() const { return ACTION_TYPE::PROCESS_NEW_VIEW; } - int effect() const; + int effect() const; - static std::vector> BuildActives(const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet); + static std::vector> + BuildActives(const itcoin::FbftConfig& config, blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet); - private: - uint32_t m_hi; - messages::new_view_nu_t m_nu; - messages::new_view_chi_t m_chi; +private: + uint32_t m_hi; + messages::new_view_nu_t m_nu; + messages::new_view_chi_t m_chi; }; class ReceiveBlock : public Action { - public: - ReceiveBlock(uint32_t replica_id, messages::Block msg):Action(replica_id), m_msg(msg){}; - ~ReceiveBlock() {}; +public: + ReceiveBlock(uint32_t replica_id, messages::Block msg) : Action(replica_id), m_msg(msg){}; + ~ReceiveBlock(){}; - std::string identify() const; - std::optional> message() const {return std::optional>((const messages::Message&) m_msg);} - ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_BLOCK; } + std::string identify() const; + std::optional> message() const { + return std::optional>((const messages::Message&)m_msg); + } + ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_BLOCK; } - int effect() const; + int effect() const; - private: - messages::Block m_msg; +private: + messages::Block m_msg; }; class ReceiveCommit : public Action { - public: - ReceiveCommit(uint32_t replica_id, messages::Commit msg):Action(replica_id), m_msg(msg){}; - ~ReceiveCommit() {}; +public: + ReceiveCommit(uint32_t replica_id, messages::Commit msg) : Action(replica_id), m_msg(msg){}; + ~ReceiveCommit(){}; - std::string identify() const; - std::optional> message() const {return std::optional>((const messages::Message&) m_msg);} - ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_COMMIT; } + std::string identify() const; + std::optional> message() const { + return std::optional>((const messages::Message&)m_msg); + } + ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_COMMIT; } - int effect() const; + int effect() const; - private: - messages::Commit m_msg; +private: + messages::Commit m_msg; }; class ReceiveNewView : public Action { - public: - ReceiveNewView(wallet::RoastWallet& wallet, uint32_t replica_id, messages::NewView msg); - ~ReceiveNewView() {}; +public: + ReceiveNewView(wallet::RoastWallet& wallet, uint32_t replica_id, messages::NewView msg); + ~ReceiveNewView(){}; - std::string identify() const; - std::optional> message() const {return std::optional>((const messages::Message&) m_msg);} - ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_NEW_VIEW; } + std::string identify() const; + std::optional> message() const { + return std::optional>((const messages::Message&)m_msg); + } + ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_NEW_VIEW; } - int effect() const; + int effect() const; - private: - wallet::RoastWallet& m_wallet; +private: + wallet::RoastWallet& m_wallet; - messages::NewView m_msg; + messages::NewView m_msg; }; class ReceivePrepare : public Action { - public: - ReceivePrepare(uint32_t replica_id, messages::Prepare msg): Action(replica_id), m_msg(msg){};; - ~ReceivePrepare() {}; +public: + ReceivePrepare(uint32_t replica_id, messages::Prepare msg) : Action(replica_id), m_msg(msg){}; + ; + ~ReceivePrepare(){}; - std::string identify() const; - std::optional> message() const {return std::optional>((const messages::Message&) m_msg);} - ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_PREPARE; } + std::string identify() const; + std::optional> message() const { + return std::optional>((const messages::Message&)m_msg); + } + ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_PREPARE; } - int effect() const; + int effect() const; - private: - messages::Prepare m_msg; +private: + messages::Prepare m_msg; }; class ReceivePrePrepare : public Action { - public: - ReceivePrePrepare(uint32_t replica_id, blockchain::Blockchain& blockchain, - double current_time, double pre_prepare_time_tolerance_delta, messages::PrePrepare msg); - ~ReceivePrePrepare(){}; - - std::string identify() const; - std::optional> message() const {return std::optional>((const messages::Message&) m_msg);} - ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_PRE_PREPARE; } - - int effect() const; - - private: - blockchain::Blockchain& m_blockchain; - double m_current_time; - double m_pre_prepare_time_tolerance_delta; - messages::PrePrepare m_msg; +public: + ReceivePrePrepare(uint32_t replica_id, blockchain::Blockchain& blockchain, double current_time, + double pre_prepare_time_tolerance_delta, messages::PrePrepare msg); + ~ReceivePrePrepare(){}; + + std::string identify() const; + std::optional> message() const { + return std::optional>((const messages::Message&)m_msg); + } + ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_PRE_PREPARE; } + + int effect() const; + +private: + blockchain::Blockchain& m_blockchain; + double m_current_time; + double m_pre_prepare_time_tolerance_delta; + messages::PrePrepare m_msg; }; class ReceiveRequest : public Action { - public: - ReceiveRequest(uint32_t replica_id, messages::Request request): Action(replica_id), m_msg(request){}; - ~ReceiveRequest(){}; +public: + ReceiveRequest(uint32_t replica_id, messages::Request request) : Action(replica_id), m_msg(request){}; + ~ReceiveRequest(){}; - std::string identify() const; - std::optional> message() const {return std::optional>((const messages::Message&) m_msg);} - ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_REQUEST; } + std::string identify() const; + std::optional> message() const { + return std::optional>((const messages::Message&)m_msg); + } + ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_REQUEST; } - int effect() const; + int effect() const; - private: - messages::Request m_msg; +private: + messages::Request m_msg; }; class ReceiveViewChange : public Action { - public: - ReceiveViewChange(uint32_t replica_id, messages::ViewChange msg): Action(replica_id), m_msg(msg){}; - ~ReceiveViewChange(){}; +public: + ReceiveViewChange(uint32_t replica_id, messages::ViewChange msg) : Action(replica_id), m_msg(msg){}; + ~ReceiveViewChange(){}; - std::string identify() const; - std::optional> message() const {return std::optional>((const messages::Message&) m_msg);} - ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_VIEW_CHANGE; } + std::string identify() const; + std::optional> message() const { + return std::optional>((const messages::Message&)m_msg); + } + ACTION_TYPE type() const { return ACTION_TYPE::RECEIVE_VIEW_CHANGE; } - int effect() const; + int effect() const; - private: - messages::ViewChange m_msg; +private: + messages::ViewChange m_msg; }; -class RecoverView: public Action { - public: - RecoverView(uint32_t replica_id, uint32_t view); - ~RecoverView(); +class RecoverView : public Action { +public: + RecoverView(uint32_t replica_id, uint32_t view); + ~RecoverView(); - std::string identify() const; - ACTION_TYPE type() const { return ACTION_TYPE::RECOVER_VIEW; } - int effect() const; + std::string identify() const; + ACTION_TYPE type() const { return ACTION_TYPE::RECOVER_VIEW; } + int effect() const; - static std::vector> BuildActives(const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet); + static std::vector> BuildActives(const itcoin::FbftConfig& config, + blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet); - private: - uint32_t m_view; +private: + uint32_t m_view; }; class SendCommit : public Action { - public: - SendCommit(wallet::RoastWallet& wallet, - PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N); - ~SendCommit(){}; +public: + SendCommit(wallet::RoastWallet& wallet, PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N); + ~SendCommit(){}; - std::string identify() const; - ACTION_TYPE type() const { return ACTION_TYPE::SEND_COMMIT; } + std::string identify() const; + ACTION_TYPE type() const { return ACTION_TYPE::SEND_COMMIT; } - int effect() const; + int effect() const; - static std::vector> BuildActives(const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet); + static std::vector> BuildActives(const itcoin::FbftConfig& config, + blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet); - private: - wallet::RoastWallet& m_wallet; +private: + wallet::RoastWallet& m_wallet; - messages::Request m_request; - uint32_t m_view; - uint32_t m_seq_number; + messages::Request m_request; + uint32_t m_view; + uint32_t m_seq_number; }; class SendNewView : public Action { - public: - SendNewView(uint32_t replica_id, - messages::new_view_nu_t nu, - messages::new_view_chi_t chi - ): Action(replica_id), m_nu(nu), m_chi(chi) {}; - ~SendNewView(){}; +public: + SendNewView(uint32_t replica_id, messages::new_view_nu_t nu, messages::new_view_chi_t chi) + : Action(replica_id), m_nu(nu), m_chi(chi){}; + ~SendNewView(){}; - std::string identify() const; - ACTION_TYPE type() const { return ACTION_TYPE::SEND_NEW_VIEW; } + std::string identify() const; + ACTION_TYPE type() const { return ACTION_TYPE::SEND_NEW_VIEW; } - int effect() const; + int effect() const; - static std::vector> BuildActives(const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet); + static std::vector> BuildActives(const itcoin::FbftConfig& config, + blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet); - private: - messages::new_view_nu_t m_nu; - messages::new_view_chi_t m_chi; +private: + messages::new_view_nu_t m_nu; + messages::new_view_chi_t m_chi; }; class SendPrepare : public Action { - public: - SendPrepare(PlTerm Replica_id, PlTerm Req_digest, PlTerm View, PlTerm Seq_number); - ~SendPrepare(){}; +public: + SendPrepare(PlTerm Replica_id, PlTerm Req_digest, PlTerm View, PlTerm Seq_number); + ~SendPrepare(){}; - std::string identify() const; - ACTION_TYPE type() const { return ACTION_TYPE::SEND_PREPARE; } + std::string identify() const; + ACTION_TYPE type() const { return ACTION_TYPE::SEND_PREPARE; } - int effect() const; + int effect() const; - static std::vector> BuildActives(const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet); + static std::vector> BuildActives(const itcoin::FbftConfig& config, + blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet); - private: - messages::Request m_request; - uint32_t m_view; - uint32_t m_seq_number; +private: + messages::Request m_request; + uint32_t m_view; + uint32_t m_seq_number; }; class SendPrePrepare : public Action { - public: - SendPrePrepare(blockchain::Blockchain& blockchain, - PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N); - ~SendPrePrepare(){}; +public: + SendPrePrepare(blockchain::Blockchain& blockchain, PlTerm Replica_id, PlTerm Req_digest, PlTerm V, + PlTerm N); + ~SendPrePrepare(){}; - std::string identify() const; - ACTION_TYPE type() const { return ACTION_TYPE::SEND_PRE_PREPARE; } + std::string identify() const; + ACTION_TYPE type() const { return ACTION_TYPE::SEND_PRE_PREPARE; } - int effect() const; + int effect() const; - static std::vector> BuildActives(const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet); + static std::vector> + BuildActives(const itcoin::FbftConfig& config, blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet); - private: - blockchain::Blockchain& m_blockchain; +private: + blockchain::Blockchain& m_blockchain; - messages::Request m_request; - uint32_t m_view; - uint32_t m_seq_number; + messages::Request m_request; + uint32_t m_view; + uint32_t m_seq_number; }; class SendViewChange : public Action { - public: - SendViewChange(uint32_t replica_id, uint32_t view): Action(replica_id), m_view(view) {}; - ~SendViewChange(){}; +public: + SendViewChange(uint32_t replica_id, uint32_t view) : Action(replica_id), m_view(view){}; + ~SendViewChange(){}; - std::string identify() const; - ACTION_TYPE type() const { return ACTION_TYPE::SEND_VIEW_CHANGE; } + std::string identify() const; + ACTION_TYPE type() const { return ACTION_TYPE::SEND_VIEW_CHANGE; } - int effect() const; + int effect() const; - static std::vector> BuildActives(const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet); + static std::vector> + BuildActives(const itcoin::FbftConfig& config, blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet); - private: - uint32_t m_view; +private: + uint32_t m_view; }; class RoastInit : public Action { @@ -370,52 +394,58 @@ class RoastInit : public Action { uint32_t m_view; uint32_t m_seq_number; - public: - RoastInit(PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N); - ~RoastInit(); +public: + RoastInit(PlTerm Replica_id, PlTerm Req_digest, PlTerm V, PlTerm N); + ~RoastInit(); - std::string identify() const; - ACTION_TYPE type() const { return ACTION_TYPE::ROAST_INIT; } + std::string identify() const; + ACTION_TYPE type() const { return ACTION_TYPE::ROAST_INIT; } - int effect() const; + int effect() const; - static std::vector> BuildActives(const itcoin::FbftConfig& config, - blockchain::Blockchain& blockchain, wallet::RoastWallet& wallet); + static std::vector> BuildActives(const itcoin::FbftConfig& config, + blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet); }; class RoastReceivePreSignature : public Action { - public: - RoastReceivePreSignature(wallet::RoastWallet& wallet, uint32_t replica_id, messages::RoastPreSignature msg); - ~RoastReceivePreSignature(); +public: + RoastReceivePreSignature(wallet::RoastWallet& wallet, uint32_t replica_id, messages::RoastPreSignature msg); + ~RoastReceivePreSignature(); - std::string identify() const; - std::optional> message() const {return std::optional>((const messages::Message&) m_msg);} - ACTION_TYPE type() const { return ACTION_TYPE::ROAST_RECEIVE_PRE_SIGNATURE; } + std::string identify() const; + std::optional> message() const { + return std::optional>((const messages::Message&)m_msg); + } + ACTION_TYPE type() const { return ACTION_TYPE::ROAST_RECEIVE_PRE_SIGNATURE; } - int effect() const; + int effect() const; - private: - wallet::RoastWallet& m_wallet; - messages::RoastPreSignature m_msg; +private: + wallet::RoastWallet& m_wallet; + messages::RoastPreSignature m_msg; }; class RoastReceiveSignatureShare : public Action { - public: - RoastReceiveSignatureShare(uint32_t replica_id, messages::RoastSignatureShare msg):Action(replica_id), m_msg(msg){}; - ~RoastReceiveSignatureShare() {}; +public: + RoastReceiveSignatureShare(uint32_t replica_id, messages::RoastSignatureShare msg) + : Action(replica_id), m_msg(msg){}; + ~RoastReceiveSignatureShare(){}; - std::string identify() const; - std::optional> message() const {return std::optional>((const messages::Message&) m_msg);} - ACTION_TYPE type() const { return ACTION_TYPE::ROAST_RECEIVE_SIGNATURE_SHARE; } + std::string identify() const; + std::optional> message() const { + return std::optional>((const messages::Message&)m_msg); + } + ACTION_TYPE type() const { return ACTION_TYPE::ROAST_RECEIVE_SIGNATURE_SHARE; } - int effect() const; + int effect() const; - private: - messages::RoastSignatureShare m_msg; +private: + messages::RoastSignatureShare m_msg; }; -} -} -} +} // namespace actions +} // namespace fbft +} // namespace itcoin #endif // ITCOIN_FBFT_ACTIONS_ACTIONS_H diff --git a/src/fbft/messages/Block.cpp b/src/fbft/messages/Block.cpp index 8bf375c..970107e 100644 --- a/src/fbft/messages/Block.cpp +++ b/src/fbft/messages/Block.cpp @@ -14,44 +14,38 @@ namespace fbft { namespace messages { Block::Block(uint32_t block_height, uint32_t block_time, std::string block_hash) -:Message(NODE_TYPE::CLIENT, 8888) -{ + : Message(NODE_TYPE::CLIENT, 8888) { m_block_height = block_height; m_block_time = block_time; m_block_hash = block_hash; } -Block::~Block() -{ -}; +Block::~Block(){}; -bool Block::equals(const Message& other) const -{ - if (typeid(*this) != typeid(other)) return false; +bool Block::equals(const Message& other) const { + if (typeid(*this) != typeid(other)) + return false; auto typed_other = static_cast(other); - if (m_block_height != typed_other.m_block_height) return false; - if (m_block_time != typed_other.m_block_time) return false; - if (m_block_hash != typed_other.m_block_hash) return false; + if (m_block_height != typed_other.m_block_height) + return false; + if (m_block_time != typed_other.m_block_time) + return false; + if (m_block_hash != typed_other.m_block_hash) + return false; return Message::equals(other); } -std::unique_ptr Block::clone() -{ +std::unique_ptr Block::clone() { std::unique_ptr msg = std::make_unique(*this); return msg; } -std::string Block::identify() const -{ - return str( - boost::format( "" ) - % m_block_height - % m_block_time - % m_block_hash - ); +std::string Block::identify() const { + return str(boost::format("") % m_block_height % m_block_time % + m_block_hash); } -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/messages/Commit.cpp b/src/fbft/messages/Commit.cpp index 67022af..611180d 100644 --- a/src/fbft/messages/Commit.cpp +++ b/src/fbft/messages/Commit.cpp @@ -5,8 +5,8 @@ #include -#include "config/FbftConfig.h" #include "../../utils/utils.h" +#include "config/FbftConfig.h" using namespace std; using namespace itcoin::blockchain; @@ -15,58 +15,44 @@ namespace itcoin { namespace fbft { namespace messages { -Commit::Commit(uint32_t sender_id, - uint32_t view, uint32_t seq_number, - std::string block_signature) -:Message(NODE_TYPE::REPLICA, sender_id) -{ +Commit::Commit(uint32_t sender_id, uint32_t view, uint32_t seq_number, std::string block_signature) + : Message(NODE_TYPE::REPLICA, sender_id) { m_view = view; m_seq_number = seq_number; m_pre_signature = block_signature; } Commit::Commit(PlTerm Sender_id, PlTerm V, PlTerm N, PlTerm Block_signature) -:Message(NODE_TYPE::REPLICA, Sender_id) -{ - m_view = (long) V; - m_seq_number = (long) N; - std::string block_signature_hex{ (const char*) Block_signature }; + : Message(NODE_TYPE::REPLICA, Sender_id) { + m_view = (long)V; + m_seq_number = (long)N; + std::string block_signature_hex{(const char*)Block_signature}; this->set_pre_signature(block_signature_hex); } -void Commit::set_pre_signature(std::string pre_signature_hex) -{ - m_pre_signature = pre_signature_hex; -} +void Commit::set_pre_signature(std::string pre_signature_hex) { m_pre_signature = pre_signature_hex; } -Commit::~Commit() -{ -}; +Commit::~Commit(){}; -std::vector> Commit::BuildToBeSent(uint32_t replica_id) -{ +std::vector> Commit::BuildToBeSent(uint32_t replica_id) { std::vector> results{}; - PlTerm Replica_id{(long) replica_id}, V, N, Block_signature; + PlTerm Replica_id{(long)replica_id}, V, N, Block_signature; PlQuery query("msg_out_commit", PlTermv(Replica_id, V, N, Block_signature)); - while ( query.next_solution() ) - { + while (query.next_solution()) { messages::Commit msg{Replica_id, V, N, Block_signature}; results.emplace_back(std::move(std::make_unique(msg))); } return results; } -std::vector Commit::FindByV_N(uint32_t replica_id, uint32_t v, uint32_t n) -{ +std::vector Commit::FindByV_N(uint32_t replica_id, uint32_t v, uint32_t n) { std::vector results{}; - PlTerm Replica_id{(long) replica_id}, V{(long) v}, N{(long) n}, Block_signature, Sender_id, Sender_sig; + PlTerm Replica_id{(long)replica_id}, V{(long)v}, N{(long)n}, Block_signature, Sender_id, Sender_sig; PlQuery query{"msg_log_commit", PlTermv(Replica_id, V, N, Block_signature, Sender_id, Sender_sig)}; - while ( query.next_solution() ) - { + while (query.next_solution()) { messages::Commit msg{Sender_id, V, N, Block_signature}; - if ((long) Sender_id != replica_id) - { - string sender_sig_hex{(const char*) Sender_sig}; + if ((long)Sender_id != replica_id) { + string sender_sig_hex{(const char*)Sender_sig}; msg.set_signature(sender_sig_hex); } results.emplace_back(msg); @@ -74,68 +60,50 @@ std::vector Commit::FindByV_N(uint32_t replica_id, uint32_t v, return results; } -bool Commit::equals(const Message& other) const -{ - if (typeid(*this) != typeid(other)) return false; +bool Commit::equals(const Message& other) const { + if (typeid(*this) != typeid(other)) + return false; auto typed_other = static_cast(other); - if (m_view != typed_other.m_view) return false; - if (m_seq_number != typed_other.m_seq_number) return false; + if (m_view != typed_other.m_view) + return false; + if (m_seq_number != typed_other.m_seq_number) + return false; return Message::equals(other); } -std::unique_ptr Commit::clone() -{ +std::unique_ptr Commit::clone() { std::unique_ptr msg = std::make_unique(*this); return msg; } -const std::string Commit::digest() const -{ +const std::string Commit::digest() const { PlTerm Digest; - int pl_ok = PlCall("digest_commit", PlTermv( - PlTerm{(long) m_view}, - PlTerm{(long) m_seq_number}, - PlString({(const char*) pre_signature().c_str()}), - PlTerm{(long) m_sender_id}, - Digest - )); - if (!pl_ok) - { - string error_msg = str( - boost::format("Unable to calculate %1% digest") - % name() - ); + int pl_ok = PlCall("digest_commit", PlTermv(PlTerm{(long)m_view}, PlTerm{(long)m_seq_number}, + PlString({(const char*)pre_signature().c_str()}), + PlTerm{(long)m_sender_id}, Digest)); + if (!pl_ok) { + string error_msg = str(boost::format("Unable to calculate %1% digest") % name()); throw(std::runtime_error(error_msg)); } - string digest{(const char *) Digest}; + string digest{(const char*)Digest}; return digest; } -std::string Commit::identify() const -{ - return str( - boost::format( "<%1%, V=%2%, N=%3%, S=%4%>" ) - % name() - % m_view - % m_seq_number - % m_sender_id - ); +std::string Commit::identify() const { + return str(boost::format("<%1%, V=%2%, N=%3%, S=%4%>") % name() % m_view % m_seq_number % m_sender_id); } // Serialization and deserialization -Commit::Commit(const Json::Value& root): -Message(root) -{ +Commit::Commit(const Json::Value& root) : Message(root) { m_view = root["payload"]["v"].asUInt(); m_seq_number = root["payload"]["n"].asUInt(); string block_signature_hex = root["payload"]["data"].asString(); this->set_pre_signature(block_signature_hex); } -std::string Commit::ToBinBuffer() const -{ +std::string Commit::ToBinBuffer() const { Json::Value payload; payload["n"] = m_seq_number; payload["v"] = m_view; @@ -143,6 +111,6 @@ std::string Commit::ToBinBuffer() const return this->FinalizeJsonRoot(payload); } -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/messages/Message.cpp b/src/fbft/messages/Message.cpp index ecb27dc..52fad1d 100644 --- a/src/fbft/messages/Message.cpp +++ b/src/fbft/messages/Message.cpp @@ -3,12 +3,12 @@ #include "messages.h" -#include #include +#include #include -#include "../../wallet/wallet.h" #include "../../utils/utils.h" +#include "../../wallet/wallet.h" using namespace std; using namespace itcoin::wallet; @@ -18,81 +18,55 @@ namespace fbft { namespace messages { Message::Message(NODE_TYPE sender_role, uint32_t sender_id) -: m_sender_role(sender_role), m_sender_id(sender_id) -{ -} + : m_sender_role(sender_role), m_sender_id(sender_id) {} Message::Message(NODE_TYPE sender_role, PlTerm Sender_id) -: m_sender_role(sender_role), m_sender_id((long) Sender_id) -{ -} + : m_sender_role(sender_role), m_sender_id((long)Sender_id) {} -Message::Message(const Json::Value& root) -{ +Message::Message(const Json::Value& root) { // This is always a replica, because we never send requests on the network m_sender_role = NODE_TYPE::REPLICA; m_sender_id = root["payload"]["sender_id"].asUInt(); m_signature = root["signature"].asString(); }; -Message::~Message() -{ -}; +Message::~Message(){}; -string Message::name() const -{ - return MSG_TYPE_AS_STRING[static_cast(this->type())]; -} +string Message::name() const { return MSG_TYPE_AS_STRING[static_cast(this->type())]; } -std::optional Message::seq_number_as_opt() const -{ - return std::nullopt; -} +std::optional Message::seq_number_as_opt() const { return std::nullopt; } -const std::string Message::digest() const -{ - throw(std::runtime_error("Message::digest() not available for message type: "+name())); +const std::string Message::digest() const { + throw(std::runtime_error("Message::digest() not available for message type: " + name())); } -bool Message::equals(const Message& other) const -{ - if (typeid(*this) != typeid(other)) return false; - if (m_sender_role != other.m_sender_role) return false; - if (m_sender_id != other.m_sender_id) return false; - if (m_signature != other.m_signature) return false; +bool Message::equals(const Message& other) const { + if (typeid(*this) != typeid(other)) + return false; + if (m_sender_role != other.m_sender_role) + return false; + if (m_sender_id != other.m_sender_id) + return false; + if (m_signature != other.m_signature) + return false; return true; } -std::string Message::signature() const { - return this->m_signature; -} +std::string Message::signature() const { return this->m_signature; } -void Message::set_signature(std::string signature) -{ - this->m_signature = signature; -} +void Message::set_signature(std::string signature) { this->m_signature = signature; } // Operations -void Message::Sign(const Wallet& wallet) -{ - wallet.AppendSignature(*this); -} +void Message::Sign(const Wallet& wallet) { wallet.AppendSignature(*this); } -bool Message::VerifySignatures(const Wallet& wallet) -{ - return wallet.VerifySignature(*this); -} +bool Message::VerifySignatures(const Wallet& wallet) { return wallet.VerifySignature(*this); } // -bool Message::operator==(const Message& other) const -{ - return this->equals(other); -} +bool Message::operator==(const Message& other) const { return this->equals(other); } -std::ostream& operator<<(std::ostream& Str, const Message& message) -{ +std::ostream& operator<<(std::ostream& Str, const Message& message) { // print something from v to str, e.g: Str << v.getX(); string message_str = message.identify(); Str << message_str; @@ -101,8 +75,7 @@ std::ostream& operator<<(std::ostream& Str, const Message& message) // Serialization and deserialization -std::string Message::FinalizeJsonRoot(Json::Value& payload) const -{ +std::string Message::FinalizeJsonRoot(Json::Value& payload) const { payload["type"] = static_cast(type()); payload["sender_id"] = m_sender_id; @@ -110,76 +83,52 @@ std::string Message::FinalizeJsonRoot(Json::Value& payload) const root["payload"] = payload; root["signature"] = signature(); - std::string result = Json::FastWriter().write(root);; + std::string result = Json::FastWriter().write(root); + ; BOOST_LOG_TRIVIAL(trace) << result; return result; } -std::string Message::ToBinBuffer() const -{ - throw(std::runtime_error("Message::ToBinBuffer() not available for message type: "+name())); +std::string Message::ToBinBuffer() const { + throw(std::runtime_error("Message::ToBinBuffer() not available for message type: " + name())); } -optional> Message::BuildFromBinBuffer(const std::string& bin_buffer) -{ +optional> Message::BuildFromBinBuffer(const std::string& bin_buffer) { optional> result = nullopt; Json::Reader reader; Json::Value root; - bool parsing_ok = reader.parse( bin_buffer, root ); - if(!parsing_ok) - { - string error_msg = str( - boost::format( "Message::BuildFromBinBuffer unable parse json: %1%." ) - % bin_buffer - ); + bool parsing_ok = reader.parse(bin_buffer, root); + if (!parsing_ok) { + string error_msg = str(boost::format("Message::BuildFromBinBuffer unable parse json: %1%.") % bin_buffer); BOOST_LOG_TRIVIAL(error) << error_msg; - } - else - { + } else { uint32_t msg_type = root["payload"]["type"].asUInt(); - if (msg_type == MSG_TYPE::COMMIT) - { + if (msg_type == MSG_TYPE::COMMIT) { result = make_unique(root); - } - else if (msg_type == MSG_TYPE::NEW_VIEW) - { + } else if (msg_type == MSG_TYPE::NEW_VIEW) { result = make_unique(root); - } - else if (msg_type == MSG_TYPE::PREPARE) - { + } else if (msg_type == MSG_TYPE::PREPARE) { result = make_unique(root); - } - else if (msg_type == MSG_TYPE::PRE_PREPARE) - { + } else if (msg_type == MSG_TYPE::PRE_PREPARE) { result = make_unique(root); - } - else if (msg_type == MSG_TYPE::VIEW_CHANGE) - { + } else if (msg_type == MSG_TYPE::VIEW_CHANGE) { result = make_unique(root); - } - else if (msg_type == MSG_TYPE::ROAST_SIGNATURE_SHARE) - { + } else if (msg_type == MSG_TYPE::ROAST_SIGNATURE_SHARE) { result = make_unique(root); - } - else if (msg_type == MSG_TYPE::ROAST_PRE_SIGNATURE) - { + } else if (msg_type == MSG_TYPE::ROAST_PRE_SIGNATURE) { result = make_unique(root); - } - else - { - string error_msg = str( - boost::format( "Message::BuildFromBinBuffer unable to identify message type in json: %1%." ) - % bin_buffer - ); + } else { + string error_msg = + str(boost::format("Message::BuildFromBinBuffer unable to identify message type in json: %1%.") % + bin_buffer); BOOST_LOG_TRIVIAL(error) << error_msg; } - } return result; } -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/messages/NewView.cpp b/src/fbft/messages/NewView.cpp index b2654c5..f821e17 100644 --- a/src/fbft/messages/NewView.cpp +++ b/src/fbft/messages/NewView.cpp @@ -3,8 +3,8 @@ #include "messages.h" -#include #include +#include #include #include @@ -22,163 +22,136 @@ namespace itcoin { namespace fbft { namespace messages { -NewView::NewView(uint32_t sender_id, - uint32_t view, - std::vector vc_messages, - std::vector ppp_messages -) -:Message(NODE_TYPE::REPLICA, sender_id) -{ +NewView::NewView(uint32_t sender_id, uint32_t view, std::vector vc_messages, + std::vector ppp_messages) + : Message(NODE_TYPE::REPLICA, sender_id) { m_view = view; m_vc_messages = vc_messages; m_ppp_messages = ppp_messages; } -NewView::NewView(PlTerm Sender_id, PlTerm V, PlTerm Nu, PlTerm Chi) -:Message(NODE_TYPE::REPLICA, Sender_id) -{ - m_view = (long) V; +NewView::NewView(PlTerm Sender_id, PlTerm V, PlTerm Nu, PlTerm Chi) : Message(NODE_TYPE::REPLICA, Sender_id) { + m_view = (long)V; // nu is an array of // when this constructor is used, we assume the replica is the primary // and the view change messages are in the log and we can retrieve them new_view_nu_t nu = NewView::nu_from_plterm(Nu); - for (new_view_nu_elem_t& nu_elem: nu) - { + for (new_view_nu_elem_t& nu_elem : nu) { uint32_t nu_n = get<0>(nu_elem); - std::string nu_digest{ get<1>(nu_elem) }; + std::string nu_digest{get<1>(nu_elem)}; ViewChange vc = ViewChange::FindByDigest(m_sender_id, nu_n, nu_digest); m_vc_messages.emplace_back(vc); } - new_view_chi_t chi = NewView::chi_from_plterm(Chi); - for (new_view_chi_elem_t& chi_elem: chi) - { + for (new_view_chi_elem_t& chi_elem : chi) { uint32_t chi_n = get<0>(chi_elem); - std::string chi_digest{ get<1>(chi_elem) }; - std::string chi_block{ get<2>(chi_elem) }; + std::string chi_digest{get<1>(chi_elem)}; + std::string chi_block{get<2>(chi_elem)}; // Further elements of chi propagate prepared requests from one view to the other - PrePrepare ppp = PrePrepare( - PlTerm((long) m_sender_id), PlTerm((long) m_view), PlTerm((long) chi_n), - PlString((const char*) chi_digest.c_str()), - PlString((const char*) chi_block.c_str()) - ); + PrePrepare ppp = + PrePrepare(PlTerm((long)m_sender_id), PlTerm((long)m_view), PlTerm((long)chi_n), + PlString((const char*)chi_digest.c_str()), PlString((const char*)chi_block.c_str())); m_ppp_messages.emplace_back(ppp); } } -NewView::~NewView() -{ -}; +NewView::~NewView(){}; -std::vector> NewView::BuildToBeSent(uint32_t replica_id) -{ +std::vector> NewView::BuildToBeSent(uint32_t replica_id) { std::vector> results{}; - PlTerm Replica_id{(long) replica_id}, V, Nu, Chi; + PlTerm Replica_id{(long)replica_id}, V, Nu, Chi; PlQuery query("msg_out_new_view", PlTermv(Replica_id, V, Nu, Chi)); - while ( query.next_solution() ) - { - std::unique_ptr msg = std::make_unique( - Replica_id, V, Nu, Chi - ); + while (query.next_solution()) { + std::unique_ptr msg = std::make_unique(Replica_id, V, Nu, Chi); results.emplace_back(std::move(msg)); } return results; } -new_view_nu_t NewView::nu_from_plterm(PlTerm Nu) -{ +new_view_nu_t NewView::nu_from_plterm(PlTerm Nu) { new_view_nu_t nu{}; - PlTail Nu_tail{Nu}; PlTerm Nu_elem; - while (Nu_tail.next(Nu_elem)) - { - if (string("[|]").compare(Nu_elem.name())!=0 || Nu_elem.arity() != 2) throw std::runtime_error("NEW_VIEW Nu element term must have arity = 2"); - uint32_t nu_n = (long) Nu_elem[1]; + PlTail Nu_tail{Nu}; + PlTerm Nu_elem; + while (Nu_tail.next(Nu_elem)) { + if (string("[|]").compare(Nu_elem.name()) != 0 || Nu_elem.arity() != 2) + throw std::runtime_error("NEW_VIEW Nu element term must have arity = 2"); + uint32_t nu_n = (long)Nu_elem[1]; PlTerm Nu_elem_2 = Nu_elem[2]; - if (string("[|]").compare(Nu_elem_2.name())!=0 || Nu_elem_2.arity() != 2) throw std::runtime_error("NEW_VIEW Nu_elem_2 term must have arity = 2"); - std::string nu_digest{ (const char*) Nu_elem_2[1] }; + if (string("[|]").compare(Nu_elem_2.name()) != 0 || Nu_elem_2.arity() != 2) + throw std::runtime_error("NEW_VIEW Nu_elem_2 term must have arity = 2"); + std::string nu_digest{(const char*)Nu_elem_2[1]}; PlTerm Nu_elem_3 = Nu_elem_2[2]; // Prolog lists end with empty list, the constant [] - assert(Nu_elem_3.type()==PL_NIL); - nu.emplace_back( make_tuple(nu_n, nu_digest) ); + assert(Nu_elem_3.type() == PL_NIL); + nu.emplace_back(make_tuple(nu_n, nu_digest)); } return nu; } -new_view_chi_t NewView::chi_from_plterm(PlTerm Chi) -{ +new_view_chi_t NewView::chi_from_plterm(PlTerm Chi) { new_view_chi_t chi{}; - PlTail Chi_tail{Chi}; PlTerm Chi_elem; - while (Chi_tail.next(Chi_elem)) - { - if (string("[|]").compare(Chi_elem.name())!=0 || Chi_elem.arity() != 2) throw std::runtime_error("SEND_NEW_VIEW Chi_elem term must have arity = 2"); - uint32_t chi_n = (long) Chi_elem[1]; + PlTail Chi_tail{Chi}; + PlTerm Chi_elem; + while (Chi_tail.next(Chi_elem)) { + if (string("[|]").compare(Chi_elem.name()) != 0 || Chi_elem.arity() != 2) + throw std::runtime_error("SEND_NEW_VIEW Chi_elem term must have arity = 2"); + uint32_t chi_n = (long)Chi_elem[1]; PlTerm Chi_elem_2 = Chi_elem[2]; - if (string("[|]").compare(Chi_elem_2.name())!=0 || Chi_elem_2.arity() != 2) throw std::runtime_error("SEND_NEW_VIEW Chi_elem_2 term must have arity = 2"); - std::string chi_digest{ (const char*) Chi_elem_2[1] }; + if (string("[|]").compare(Chi_elem_2.name()) != 0 || Chi_elem_2.arity() != 2) + throw std::runtime_error("SEND_NEW_VIEW Chi_elem_2 term must have arity = 2"); + std::string chi_digest{(const char*)Chi_elem_2[1]}; PlTerm Chi_elem_3 = Chi_elem_2[2]; - if (string("[|]").compare(Chi_elem_3.name())!=0 || Chi_elem_3.arity() != 2) throw std::runtime_error("SEND_NEW_VIEW Chi_elem_3 term must have arity = 2"); - std::string chi_block{ (const char*) Chi_elem_3[1] }; + if (string("[|]").compare(Chi_elem_3.name()) != 0 || Chi_elem_3.arity() != 2) + throw std::runtime_error("SEND_NEW_VIEW Chi_elem_3 term must have arity = 2"); + std::string chi_block{(const char*)Chi_elem_3[1]}; PlTerm Chi_elem_4 = Chi_elem_3[2]; // Prolog lists end with empty list, the constant [] - assert(Chi_elem_4.type()==PL_NIL); + assert(Chi_elem_4.type() == PL_NIL); - chi.emplace_back( make_tuple(chi_n, chi_digest, chi_block) ); + chi.emplace_back(make_tuple(chi_n, chi_digest, chi_block)); } return chi; } -PlTerm NewView::nu_as_plterm(new_view_nu_t nu) -{ +PlTerm NewView::nu_as_plterm(new_view_nu_t nu) { PlTerm result; PlTail Nu_tail(result); - for (new_view_nu_elem_t elem: nu) - { + for (new_view_nu_elem_t elem : nu) { uint32_t n = get<0>(elem); string digest = get<1>(elem); - Nu_tail.append( PlCompound("[|]", PlTermv( - PlTerm((long) n), - PlCompound("[|]", PlTermv( - PlString((const char*) digest.c_str()), - PlCompound("[]") - )) - ))); + Nu_tail.append(PlCompound( + "[|]", PlTermv(PlTerm((long)n), + PlCompound("[|]", PlTermv(PlString((const char*)digest.c_str()), PlCompound("[]")))))); } Nu_tail.close(); return result; } -PlTerm NewView::chi_as_plterm(new_view_chi_t chi) -{ +PlTerm NewView::chi_as_plterm(new_view_chi_t chi) { PlTerm result; PlTail Chi_tail(result); - for (new_view_chi_elem_t elem: chi) - { + for (new_view_chi_elem_t elem : chi) { uint32_t n = get<0>(elem); string digest = get<1>(elem); string prepared_block = get<2>(elem); - Chi_tail.append( PlCompound("[|]", PlTermv( - PlTerm((long) n), - PlCompound("[|]", PlTermv( - PlString((const char*) digest.c_str()), - PlCompound("[|]", PlTermv( - PlString((const char*) prepared_block.c_str()), - PlCompound("[]") - )) - )) - ))); + Chi_tail.append(PlCompound( + "[|]", + PlTermv( + PlTerm((long)n), + PlCompound("[|]", PlTermv(PlString((const char*)digest.c_str()), + PlCompound("[|]", PlTermv(PlString((const char*)prepared_block.c_str()), + PlCompound("[]")))))))); } Chi_tail.close(); return result; } -new_view_nu_t NewView::nu() const -{ +new_view_nu_t NewView::nu() const { new_view_nu_t result; - for (messages::ViewChange elem: m_vc_messages) - { + for (messages::ViewChange elem : m_vc_messages) { uint32_t n = elem.sender_id(); string digest = elem.digest(); result.emplace_back(make_tuple(n, digest)); @@ -186,11 +159,9 @@ new_view_nu_t NewView::nu() const return result; } -new_view_chi_t NewView::chi() const -{ +new_view_chi_t NewView::chi() const { new_view_chi_t result; - for (messages::PrePrepare elem: m_ppp_messages) - { + for (messages::PrePrepare elem : m_ppp_messages) { uint32_t n = elem.seq_number(); string digest = elem.req_digest(); string prepared_block = elem.proposed_block_hex(); @@ -199,13 +170,10 @@ new_view_chi_t NewView::chi() const return result; } -void NewView::Sign(const RoastWallet& wallet) -{ +void NewView::Sign(const RoastWallet& wallet) { // Sign the view change messages not having a signature - for(auto& vc: m_vc_messages) - { - if (vc.sender_id() == m_sender_id) - { + for (auto& vc : m_vc_messages) { + if (vc.sender_id() == m_sender_id) { wallet.AppendSignature(vc); } } @@ -213,14 +181,11 @@ void NewView::Sign(const RoastWallet& wallet) wallet.AppendSignature(*this); } -bool NewView::VerifySignatures(const RoastWallet& wallet) -{ +bool NewView::VerifySignatures(const RoastWallet& wallet) { bool result = true; - for (const messages::ViewChange& vc: m_vc_messages) - { + for (const messages::ViewChange& vc : m_vc_messages) { bool vc_valid = wallet.VerifySignature(vc); - if (!vc_valid) - { + if (!vc_valid) { BOOST_LOG_TRIVIAL(error) << "A received NEW_VIEW contains an invalid view change, and will be ignored!"; return false; } @@ -230,103 +195,82 @@ bool NewView::VerifySignatures(const RoastWallet& wallet) return result; } -bool NewView::equals(const Message& other) const -{ - if (typeid(*this) != typeid(other)) return false; +bool NewView::equals(const Message& other) const { + if (typeid(*this) != typeid(other)) + return false; auto typed_other = static_cast(other); - if (m_view != typed_other.m_view) return false; - if (m_vc_messages != typed_other.m_vc_messages) return false; - if (m_ppp_messages != typed_other.m_ppp_messages) return false; + if (m_view != typed_other.m_view) + return false; + if (m_vc_messages != typed_other.m_vc_messages) + return false; + if (m_ppp_messages != typed_other.m_ppp_messages) + return false; return Message::equals(other); } -std::unique_ptr NewView::clone() -{ +std::unique_ptr NewView::clone() { std::unique_ptr msg = std::make_unique(*this); return msg; } -const std::string NewView::digest() const -{ +const std::string NewView::digest() const { PlTerm Digest; - PlTermv args( - PlTerm((long) m_view), - NewView::nu_as_plterm(this->nu()), - NewView::chi_as_plterm(this->chi()), - Digest - ); + PlTermv args(PlTerm((long)m_view), NewView::nu_as_plterm(this->nu()), NewView::chi_as_plterm(this->chi()), + Digest); int result = PlCall("digest_new_view", args); - if (result) - { - string digest{(const char *) Digest}; + if (result) { + string digest{(const char*)Digest}; return digest; - } - else - { - string error_msg = str( - boost::format("Unable to calculate NEW_VIEW digest") - ); + } else { + string error_msg = str(boost::format("Unable to calculate NEW_VIEW digest")); throw(std::runtime_error(error_msg)); } } -std::string NewView::identify() const -{ - return str( - boost::format( "<%1%, V=%2%, S=%3%>" ) - % name() - % m_view - % m_sender_id - ); +std::string NewView::identify() const { + return str(boost::format("<%1%, V=%2%, S=%3%>") % name() % m_view % m_sender_id); } // Serialization and deserialization -NewView::NewView(const Json::Value& root): -Message(root) -{ +NewView::NewView(const Json::Value& root) : Message(root) { m_view = root["payload"]["v"].asUInt(); const Json::Value nu = root["payload"]["nu"]; - for(Json::Value nu_elem_json: nu) - { + for (Json::Value nu_elem_json : nu) { ViewChange vc_elem{nu_elem_json}; m_vc_messages.emplace_back(vc_elem); } const Json::Value chi = root["payload"]["chi"]; - for(Json::Value chi_elem_json: chi) - { + for (Json::Value chi_elem_json : chi) { PrePrepare ppp_elem{chi_elem_json}; m_ppp_messages.emplace_back(ppp_elem); } } -std::string NewView::ToBinBuffer() const -{ +std::string NewView::ToBinBuffer() const { Json::Reader reader; Json::Value payload; payload["v"] = m_view; Json::Value nu; - for(ViewChange m_vc_elem: m_vc_messages) - { + for (ViewChange m_vc_elem : m_vc_messages) { Json::Value nu_elem; - reader.parse( m_vc_elem.ToBinBuffer(), nu_elem ); + reader.parse(m_vc_elem.ToBinBuffer(), nu_elem); nu.append(nu_elem); } payload["nu"] = nu; Json::Value chi; - for(PrePrepare m_ppp_elem: m_ppp_messages) - { + for (PrePrepare m_ppp_elem : m_ppp_messages) { Json::Value chi_elem; - reader.parse( m_ppp_elem.ToBinBuffer(), chi_elem ); + reader.parse(m_ppp_elem.ToBinBuffer(), chi_elem); chi.append(chi_elem); } payload["chi"] = chi; return this->FinalizeJsonRoot(payload); } -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/messages/PrePrepare.cpp b/src/fbft/messages/PrePrepare.cpp index bf9ee49..3e612c0 100644 --- a/src/fbft/messages/PrePrepare.cpp +++ b/src/fbft/messages/PrePrepare.cpp @@ -3,15 +3,15 @@ #include "messages.h" -#include #include +#include #include #include #include -#include "config/FbftConfig.h" #include "../../utils/utils.h" +#include "config/FbftConfig.h" using namespace std; using namespace itcoin::blockchain; @@ -20,136 +20,105 @@ namespace itcoin { namespace fbft { namespace messages { -PrePrepare::PrePrepare(uint32_t sender_id, -uint32_t view, uint32_t seq_number, std::string req_digest, -CBlock proposed_block) -:Message(NODE_TYPE::REPLICA, sender_id) -{ +PrePrepare::PrePrepare(uint32_t sender_id, uint32_t view, uint32_t seq_number, std::string req_digest, + CBlock proposed_block) + : Message(NODE_TYPE::REPLICA, sender_id) { m_view = view; m_seq_number = seq_number; m_req_digest = req_digest; m_proposed_block = HexSerializableCBlock(proposed_block); } -PrePrepare::PrePrepare(PlTerm Sender_id, PlTerm V, PlTerm N, PlTerm Req_digest, -PlTerm Proposed_block) -:Message(NODE_TYPE::REPLICA, Sender_id) -{ - m_view = (long) V; - m_seq_number = (long) N; - m_req_digest = (char*) Req_digest; +PrePrepare::PrePrepare(PlTerm Sender_id, PlTerm V, PlTerm N, PlTerm Req_digest, PlTerm Proposed_block) + : Message(NODE_TYPE::REPLICA, Sender_id) { + m_view = (long)V; + m_seq_number = (long)N; + m_req_digest = (char*)Req_digest; - std::string proposed_block_hex { (char*) Proposed_block }; + std::string proposed_block_hex{(char*)Proposed_block}; this->set_proposed_block(proposed_block_hex); } -PrePrepare::~PrePrepare() -{ -}; +PrePrepare::~PrePrepare(){}; -void PrePrepare::set_proposed_block(std::string proposed_block_hex) -{ +void PrePrepare::set_proposed_block(std::string proposed_block_hex) { m_proposed_block = HexSerializableCBlock(proposed_block_hex); } -std::vector> PrePrepare::BuildToBeSent(uint32_t replica_id) -{ +std::vector> PrePrepare::BuildToBeSent(uint32_t replica_id) { std::vector> results{}; - PlTerm Replica_id{(long) replica_id}, V, N, Req_digest, Proposed_block; + PlTerm Replica_id{(long)replica_id}, V, N, Req_digest, Proposed_block; PlQuery query("msg_out_pre_prepare", PlTermv(Replica_id, V, N, Req_digest, Proposed_block)); - while ( query.next_solution() ) - { - messages::PrePrepare msg{ - Replica_id, V, N, Req_digest, Proposed_block - }; + while (query.next_solution()) { + messages::PrePrepare msg{Replica_id, V, N, Req_digest, Proposed_block}; results.emplace_back(std::move(std::make_unique(msg))); } return results; } -messages::PrePrepare PrePrepare::FindByV_N_Req(uint32_t replica_id, uint32_t v, uint32_t n, std::string req_digest) -{ - PlString Req_digest{(const char*) req_digest.c_str()}; - PlTerm Replica_id{(long) replica_id}, V, N, Proposed_block, Sender_id, Sender_sig; - int result = PlCall("msg_log_pre_prepare", PlTermv(Replica_id, V, N, Req_digest, Proposed_block, Sender_id, Sender_sig)); - if (result) - { +messages::PrePrepare PrePrepare::FindByV_N_Req(uint32_t replica_id, uint32_t v, uint32_t n, + std::string req_digest) { + PlString Req_digest{(const char*)req_digest.c_str()}; + PlTerm Replica_id{(long)replica_id}, V, N, Proposed_block, Sender_id, Sender_sig; + int result = PlCall("msg_log_pre_prepare", + PlTermv(Replica_id, V, N, Req_digest, Proposed_block, Sender_id, Sender_sig)); + if (result) { messages::PrePrepare msg{Sender_id, V, N, Req_digest, Proposed_block}; - if ((long) Sender_id != replica_id) - { - string sender_sig{(const char*) Sender_sig}; + if ((long)Sender_id != replica_id) { + string sender_sig{(const char*)Sender_sig}; msg.set_signature(sender_sig); } return msg; - } - else - { + } else { throw(std::runtime_error("Unable to find PrePrepare with V and N")); } } -bool PrePrepare::equals(const Message& other) const -{ - if (typeid(*this) != typeid(other)) return false; +bool PrePrepare::equals(const Message& other) const { + if (typeid(*this) != typeid(other)) + return false; auto typed_other = static_cast(other); - if (m_view != typed_other.m_view) return false; - if (m_seq_number != typed_other.m_seq_number) return false; - if (m_req_digest != typed_other.m_req_digest) return false; - if (m_proposed_block.GetHash() != typed_other.m_proposed_block.GetHash()) return false; + if (m_view != typed_other.m_view) + return false; + if (m_seq_number != typed_other.m_seq_number) + return false; + if (m_req_digest != typed_other.m_req_digest) + return false; + if (m_proposed_block.GetHash() != typed_other.m_proposed_block.GetHash()) + return false; return Message::equals(other); } -std::unique_ptr PrePrepare::clone() -{ +std::unique_ptr PrePrepare::clone() { std::unique_ptr msg = std::make_unique(*this); return msg; } -const std::string PrePrepare::digest() const -{ +const std::string PrePrepare::digest() const { PlTerm Digest; - int pl_ok = PlCall("digest_pre_prepare", PlTermv( - PlTerm{(long) m_view}, - PlTerm{(long) m_seq_number}, - PlString({(const char*) m_req_digest.c_str()}), - PlString({(const char*) proposed_block_hex().c_str()}), - Digest - )); - if (!pl_ok) - { - string error_msg = str( - boost::format("Unable to calculate %1% digest") - % name() - ); + int pl_ok = + PlCall("digest_pre_prepare", PlTermv(PlTerm{(long)m_view}, PlTerm{(long)m_seq_number}, + PlString({(const char*)m_req_digest.c_str()}), + PlString({(const char*)proposed_block_hex().c_str()}), Digest)); + if (!pl_ok) { + string error_msg = str(boost::format("Unable to calculate %1% digest") % name()); throw(std::runtime_error(error_msg)); } - string digest{(const char *) Digest}; + string digest{(const char*)Digest}; return digest; } -std::string PrePrepare::proposed_block_hex() const -{ - return m_proposed_block.GetHex(); -} +std::string PrePrepare::proposed_block_hex() const { return m_proposed_block.GetHex(); } -std::string PrePrepare::identify() const -{ - return str( - boost::format( "<%1%, req=%2%, V=%3%, N=%4%, S=%5%>" ) - % name() - % req_digest() - % m_view - % m_seq_number - % m_sender_id - ); +std::string PrePrepare::identify() const { + return str(boost::format("<%1%, req=%2%, V=%3%, N=%4%, S=%5%>") % name() % req_digest() % m_view % + m_seq_number % m_sender_id); } // Serialization and deserialization -PrePrepare::PrePrepare(const Json::Value& root): -Message(root) -{ +PrePrepare::PrePrepare(const Json::Value& root) : Message(root) { m_view = root["payload"]["v"].asUInt(); m_seq_number = root["payload"]["n"].asUInt(); m_req_digest = root["payload"]["req_digest"].asString(); @@ -157,8 +126,7 @@ Message(root) this->set_proposed_block(proposed_block_hex); } -std::string PrePrepare::ToBinBuffer() const -{ +std::string PrePrepare::ToBinBuffer() const { Json::Value payload; payload["n"] = m_seq_number; payload["v"] = m_view; @@ -167,6 +135,6 @@ std::string PrePrepare::ToBinBuffer() const return this->FinalizeJsonRoot(payload); } -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/messages/Prepare.cpp b/src/fbft/messages/Prepare.cpp index 42de52d..319d387 100644 --- a/src/fbft/messages/Prepare.cpp +++ b/src/fbft/messages/Prepare.cpp @@ -3,8 +3,8 @@ #include "messages.h" -#include #include +#include #include #include "config/FbftConfig.h" @@ -16,104 +16,80 @@ namespace fbft { namespace messages { Prepare::Prepare(uint32_t sender_id, uint32_t view, uint32_t seq_number, std::string req_digest) -:Message(NODE_TYPE::REPLICA, sender_id) -{ + : Message(NODE_TYPE::REPLICA, sender_id) { m_view = view; m_seq_number = seq_number; m_req_digest = req_digest; } Prepare::Prepare(PlTerm Sender_id, PlTerm V, PlTerm N, PlTerm Req_digest) -:Message(NODE_TYPE::REPLICA, Sender_id) -{ - m_view = (long) V; - m_seq_number = (long) N; - m_req_digest = (char*) Req_digest; + : Message(NODE_TYPE::REPLICA, Sender_id) { + m_view = (long)V; + m_seq_number = (long)N; + m_req_digest = (char*)Req_digest; } -Prepare::~Prepare() -{ -}; +Prepare::~Prepare(){}; -std::vector> Prepare::BuildToBeSent(uint32_t replica_id) -{ +std::vector> Prepare::BuildToBeSent(uint32_t replica_id) { std::vector> results{}; - PlTerm Replica_id{(long) replica_id}, V, N, Req_digest; + PlTerm Replica_id{(long)replica_id}, V, N, Req_digest; PlQuery query("msg_out_prepare", PlTermv(Replica_id, V, N, Req_digest)); - while ( query.next_solution() ) - { - std::unique_ptr msg = std::make_unique( - Replica_id, V, N, Req_digest - ); + while (query.next_solution()) { + std::unique_ptr msg = + std::make_unique(Replica_id, V, N, Req_digest); results.emplace_back(std::move(msg)); } return results; } -bool Prepare::equals(const Message& other) const -{ - if (typeid(*this) != typeid(other)) return false; +bool Prepare::equals(const Message& other) const { + if (typeid(*this) != typeid(other)) + return false; auto typed_other = static_cast(other); - if (m_view != typed_other.m_view) return false; - if (m_seq_number != typed_other.m_seq_number) return false; - if (m_req_digest != typed_other.m_req_digest) return false; + if (m_view != typed_other.m_view) + return false; + if (m_seq_number != typed_other.m_seq_number) + return false; + if (m_req_digest != typed_other.m_req_digest) + return false; return Message::equals(other); } -std::unique_ptr Prepare::clone() -{ +std::unique_ptr Prepare::clone() { std::unique_ptr msg = std::make_unique(*this); return msg; } -const std::string Prepare::digest() const -{ +const std::string Prepare::digest() const { PlTerm Digest; - int pl_ok = PlCall("digest_prepare", PlTermv( - PlTerm{(long) m_view}, - PlTerm{(long) m_seq_number}, - PlString({(const char*) m_req_digest.c_str()}), - PlTerm{(long) m_sender_id}, - Digest - )); - if (!pl_ok) - { - string error_msg = str( - boost::format("Unable to calculate %1% digest") - % name() - ); + int pl_ok = PlCall("digest_prepare", PlTermv(PlTerm{(long)m_view}, PlTerm{(long)m_seq_number}, + PlString({(const char*)m_req_digest.c_str()}), + PlTerm{(long)m_sender_id}, Digest)); + if (!pl_ok) { + string error_msg = str(boost::format("Unable to calculate %1% digest") % name()); throw(std::runtime_error(error_msg)); } - string digest{(const char *) Digest}; + string digest{(const char*)Digest}; return digest; } -std::string Prepare::identify() const -{ - return str( - boost::format( "<%1%, Req=%2%, V=%3%, N=%4%, S=%5%>" ) - % name() - % m_req_digest - % m_view - % m_seq_number - % m_sender_id - ); +std::string Prepare::identify() const { + return str(boost::format("<%1%, Req=%2%, V=%3%, N=%4%, S=%5%>") % name() % m_req_digest % m_view % + m_seq_number % m_sender_id); } // Serialization and deserialization -Prepare::Prepare(const Json::Value& root): -Message(root) -{ +Prepare::Prepare(const Json::Value& root) : Message(root) { m_view = root["payload"]["v"].asUInt(); m_seq_number = root["payload"]["n"].asUInt(); m_req_digest = root["payload"]["req_digest"].asString(); } -std::string Prepare::ToBinBuffer() const -{ +std::string Prepare::ToBinBuffer() const { Json::Value payload; payload["n"] = m_seq_number; payload["v"] = m_view; @@ -121,6 +97,6 @@ std::string Prepare::ToBinBuffer() const return this->FinalizeJsonRoot(payload); } -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/messages/Request.cpp b/src/fbft/messages/Request.cpp index d111ec5..ef249eb 100644 --- a/src/fbft/messages/Request.cpp +++ b/src/fbft/messages/Request.cpp @@ -14,108 +14,75 @@ namespace itcoin { namespace fbft { namespace messages { -Request::Request(): -Message(NODE_TYPE::CLIENT, 9999) -{ +Request::Request() : Message(NODE_TYPE::CLIENT, 9999) { m_target_block_time = 0; m_timestamp = 0; } -Request::Request(uint32_t genesis_block_timestamp, uint32_t target_block_time, uint32_t timestamp): -Message(NODE_TYPE::CLIENT, 9999) -{ +Request::Request(uint32_t genesis_block_timestamp, uint32_t target_block_time, uint32_t timestamp) + : Message(NODE_TYPE::CLIENT, 9999) { m_genesis_block_timestamp = genesis_block_timestamp; m_target_block_time = target_block_time; m_timestamp = timestamp; } -Request::~Request() -{ -}; +Request::~Request(){}; -messages::Request Request::FindByDigest(uint32_t replica_id, std::string req_digest) -{ +messages::Request Request::FindByDigest(uint32_t replica_id, std::string req_digest) { messages::Request msg; bool result = TryFindByDigest(replica_id, req_digest, msg); - if (result) - { + if (result) { return msg; - } - else - { - string error_msg = str( - boost::format("Unable to find REQUEST with digest %1%") - % req_digest - ); + } else { + string error_msg = str(boost::format("Unable to find REQUEST with digest %1%") % req_digest); throw(std::runtime_error(error_msg)); } } -bool Request::TryFindByDigest(uint32_t replica_id, const std::string req_digest, messages::Request& out_request) -{ - PlString Req_digest{(const char*) req_digest.c_str()}; - PlTerm Replica_id{(long) replica_id}, Req_timestamp, Genesis_block_time, Target_block_time; - int result = - PlCall("msg_log_request", PlTermv(Replica_id, Req_digest, Req_timestamp)) && - PlCall("nb_getval", PlTermv(PlTerm("target_block_time"), Target_block_time)) && - PlCall("nb_getval", PlTermv(PlTerm("genesis_block_timestamp"), Genesis_block_time)); - if (result) - { - uint32_t genesis_block_time = (long) Genesis_block_time; - uint32_t target_block_time = (long) Target_block_time; - uint32_t req_timestamp = (long) Req_timestamp; +bool Request::TryFindByDigest(uint32_t replica_id, const std::string req_digest, + messages::Request& out_request) { + PlString Req_digest{(const char*)req_digest.c_str()}; + PlTerm Replica_id{(long)replica_id}, Req_timestamp, Genesis_block_time, Target_block_time; + int result = PlCall("msg_log_request", PlTermv(Replica_id, Req_digest, Req_timestamp)) && + PlCall("nb_getval", PlTermv(PlTerm("target_block_time"), Target_block_time)) && + PlCall("nb_getval", PlTermv(PlTerm("genesis_block_timestamp"), Genesis_block_time)); + if (result) { + uint32_t genesis_block_time = (long)Genesis_block_time; + uint32_t target_block_time = (long)Target_block_time; + uint32_t req_timestamp = (long)Req_timestamp; out_request = messages::Request{genesis_block_time, target_block_time, req_timestamp}; return true; - } - else - { - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("Unable to find REQUEST with digest %1%") - % req_digest - ); + } else { + BOOST_LOG_TRIVIAL(debug) << str(boost::format("Unable to find REQUEST with digest %1%") % req_digest); return false; } } - -bool Request::equals(const Message& other) const -{ - if (typeid(*this) != typeid(other)) return false; +bool Request::equals(const Message& other) const { + if (typeid(*this) != typeid(other)) + return false; auto typed_other = static_cast(other); - if (m_timestamp != typed_other.m_timestamp) return false; + if (m_timestamp != typed_other.m_timestamp) + return false; return Message::equals(other); } -std::unique_ptr Request::clone() -{ +std::unique_ptr Request::clone() { std::unique_ptr msg = std::make_unique(*this); return msg; } -uint32_t Request::height() const -{ - return (m_timestamp-m_genesis_block_timestamp) / m_target_block_time; -} +uint32_t Request::height() const { return (m_timestamp - m_genesis_block_timestamp) / m_target_block_time; } -const std::string Request::digest() const -{ - return str( - boost::format( "(H=%1%, T=%2%)" ) - % height() - % m_timestamp - ); +const std::string Request::digest() const { + return str(boost::format("(H=%1%, T=%2%)") % height() % m_timestamp); } -std::string Request::identify() const -{ - return str( - boost::format( "Request digest=%1%, timestamp=%3%" ) - % digest() - % m_timestamp - ); +std::string Request::identify() const { + return str(boost::format("Request digest=%1%, timestamp=%3%") % digest() % m_timestamp); } -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/messages/RoastPreSignature.cpp b/src/fbft/messages/RoastPreSignature.cpp index dc9b118..2fa0a6e 100644 --- a/src/fbft/messages/RoastPreSignature.cpp +++ b/src/fbft/messages/RoastPreSignature.cpp @@ -3,8 +3,8 @@ #include "messages.h" -#include #include +#include #include #include @@ -22,118 +22,88 @@ namespace itcoin { namespace fbft { namespace messages { -RoastPreSignature::RoastPreSignature(uint32_t sender_id, vector signers, string pre_signature): -Message(NODE_TYPE::REPLICA, sender_id) -{ +RoastPreSignature::RoastPreSignature(uint32_t sender_id, vector signers, string pre_signature) + : Message(NODE_TYPE::REPLICA, sender_id) { m_signers = signers; m_pre_signature = pre_signature; } -RoastPreSignature::RoastPreSignature(PlTerm Sender_id, PlTerm Signers, PlTerm Pre_signature): -Message(NODE_TYPE::REPLICA, Sender_id) -{ - PlTail SignersTail{Signers}; PlTerm SignerElem; - while(SignersTail.next(SignerElem)) - { - m_signers.emplace_back((long) SignerElem); +RoastPreSignature::RoastPreSignature(PlTerm Sender_id, PlTerm Signers, PlTerm Pre_signature) + : Message(NODE_TYPE::REPLICA, Sender_id) { + PlTail SignersTail{Signers}; + PlTerm SignerElem; + while (SignersTail.next(SignerElem)) { + m_signers.emplace_back((long)SignerElem); } - m_pre_signature = std::string{(const char*) Pre_signature}; + m_pre_signature = std::string{(const char*)Pre_signature}; } -RoastPreSignature::~RoastPreSignature() -{ -} +RoastPreSignature::~RoastPreSignature() {} -std::vector> RoastPreSignature::BuildToBeSent(uint32_t replica_id) -{ +std::vector> +RoastPreSignature::BuildToBeSent(uint32_t replica_id) { std::vector> results{}; - PlTerm Replica_id{(long) replica_id}, Signers, Pre_signature; + PlTerm Replica_id{(long)replica_id}, Signers, Pre_signature; PlQuery query("msg_out_roast_pre_signature", PlTermv(Replica_id, Signers, Pre_signature)); - while ( query.next_solution() ) - { - std::unique_ptr msg = std::make_unique( - Replica_id, Signers, Pre_signature - ); + while (query.next_solution()) { + std::unique_ptr msg = + std::make_unique(Replica_id, Signers, Pre_signature); results.emplace_back(std::move(msg)); } return results; } -std::unique_ptr RoastPreSignature::clone() -{ +std::unique_ptr RoastPreSignature::clone() { std::unique_ptr msg = std::make_unique(*this); return msg; } -const std::string RoastPreSignature::digest() const -{ +const std::string RoastPreSignature::digest() const { PlTerm Digest; - PlTermv args( - signers_as_plterm(), - PlString((const char *) m_pre_signature.c_str()), - PlTerm{(long) m_sender_id}, - Digest - ); + PlTermv args(signers_as_plterm(), PlString((const char*)m_pre_signature.c_str()), PlTerm{(long)m_sender_id}, + Digest); int result = PlCall("digest_roast_pre_signature", args); - if (result) - { - string digest{(const char *) Digest}; + if (result) { + string digest{(const char*)Digest}; return digest; - } - else - { - string error_msg = str( - boost::format("Unable to calculate digest of %1%") - % identify() - ); + } else { + string error_msg = str(boost::format("Unable to calculate digest of %1%") % identify()); throw(std::runtime_error(error_msg)); } } -bool RoastPreSignature::equals(const Message& other) const -{ - if (typeid(*this) != typeid(other)) return false; +bool RoastPreSignature::equals(const Message& other) const { + if (typeid(*this) != typeid(other)) + return false; auto typed_other = static_cast(other); - if (m_signers != typed_other.m_signers) return false; - if (m_pre_signature != typed_other.m_pre_signature) return false; + if (m_signers != typed_other.m_signers) + return false; + if (m_pre_signature != typed_other.m_pre_signature) + return false; return Message::equals(other); } -std::string RoastPreSignature::identify() const -{ +std::string RoastPreSignature::identify() const { std::stringstream signers_stream; std::copy(m_signers.begin(), m_signers.end(), std::ostream_iterator(signers_stream, ",")); string signers_str = signers_stream.str(); signers_str.pop_back(); - return str( - boost::format( "<%1%, Signers=[%2%], Pre_sig=%3%, S=%4%>" ) - % name() - % signers_str - % m_pre_signature.substr(0,5) - % m_sender_id - ); + return str(boost::format("<%1%, Signers=[%2%], Pre_sig=%3%, S=%4%>") % name() % signers_str % + m_pre_signature.substr(0, 5) % m_sender_id); } -std::string RoastPreSignature::pre_signature() const -{ - return m_pre_signature; -} +std::string RoastPreSignature::pre_signature() const { return m_pre_signature; } -std::vector RoastPreSignature::signers() const -{ - return m_signers; -} +std::vector RoastPreSignature::signers() const { return m_signers; } -PlTerm RoastPreSignature::signers_as_plterm() const -{ +PlTerm RoastPreSignature::signers_as_plterm() const { PlTerm result; PlTail Pi_tail(result); - for (uint32_t s: m_signers) - { - Pi_tail.append( PlTerm((long) s) ); + for (uint32_t s : m_signers) { + Pi_tail.append(PlTerm((long)s)); } Pi_tail.close(); return result; @@ -141,32 +111,27 @@ PlTerm RoastPreSignature::signers_as_plterm() const // Serialization and deserialization -RoastPreSignature::RoastPreSignature(const Json::Value& root): -Message(root) -{ +RoastPreSignature::RoastPreSignature(const Json::Value& root) : Message(root) { m_pre_signature = root["payload"]["pre_signature"].asString(); const Json::Value signers = root["payload"]["signers"]; m_signers.reserve(signers.size()); - for(Json::Value signr_elem_json: signers) - { + for (Json::Value signr_elem_json : signers) { uint32_t signr = signr_elem_json.asUInt(); m_signers.emplace_back(signr); } } -std::string RoastPreSignature::ToBinBuffer() const -{ +std::string RoastPreSignature::ToBinBuffer() const { Json::Value payload; payload["pre_signature"] = m_pre_signature; Json::Value signers; - for(uint32_t signr: m_signers) - { + for (uint32_t signr : m_signers) { signers.append(signr); } payload["signers"] = signers; return this->FinalizeJsonRoot(payload); } -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/messages/RoastSignatureShare.cpp b/src/fbft/messages/RoastSignatureShare.cpp index 3b1fe9e..8bc8552 100644 --- a/src/fbft/messages/RoastSignatureShare.cpp +++ b/src/fbft/messages/RoastSignatureShare.cpp @@ -3,8 +3,8 @@ #include "messages.h" -#include #include +#include #include #include @@ -22,119 +22,91 @@ namespace itcoin { namespace fbft { namespace messages { -RoastSignatureShare::RoastSignatureShare(uint32_t sender_id, string signature_share, string next_pre_signature_share): -Message(NODE_TYPE::REPLICA, sender_id) -{ +RoastSignatureShare::RoastSignatureShare(uint32_t sender_id, string signature_share, + string next_pre_signature_share) + : Message(NODE_TYPE::REPLICA, sender_id) { m_signature_share = signature_share; m_next_pre_signature_share = next_pre_signature_share; } -RoastSignatureShare::RoastSignatureShare(PlTerm Sender_id, PlTerm Signature_share, PlTerm Next_pre_signature_share): -Message(NODE_TYPE::REPLICA, Sender_id) -{ - m_signature_share = std::string{(const char*) Signature_share}; - m_next_pre_signature_share = std::string{(const char*) Next_pre_signature_share}; +RoastSignatureShare::RoastSignatureShare(PlTerm Sender_id, PlTerm Signature_share, + PlTerm Next_pre_signature_share) + : Message(NODE_TYPE::REPLICA, Sender_id) { + m_signature_share = std::string{(const char*)Signature_share}; + m_next_pre_signature_share = std::string{(const char*)Next_pre_signature_share}; } -RoastSignatureShare::~RoastSignatureShare() -{ -} +RoastSignatureShare::~RoastSignatureShare() {} -std::vector> RoastSignatureShare::BuildToBeSent(uint32_t replica_id) -{ +std::vector> +RoastSignatureShare::BuildToBeSent(uint32_t replica_id) { std::vector> results{}; - PlTerm Replica_id{(long) replica_id}, Signature_share, Next_pre_signature_share; - PlQuery query("msg_out_roast_signature_share", PlTermv(Replica_id, Signature_share, Next_pre_signature_share)); - while ( query.next_solution() ) - { + PlTerm Replica_id{(long)replica_id}, Signature_share, Next_pre_signature_share; + PlQuery query("msg_out_roast_signature_share", + PlTermv(Replica_id, Signature_share, Next_pre_signature_share)); + while (query.next_solution()) { std::unique_ptr msg = std::make_unique( - Replica_id, Signature_share, Next_pre_signature_share - ); + Replica_id, Signature_share, Next_pre_signature_share); results.emplace_back(std::move(msg)); } return results; } -std::unique_ptr RoastSignatureShare::clone() -{ +std::unique_ptr RoastSignatureShare::clone() { std::unique_ptr msg = std::make_unique(*this); return msg; } -const std::string RoastSignatureShare::digest() const -{ +const std::string RoastSignatureShare::digest() const { PlTerm Digest; - PlTermv args( - PlString((const char *) m_signature_share.c_str()), - PlString((const char *) m_next_pre_signature_share.c_str()), - PlTerm{(long) m_sender_id}, - Digest - ); + PlTermv args(PlString((const char*)m_signature_share.c_str()), + PlString((const char*)m_next_pre_signature_share.c_str()), PlTerm{(long)m_sender_id}, Digest); int result = PlCall("digest_roast_signature_share", args); - if (result) - { - string digest{(const char *) Digest}; + if (result) { + string digest{(const char*)Digest}; return digest; - } - else - { - string error_msg = str( - boost::format("Unable to calculate digest of %1%") - % identify() - ); + } else { + string error_msg = str(boost::format("Unable to calculate digest of %1%") % identify()); throw(std::runtime_error(error_msg)); } } -bool RoastSignatureShare::equals(const Message& other) const -{ - if (typeid(*this) != typeid(other)) return false; +bool RoastSignatureShare::equals(const Message& other) const { + if (typeid(*this) != typeid(other)) + return false; auto typed_other = static_cast(other); - if (m_signature_share != typed_other.m_signature_share) return false; - if (m_next_pre_signature_share != typed_other.m_next_pre_signature_share) return false; + if (m_signature_share != typed_other.m_signature_share) + return false; + if (m_next_pre_signature_share != typed_other.m_next_pre_signature_share) + return false; return Message::equals(other); } -std::string RoastSignatureShare::identify() const -{ - return str( - boost::format( "<%1%, Sig_share=%2%, Next_pre_sig_share=%3%, S=%4%>" ) - % name() - % m_signature_share.substr(0,5) - % m_next_pre_signature_share.substr(0,5) - % m_sender_id - ); +std::string RoastSignatureShare::identify() const { + return str(boost::format("<%1%, Sig_share=%2%, Next_pre_sig_share=%3%, S=%4%>") % name() % + m_signature_share.substr(0, 5) % m_next_pre_signature_share.substr(0, 5) % m_sender_id); } -std::string RoastSignatureShare::signature_share() const -{ - return m_signature_share; -} +std::string RoastSignatureShare::signature_share() const { return m_signature_share; } -std::string RoastSignatureShare::next_pre_signature_share() const -{ - return m_next_pre_signature_share; -} +std::string RoastSignatureShare::next_pre_signature_share() const { return m_next_pre_signature_share; } // Serialization and deserialization -RoastSignatureShare::RoastSignatureShare(const Json::Value& root): -Message(root) -{ +RoastSignatureShare::RoastSignatureShare(const Json::Value& root) : Message(root) { m_signature_share = root["payload"]["signature_share"].asString(); m_next_pre_signature_share = root["payload"]["next_pre_sig_share"].asString(); } -std::string RoastSignatureShare::ToBinBuffer() const -{ +std::string RoastSignatureShare::ToBinBuffer() const { Json::Value payload; payload["signature_share"] = m_signature_share; payload["next_pre_sig_share"] = m_next_pre_signature_share; return this->FinalizeJsonRoot(payload); } -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/messages/ViewChange.cpp b/src/fbft/messages/ViewChange.cpp index a3e5d5e..ac3daff 100644 --- a/src/fbft/messages/ViewChange.cpp +++ b/src/fbft/messages/ViewChange.cpp @@ -17,13 +17,9 @@ namespace itcoin { namespace fbft { namespace messages { -ViewChange::ViewChange(uint32_t sender_id, - uint32_t view, uint32_t hi, - string c, - view_change_prepared_t pi, - view_change_pre_prepared_t qi) -:Message(NODE_TYPE::REPLICA, sender_id) -{ +ViewChange::ViewChange(uint32_t sender_id, uint32_t view, uint32_t hi, string c, view_change_prepared_t pi, + view_change_pre_prepared_t qi) + : Message(NODE_TYPE::REPLICA, sender_id) { m_view = view; m_hi = hi; m_c = c; @@ -31,226 +27,187 @@ ViewChange::ViewChange(uint32_t sender_id, m_qi = qi; } -ViewChange::ViewChange(PlTerm Sender_id, - PlTerm V, PlTerm Hi, PlTerm C, PlTerm Pi, PlTerm Qi) -:Message(NODE_TYPE::REPLICA, Sender_id) -{ - m_view = (long) V; - m_hi = (long) Hi; +ViewChange::ViewChange(PlTerm Sender_id, PlTerm V, PlTerm Hi, PlTerm C, PlTerm Pi, PlTerm Qi) + : Message(NODE_TYPE::REPLICA, Sender_id) { + m_view = (long)V; + m_hi = (long)Hi; // Parse value of C - m_c = std::string{(const char*) C}; - - PlTail P_tail{Pi}; PlTerm P_elem; - while (P_tail.next(P_elem)) - { - if (string("[|]").compare(P_elem.name())!=0 || P_elem.arity() != 2) throw std::runtime_error("VIEW_CHANGE message P_elem term must have arity = 2"); - uint32_t p_n = (long) P_elem[1]; + m_c = std::string{(const char*)C}; + + PlTail P_tail{Pi}; + PlTerm P_elem; + while (P_tail.next(P_elem)) { + if (string("[|]").compare(P_elem.name()) != 0 || P_elem.arity() != 2) + throw std::runtime_error("VIEW_CHANGE message P_elem term must have arity = 2"); + uint32_t p_n = (long)P_elem[1]; PlTerm P_elem_2 = P_elem[2]; - if (string("[|]").compare(P_elem_2.name())!=0 || P_elem_2.arity() != 2) throw std::runtime_error("VIEW_CHANGE message P_elem_2 term must have arity = 2"); - std::string p_req_digest{ (char*) P_elem_2[1] }; + if (string("[|]").compare(P_elem_2.name()) != 0 || P_elem_2.arity() != 2) + throw std::runtime_error("VIEW_CHANGE message P_elem_2 term must have arity = 2"); + std::string p_req_digest{(char*)P_elem_2[1]}; PlTerm P_elem_3 = P_elem_2[2]; - if (string("[|]").compare(P_elem_3.name())!=0 || P_elem_3.arity() != 2) throw std::runtime_error("VIEW_CHANGE message P_elem_3 term must have arity = 2"); - uint32_t p_v = (long) P_elem_3[1]; + if (string("[|]").compare(P_elem_3.name()) != 0 || P_elem_3.arity() != 2) + throw std::runtime_error("VIEW_CHANGE message P_elem_3 term must have arity = 2"); + uint32_t p_v = (long)P_elem_3[1]; PlTerm P_elem_4 = P_elem_3[2]; - assert(P_elem_4.type()==PL_NIL); // Prolog lists end with empty list, the constant [] + assert(P_elem_4.type() == PL_NIL); // Prolog lists end with empty list, the constant [] - m_pi.emplace_back( make_tuple(p_n, p_req_digest, p_v) ); + m_pi.emplace_back(make_tuple(p_n, p_req_digest, p_v)); } - PlTail Q_tail{Qi}; PlTerm Q_elem; - while (Q_tail.next(Q_elem)) - { - if (string("[|]").compare(Q_elem.name())!=0 || Q_elem.arity() != 2) throw std::runtime_error("VIEW_CHANGE message Q_elem term must have arity = 2"); - uint32_t q_n = (long) Q_elem[1]; + PlTail Q_tail{Qi}; + PlTerm Q_elem; + while (Q_tail.next(Q_elem)) { + if (string("[|]").compare(Q_elem.name()) != 0 || Q_elem.arity() != 2) + throw std::runtime_error("VIEW_CHANGE message Q_elem term must have arity = 2"); + uint32_t q_n = (long)Q_elem[1]; PlTerm Q_elem_2 = Q_elem[2]; - if (string("[|]").compare(Q_elem_2.name())!=0 || Q_elem_2.arity() != 2) throw std::runtime_error("VIEW_CHANGE message Q_elem_2 term must have arity = 2"); - std::string q_req_digest{ (char*) Q_elem_2[1] }; + if (string("[|]").compare(Q_elem_2.name()) != 0 || Q_elem_2.arity() != 2) + throw std::runtime_error("VIEW_CHANGE message Q_elem_2 term must have arity = 2"); + std::string q_req_digest{(char*)Q_elem_2[1]}; PlTerm Q_elem_3 = Q_elem_2[2]; - if (string("[|]").compare(Q_elem_3.name())!=0 || Q_elem_3.arity() != 2) throw std::runtime_error("VIEW_CHANGE message Q_elem_3 term must have arity = 2"); - std::string q_prep_block{ (char*) Q_elem_3[1] }; + if (string("[|]").compare(Q_elem_3.name()) != 0 || Q_elem_3.arity() != 2) + throw std::runtime_error("VIEW_CHANGE message Q_elem_3 term must have arity = 2"); + std::string q_prep_block{(char*)Q_elem_3[1]}; PlTerm Q_elem_4 = Q_elem_3[2]; - if (string("[|]").compare(Q_elem_4.name())!=0 || Q_elem_4.arity() != 2) throw std::runtime_error("VIEW_CHANGE message Q_elem_4 term must have arity = 2"); - uint32_t q_v = (long) Q_elem_4[1]; + if (string("[|]").compare(Q_elem_4.name()) != 0 || Q_elem_4.arity() != 2) + throw std::runtime_error("VIEW_CHANGE message Q_elem_4 term must have arity = 2"); + uint32_t q_v = (long)Q_elem_4[1]; PlTerm Q_elem_5 = Q_elem_4[2]; // Prolog lists end with empty list, the constant [] - assert(Q_elem_5.type()==PL_NIL); + assert(Q_elem_5.type() == PL_NIL); - m_qi.emplace_back( make_tuple(q_n, q_req_digest, q_prep_block, q_v) ); + m_qi.emplace_back(make_tuple(q_n, q_req_digest, q_prep_block, q_v)); } } -ViewChange::~ViewChange() -{ -}; +ViewChange::~ViewChange(){}; -std::vector> ViewChange::BuildToBeSent(uint32_t replica_id) -{ +std::vector> ViewChange::BuildToBeSent(uint32_t replica_id) { std::vector> results{}; - PlTerm Replica_id{(long) replica_id}, V, Hi, C, Pi, Qi; + PlTerm Replica_id{(long)replica_id}, V, Hi, C, Pi, Qi; PlQuery query("msg_out_view_change", PlTermv(Replica_id, V, Hi, C, Pi, Qi)); - while ( query.next_solution() ) - { - std::unique_ptr msg = std::make_unique( - Replica_id, V, Hi, C, Pi, Qi - ); + while (query.next_solution()) { + std::unique_ptr msg = + std::make_unique(Replica_id, V, Hi, C, Pi, Qi); results.emplace_back(std::move(msg)); } return results; } -messages::ViewChange ViewChange::FindByDigest(uint32_t replica_id, uint32_t sender_id, std::string digest) -{ - PlString Vc_digest{(const char*) digest.c_str()}; - PlTerm Replica_id{(long) replica_id}, V, Hi, C, Pi, Qi, Sender_id{(long) sender_id}, Sender_sig; - int result = PlCall("msg_log_view_change", PlTermv(Replica_id, Vc_digest, V, Hi, C, Pi, Qi, Sender_id, Sender_sig)); - if (result) - { +messages::ViewChange ViewChange::FindByDigest(uint32_t replica_id, uint32_t sender_id, std::string digest) { + PlString Vc_digest{(const char*)digest.c_str()}; + PlTerm Replica_id{(long)replica_id}, V, Hi, C, Pi, Qi, Sender_id{(long)sender_id}, Sender_sig; + int result = + PlCall("msg_log_view_change", PlTermv(Replica_id, Vc_digest, V, Hi, C, Pi, Qi, Sender_id, Sender_sig)); + if (result) { messages::ViewChange msg{Sender_id, V, Hi, C, Pi, Qi}; - if ((long) Sender_id != replica_id) - { - string sender_sig{(const char*) Sender_sig}; + if ((long)Sender_id != replica_id) { + string sender_sig{(const char*)Sender_sig}; msg.set_signature(sender_sig); } return msg; - } - else - { - string error_msg = str( - boost::format("Unable to find VIEW_CHANGE with digest %1%") - % digest - ); + } else { + string error_msg = str(boost::format("Unable to find VIEW_CHANGE with digest %1%") % digest); throw(std::runtime_error(error_msg)); } } -bool ViewChange::equals(const Message& other) const -{ - if (typeid(*this) != typeid(other)) return false; +bool ViewChange::equals(const Message& other) const { + if (typeid(*this) != typeid(other)) + return false; auto typed_other = static_cast(other); - if (m_view != typed_other.m_view) return false; - if (m_hi != typed_other.m_hi) return false; - if (m_c != typed_other.m_c) return false; - if (m_pi != typed_other.m_pi) return false; - if (m_qi != typed_other.m_qi) return false; + if (m_view != typed_other.m_view) + return false; + if (m_hi != typed_other.m_hi) + return false; + if (m_c != typed_other.m_c) + return false; + if (m_pi != typed_other.m_pi) + return false; + if (m_qi != typed_other.m_qi) + return false; return Message::equals(other); } -std::unique_ptr ViewChange::clone() -{ +std::unique_ptr ViewChange::clone() { std::unique_ptr msg = std::make_unique(*this); return msg; } -PlTerm ViewChange::pi_as_plterm() const -{ +PlTerm ViewChange::pi_as_plterm() const { PlTerm result; PlTail Pi_tail(result); - for (messages::view_change_prepared_elem_t elem: m_pi) - { + for (messages::view_change_prepared_elem_t elem : m_pi) { uint32_t n = get<0>(elem); string digest = get<1>(elem); uint32_t v = get<2>(elem); - Pi_tail.append( PlCompound("[|]", PlTermv( - PlTerm((long) n), - PlCompound("[|]", PlTermv( - PlString((const char*) digest.c_str()), - PlCompound("[|]", PlTermv( - PlTerm((long) v), - PlCompound("[]") - )) - )) - ))); + Pi_tail.append(PlCompound( + "[|]", + PlTermv(PlTerm((long)n), + PlCompound("[|]", PlTermv(PlString((const char*)digest.c_str()), + PlCompound("[|]", PlTermv(PlTerm((long)v), PlCompound("[]")))))))); } Pi_tail.close(); return result; } -PlTerm ViewChange::qi_as_plterm() const -{ +PlTerm ViewChange::qi_as_plterm() const { PlTerm result; PlTail Qi_tail(result); - for (messages::view_change_pre_prepared_elem_t elem: m_qi) - { + for (messages::view_change_pre_prepared_elem_t elem : m_qi) { uint32_t n = get<0>(elem); string digest = get<1>(elem); string prep_block = get<2>(elem); uint32_t v = get<3>(elem); - Qi_tail.append( PlCompound("[|]", PlTermv( - PlTerm((long) n), - PlCompound("[|]", PlTermv( - PlString((const char*) digest.c_str()), - PlCompound("[|]", PlTermv( - PlString((const char*) prep_block.c_str()), - PlCompound("[|]", PlTermv( - PlTerm((long) v), - PlCompound("[]") - )) - )) - )) - ))); + Qi_tail.append(PlCompound( + "[|]", + PlTermv( + PlTerm((long)n), + PlCompound("[|]", + PlTermv(PlString((const char*)digest.c_str()), + PlCompound("[|]", PlTermv(PlString((const char*)prep_block.c_str()), + PlCompound("[|]", PlTermv(PlTerm((long)v), + PlCompound("[]")))))))))); } Qi_tail.close(); return result; } -const std::string ViewChange::digest() const -{ +const std::string ViewChange::digest() const { PlTerm Digest; - PlTermv args( - PlTerm((long) m_view), - PlTerm((long) m_hi), - PlString((const char *) m_c.c_str()), - this->pi_as_plterm(), - this->qi_as_plterm(), - PlTerm((long) m_sender_id), - Digest - ); + PlTermv args(PlTerm((long)m_view), PlTerm((long)m_hi), PlString((const char*)m_c.c_str()), + this->pi_as_plterm(), this->qi_as_plterm(), PlTerm((long)m_sender_id), Digest); int result = PlCall("digest_view_change", args); - if (result) - { - string digest{(const char *) Digest}; + if (result) { + string digest{(const char*)Digest}; return digest; - } - else - { - string error_msg = str( - boost::format("Unable to calculate VIEW_CHANGE digest") - ); + } else { + string error_msg = str(boost::format("Unable to calculate VIEW_CHANGE digest")); throw(std::runtime_error(error_msg)); } } -std::string ViewChange::identify() const -{ - return str( - boost::format( "<%1%, V=%2%, Hi=%3%, S=%4%>" ) - % name() - % m_view - % m_hi - % m_sender_id - ); +std::string ViewChange::identify() const { + return str(boost::format("<%1%, V=%2%, Hi=%3%, S=%4%>") % name() % m_view % m_hi % m_sender_id); } // Serialization and deserialization -ViewChange::ViewChange(const Json::Value& root): -Message(root) -{ +ViewChange::ViewChange(const Json::Value& root) : Message(root) { m_view = root["payload"]["v"].asUInt(); m_hi = root["payload"]["hi"].asUInt(); m_c = root["payload"]["c"].asString(); const Json::Value pi = root["payload"]["pi"]; m_pi.reserve(pi.size()); - for(Json::Value pi_elem_json: pi) - { + for (Json::Value pi_elem_json : pi) { uint32_t n = pi_elem_json["n"].asUInt(); string req_digest = pi_elem_json["req_digest"].asString(); uint32_t v = pi_elem_json["v"].asUInt(); @@ -260,45 +217,39 @@ Message(root) const Json::Value qi = root["payload"]["qi"]; m_qi.reserve(qi.size()); - std::transform( - qi.begin(), qi.end(), - std::back_inserter(m_qi), [](const auto& e) { - uint32_t n = e["n"].asUInt(); - string req_digest = e["req_digest"].asString(); - string data = e["data"].asString(); - uint32_t v = e["v"].asUInt(); - view_change_pre_prepared_elem_t qi_elem = make_tuple(n, req_digest, data, v); - return qi_elem; - } - ); + std::transform(qi.begin(), qi.end(), std::back_inserter(m_qi), [](const auto& e) { + uint32_t n = e["n"].asUInt(); + string req_digest = e["req_digest"].asString(); + string data = e["data"].asString(); + uint32_t v = e["v"].asUInt(); + view_change_pre_prepared_elem_t qi_elem = make_tuple(n, req_digest, data, v); + return qi_elem; + }); } -std::string ViewChange::ToBinBuffer() const -{ +std::string ViewChange::ToBinBuffer() const { Json::Value payload; payload["v"] = m_view; payload["hi"] = m_hi; payload["c"] = m_c; Json::Value pi; - for(view_change_prepared_elem_t m_pi_elem: m_pi) - { + for (view_change_prepared_elem_t m_pi_elem : m_pi) { Json::Value pi_elem; - pi_elem["n"]=get<0>(m_pi_elem); - pi_elem["req_digest"]=get<1>(m_pi_elem); - pi_elem["v"]=get<2>(m_pi_elem); + pi_elem["n"] = get<0>(m_pi_elem); + pi_elem["req_digest"] = get<1>(m_pi_elem); + pi_elem["v"] = get<2>(m_pi_elem); pi.append(pi_elem); } payload["pi"] = pi; Json::Value qi; - for(view_change_pre_prepared_elem_t m_qi_elem: m_qi) - { + for (view_change_pre_prepared_elem_t m_qi_elem : m_qi) { Json::Value qi_elem; - qi_elem["n"]=get<0>(m_qi_elem); - qi_elem["req_digest"]=get<1>(m_qi_elem); - qi_elem["data"]=get<2>(m_qi_elem); - qi_elem["v"]=get<3>(m_qi_elem); + qi_elem["n"] = get<0>(m_qi_elem); + qi_elem["req_digest"] = get<1>(m_qi_elem); + qi_elem["data"] = get<2>(m_qi_elem); + qi_elem["v"] = get<3>(m_qi_elem); qi.append(qi_elem); } payload["qi"] = qi; @@ -306,6 +257,6 @@ std::string ViewChange::ToBinBuffer() const return this->FinalizeJsonRoot(payload); } -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/messages/messages.h b/src/fbft/messages/messages.h index 4806e43..f6f976e 100644 --- a/src/fbft/messages/messages.h +++ b/src/fbft/messages/messages.h @@ -13,12 +13,14 @@ #include "../../blockchain/blockchain.h" -namespace itcoin { namespace wallet { - class RoastWallet; - class Wallet; -}} +namespace itcoin { +namespace wallet { +class RoastWallet; +class Wallet; +} // namespace wallet +} // namespace itcoin -namespace wallet=itcoin::wallet; +namespace wallet = itcoin::wallet; namespace itcoin { namespace fbft { @@ -29,7 +31,7 @@ enum NODE_TYPE : unsigned int { CLIENT = 1, }; -const std::string NODE_TYPE_AS_STRING[] = { "REPLICA", "CLIENT" }; +const std::string NODE_TYPE_AS_STRING[] = {"REPLICA", "CLIENT"}; enum MSG_TYPE : unsigned int { BLOCK = 0, @@ -44,15 +46,15 @@ enum MSG_TYPE : unsigned int { }; const std::string MSG_TYPE_AS_STRING[] = { - "BLOCK", - "COMMIT", - "NEW_VIEW", - "PREPARE", - "PRE_PREPARE", - "REQUEST", - "ROAST_PRE_SIGNATURE", - "ROAST_SIGNATURE_SHARE", - "VIEW_CHANGE", + "BLOCK", + "COMMIT", + "NEW_VIEW", + "PREPARE", + "PRE_PREPARE", + "REQUEST", + "ROAST_PRE_SIGNATURE", + "ROAST_SIGNATURE_SHARE", + "VIEW_CHANGE", }; // Type definitions for messages @@ -72,358 +74,345 @@ typedef std::vector new_view_chi_t; // Abstract class class Message { - public: - Message(NODE_TYPE sender_role, uint32_t sender_id); - Message(NODE_TYPE sender_role, PlTerm Sender_id); - virtual ~Message(); - - // Getters - virtual std::unique_ptr clone() = 0; - virtual const std::string digest() const; - virtual std::string identify() const = 0; - std::string name() const; - virtual std::optional seq_number_as_opt() const; - std::string signature() const; - uint32_t sender_id() const {return m_sender_id;} - virtual MSG_TYPE type() const = 0; - - // Setters - void set_signature(std::string signature_hex); - - // Operations - virtual void Sign(const wallet::Wallet& wallet); - virtual bool VerifySignatures(const wallet::Wallet& wallet); - - // Operators - friend std::ostream& operator<<(std::ostream& Str, const Message& action); - bool operator==(const Message& other) const; - - // Serialization - virtual std::string ToBinBuffer() const; // Should be = 0; - - // TODO: ritornare direttamente uno unique_ptr, eventualmente nullptr - static std::optional> BuildFromBinBuffer(const std::string& bin_buffer); - - protected: - Message(const Json::Value& root); - - NODE_TYPE m_sender_role; - uint32_t m_sender_id; - std::string m_signature; - - virtual bool equals(const Message& other) const; - std::string FinalizeJsonRoot(Json::Value& root) const; +public: + Message(NODE_TYPE sender_role, uint32_t sender_id); + Message(NODE_TYPE sender_role, PlTerm Sender_id); + virtual ~Message(); + + // Getters + virtual std::unique_ptr clone() = 0; + virtual const std::string digest() const; + virtual std::string identify() const = 0; + std::string name() const; + virtual std::optional seq_number_as_opt() const; + std::string signature() const; + uint32_t sender_id() const { return m_sender_id; } + virtual MSG_TYPE type() const = 0; + + // Setters + void set_signature(std::string signature_hex); + + // Operations + virtual void Sign(const wallet::Wallet& wallet); + virtual bool VerifySignatures(const wallet::Wallet& wallet); + + // Operators + friend std::ostream& operator<<(std::ostream& Str, const Message& action); + bool operator==(const Message& other) const; + + // Serialization + virtual std::string ToBinBuffer() const; // Should be = 0; + + // TODO: ritornare direttamente uno unique_ptr, eventualmente nullptr + static std::optional> BuildFromBinBuffer(const std::string& bin_buffer); + +protected: + Message(const Json::Value& root); + + NODE_TYPE m_sender_role; + uint32_t m_sender_id; + std::string m_signature; + + virtual bool equals(const Message& other) const; + std::string FinalizeJsonRoot(Json::Value& root) const; }; class Request : public Message { - public: - Request(); - // TODO: the timestamp type should become an uin32_t like the nTime field in block.h - Request(uint32_t genesis_block_timestamp, uint32_t target_block_time, uint32_t timestamp); - ~Request(); - - // Getters - std::unique_ptr clone(); - const std::string digest() const; - std::string identify() const; - uint32_t timestamp() const { return m_timestamp; } - uint32_t height() const; - MSG_TYPE type() const { return MSG_TYPE::REQUEST; } - - // Finders - // TODO, replace with one optional - static messages::Request FindByDigest(uint32_t replica_id, std::string req_digest); - static bool TryFindByDigest(uint32_t replica_id, const std::string req_digest, messages::Request& out_request); - - private: - uint32_t m_genesis_block_timestamp; - uint32_t m_target_block_time; - uint32_t m_timestamp; - - bool equals(const Message& other) const; +public: + Request(); + // TODO: the timestamp type should become an uin32_t like the nTime field in block.h + Request(uint32_t genesis_block_timestamp, uint32_t target_block_time, uint32_t timestamp); + ~Request(); + + // Getters + std::unique_ptr clone(); + const std::string digest() const; + std::string identify() const; + uint32_t timestamp() const { return m_timestamp; } + uint32_t height() const; + MSG_TYPE type() const { return MSG_TYPE::REQUEST; } + + // Finders + // TODO, replace with one optional + static messages::Request FindByDigest(uint32_t replica_id, std::string req_digest); + static bool TryFindByDigest(uint32_t replica_id, const std::string req_digest, + messages::Request& out_request); + +private: + uint32_t m_genesis_block_timestamp; + uint32_t m_target_block_time; + uint32_t m_timestamp; + + bool equals(const Message& other) const; }; class PrePrepare : public Message { - public: - PrePrepare(uint32_t sender_id, - uint32_t view, uint32_t seq_number, std::string req_digest, - CBlock proposed_block); - PrePrepare(PlTerm Sender_id, PlTerm V, PlTerm N, PlTerm Req_digest, PlTerm Proposed_block); - PrePrepare(const Json::Value& root); - ~PrePrepare(); - - // Getters - std::unique_ptr clone(); - const std::string digest() const; - std::string identify() const; - uint32_t view() const { return m_view; } - uint32_t seq_number() const { return m_seq_number; } - std::optional seq_number_as_opt() const { return m_seq_number; } - std::string req_digest() const { return m_req_digest; } - MSG_TYPE type() const { return MSG_TYPE::PRE_PREPARE; } - const CBlock& proposed_block() const { return m_proposed_block; } - std::string proposed_block_hex() const; - - // Builders - static std::vector> BuildToBeSent(uint32_t replica_id); - - // Finders - static messages::PrePrepare FindByV_N_Req(uint32_t replica_id, uint32_t v, uint32_t n, std::string req_digest); - - // Serialization - std::string ToBinBuffer() const; - - private: - uint32_t m_view; - uint32_t m_seq_number; - std::string m_req_digest; - itcoin::blockchain::HexSerializableCBlock m_proposed_block; - - bool equals(const Message& other) const; - void set_proposed_block(std::string proposed_block_hex); +public: + PrePrepare(uint32_t sender_id, uint32_t view, uint32_t seq_number, std::string req_digest, + CBlock proposed_block); + PrePrepare(PlTerm Sender_id, PlTerm V, PlTerm N, PlTerm Req_digest, PlTerm Proposed_block); + PrePrepare(const Json::Value& root); + ~PrePrepare(); + + // Getters + std::unique_ptr clone(); + const std::string digest() const; + std::string identify() const; + uint32_t view() const { return m_view; } + uint32_t seq_number() const { return m_seq_number; } + std::optional seq_number_as_opt() const { return m_seq_number; } + std::string req_digest() const { return m_req_digest; } + MSG_TYPE type() const { return MSG_TYPE::PRE_PREPARE; } + const CBlock& proposed_block() const { return m_proposed_block; } + std::string proposed_block_hex() const; + + // Builders + static std::vector> BuildToBeSent(uint32_t replica_id); + + // Finders + static messages::PrePrepare FindByV_N_Req(uint32_t replica_id, uint32_t v, uint32_t n, + std::string req_digest); + + // Serialization + std::string ToBinBuffer() const; + +private: + uint32_t m_view; + uint32_t m_seq_number; + std::string m_req_digest; + itcoin::blockchain::HexSerializableCBlock m_proposed_block; + + bool equals(const Message& other) const; + void set_proposed_block(std::string proposed_block_hex); }; class Prepare : public Message { - public: - Prepare(uint32_t sender_id, - uint32_t view, uint32_t seq_number, std::string req_digest); - Prepare(PlTerm Sender_id, PlTerm V, PlTerm N, PlTerm Req_digest); - Prepare(const Json::Value& root); - ~Prepare(); - - // Getters - std::unique_ptr clone(); - const std::string digest() const; - std::string identify() const; - std::string req_digest() const { return m_req_digest; } - uint32_t seq_number() const { return m_seq_number; } - std::optional seq_number_as_opt() const { return m_seq_number; } - MSG_TYPE type() const { return MSG_TYPE::PREPARE; } - uint32_t view() const { return m_view; } - - // Builders - static std::vector> BuildToBeSent(uint32_t replica_id); - - // Serialization - std::string ToBinBuffer() const; - - private: - uint32_t m_view; - uint32_t m_seq_number; - std::string m_req_digest; - - bool equals(const Message& other) const; +public: + Prepare(uint32_t sender_id, uint32_t view, uint32_t seq_number, std::string req_digest); + Prepare(PlTerm Sender_id, PlTerm V, PlTerm N, PlTerm Req_digest); + Prepare(const Json::Value& root); + ~Prepare(); + + // Getters + std::unique_ptr clone(); + const std::string digest() const; + std::string identify() const; + std::string req_digest() const { return m_req_digest; } + uint32_t seq_number() const { return m_seq_number; } + std::optional seq_number_as_opt() const { return m_seq_number; } + MSG_TYPE type() const { return MSG_TYPE::PREPARE; } + uint32_t view() const { return m_view; } + + // Builders + static std::vector> BuildToBeSent(uint32_t replica_id); + + // Serialization + std::string ToBinBuffer() const; + +private: + uint32_t m_view; + uint32_t m_seq_number; + std::string m_req_digest; + + bool equals(const Message& other) const; }; class Commit : public Message { - public: - Commit(uint32_t sender_id, uint32_t view, uint32_t seq_number, std::string block_signature); - Commit(PlTerm Sender_id, PlTerm V, PlTerm N, PlTerm Block_signature); - Commit(const Json::Value& root); - ~Commit(); - - // Getters - std::unique_ptr clone(); - const std::string pre_signature() const { return m_pre_signature; } - const std::string digest() const; - std::string identify() const; - uint32_t seq_number() const { return m_seq_number; } - std::optional seq_number_as_opt() const { return m_seq_number; } - MSG_TYPE type() const { return MSG_TYPE::COMMIT; } - uint32_t view() const { return m_view; } - - // Finders - static std::vector FindByV_N(uint32_t replica_id, uint32_t v, uint32_t n); - - // Builders - static std::vector> BuildToBeSent(uint32_t replica_id); - - // Serialization - std::string ToBinBuffer() const; - - private: - uint32_t m_view; - uint32_t m_seq_number; - std::string m_pre_signature; - - bool equals(const Message& other) const; - void set_pre_signature(std::string pre_signature_hex); +public: + Commit(uint32_t sender_id, uint32_t view, uint32_t seq_number, std::string block_signature); + Commit(PlTerm Sender_id, PlTerm V, PlTerm N, PlTerm Block_signature); + Commit(const Json::Value& root); + ~Commit(); + + // Getters + std::unique_ptr clone(); + const std::string pre_signature() const { return m_pre_signature; } + const std::string digest() const; + std::string identify() const; + uint32_t seq_number() const { return m_seq_number; } + std::optional seq_number_as_opt() const { return m_seq_number; } + MSG_TYPE type() const { return MSG_TYPE::COMMIT; } + uint32_t view() const { return m_view; } + + // Finders + static std::vector FindByV_N(uint32_t replica_id, uint32_t v, uint32_t n); + + // Builders + static std::vector> BuildToBeSent(uint32_t replica_id); + + // Serialization + std::string ToBinBuffer() const; + +private: + uint32_t m_view; + uint32_t m_seq_number; + std::string m_pre_signature; + + bool equals(const Message& other) const; + void set_pre_signature(std::string pre_signature_hex); }; class Block : public Message { - public: - Block(uint32_t block_height, uint32_t block_time, std::string block_hash); - ~Block(); - - // Getters - std::unique_ptr clone(); - uint32_t block_time() const { return m_block_time; } - std::string block_hash() const { return m_block_hash; }; - uint32_t block_height() const { return m_block_height; } - std::string identify() const; - MSG_TYPE type() const { return MSG_TYPE::BLOCK; } - - private: - uint32_t m_block_height; - std::string m_block_hash; - uint32_t m_block_time; - - bool equals(const Message& other) const; +public: + Block(uint32_t block_height, uint32_t block_time, std::string block_hash); + ~Block(); + + // Getters + std::unique_ptr clone(); + uint32_t block_time() const { return m_block_time; } + std::string block_hash() const { return m_block_hash; }; + uint32_t block_height() const { return m_block_height; } + std::string identify() const; + MSG_TYPE type() const { return MSG_TYPE::BLOCK; } + +private: + uint32_t m_block_height; + std::string m_block_hash; + uint32_t m_block_time; + + bool equals(const Message& other) const; }; class ViewChange : public Message { - public: - ViewChange(uint32_t sender_id, - uint32_t view, uint32_t hi, - std::string c, - view_change_prepared_t pi, - view_change_pre_prepared_t qi); - ViewChange(PlTerm Sender_id, - PlTerm V, PlTerm Hi, PlTerm C, PlTerm Pi, PlTerm Qi); - ViewChange(const Json::Value& root); - ~ViewChange(); - - // Getters - std::unique_ptr clone(); - const std::string digest() const; - uint32_t view() const { return m_view; } - uint32_t hi() const { return m_hi; } - std::string identify() const; - const std::string c() const { return m_c; } - const view_change_prepared_t& pi() const { return m_pi; } - PlTerm pi_as_plterm() const; - const view_change_pre_prepared_t& qi() const { return m_qi; } - PlTerm qi_as_plterm() const; - MSG_TYPE type() const { return MSG_TYPE::VIEW_CHANGE; } - - // Builders - static std::vector> BuildToBeSent(uint32_t replica_id); - - // Finders - static messages::ViewChange FindByDigest(uint32_t replica_id, uint32_t sender_id, std::string digest); - - // Serialization - std::string ToBinBuffer() const; - - private: - uint32_t m_view; - uint32_t m_hi; - std::string m_c; - view_change_prepared_t m_pi; - view_change_pre_prepared_t m_qi; - - bool equals(const Message& other) const; +public: + ViewChange(uint32_t sender_id, uint32_t view, uint32_t hi, std::string c, view_change_prepared_t pi, + view_change_pre_prepared_t qi); + ViewChange(PlTerm Sender_id, PlTerm V, PlTerm Hi, PlTerm C, PlTerm Pi, PlTerm Qi); + ViewChange(const Json::Value& root); + ~ViewChange(); + + // Getters + std::unique_ptr clone(); + const std::string digest() const; + uint32_t view() const { return m_view; } + uint32_t hi() const { return m_hi; } + std::string identify() const; + const std::string c() const { return m_c; } + const view_change_prepared_t& pi() const { return m_pi; } + PlTerm pi_as_plterm() const; + const view_change_pre_prepared_t& qi() const { return m_qi; } + PlTerm qi_as_plterm() const; + MSG_TYPE type() const { return MSG_TYPE::VIEW_CHANGE; } + + // Builders + static std::vector> BuildToBeSent(uint32_t replica_id); + + // Finders + static messages::ViewChange FindByDigest(uint32_t replica_id, uint32_t sender_id, std::string digest); + + // Serialization + std::string ToBinBuffer() const; + +private: + uint32_t m_view; + uint32_t m_hi; + std::string m_c; + view_change_prepared_t m_pi; + view_change_pre_prepared_t m_qi; + + bool equals(const Message& other) const; }; -class NewView: public Message { - public: - NewView(uint32_t sender_id, - uint32_t view, - std::vector vc_messages, - std::vector ppp_messages - ); - NewView(PlTerm Sender_id, - PlTerm V, PlTerm Nu, PlTerm Chi - ); - NewView(const Json::Value& root); - ~NewView(); - - // Getters - std::unique_ptr clone(); - const std::string digest() const; - std::string identify() const; - const std::vector& view_changes() const { return m_vc_messages; }; - new_view_nu_t nu() const; - const std::vector& pre_prepares() const { return m_ppp_messages; }; - new_view_chi_t chi() const; - MSG_TYPE type() const { return MSG_TYPE::NEW_VIEW; } - uint32_t view() const { return m_view; } - - // Builders - static std::vector> BuildToBeSent(uint32_t replica_id); - static new_view_nu_t nu_from_plterm(PlTerm Nu); - static PlTerm nu_as_plterm(new_view_nu_t nu); - static new_view_chi_t chi_from_plterm(PlTerm Chi); - static PlTerm chi_as_plterm(new_view_chi_t chi); - - // Operations - void Sign(const wallet::RoastWallet& wallet); - bool VerifySignatures(const wallet::RoastWallet& wallet); - - // Serialization - std::string ToBinBuffer() const; - - private: - uint32_t m_view; - std::vector m_vc_messages; - std::vector m_ppp_messages; - - bool equals(const Message& other) const; +class NewView : public Message { +public: + NewView(uint32_t sender_id, uint32_t view, std::vector vc_messages, + std::vector ppp_messages); + NewView(PlTerm Sender_id, PlTerm V, PlTerm Nu, PlTerm Chi); + NewView(const Json::Value& root); + ~NewView(); + + // Getters + std::unique_ptr clone(); + const std::string digest() const; + std::string identify() const; + const std::vector& view_changes() const { return m_vc_messages; }; + new_view_nu_t nu() const; + const std::vector& pre_prepares() const { return m_ppp_messages; }; + new_view_chi_t chi() const; + MSG_TYPE type() const { return MSG_TYPE::NEW_VIEW; } + uint32_t view() const { return m_view; } + + // Builders + static std::vector> BuildToBeSent(uint32_t replica_id); + static new_view_nu_t nu_from_plterm(PlTerm Nu); + static PlTerm nu_as_plterm(new_view_nu_t nu); + static new_view_chi_t chi_from_plterm(PlTerm Chi); + static PlTerm chi_as_plterm(new_view_chi_t chi); + + // Operations + void Sign(const wallet::RoastWallet& wallet); + bool VerifySignatures(const wallet::RoastWallet& wallet); + + // Serialization + std::string ToBinBuffer() const; + +private: + uint32_t m_view; + std::vector m_vc_messages; + std::vector m_ppp_messages; + + bool equals(const Message& other) const; }; class RoastPreSignature : public Message { - public: - RoastPreSignature(uint32_t sender_id, - std::vector signers, std::string pre_signature); - RoastPreSignature(PlTerm Sender_id, - PlTerm Signers, PlTerm Pre_signature); - RoastPreSignature(const Json::Value& root); - ~RoastPreSignature(); - - // Builders - static std::vector> BuildToBeSent(uint32_t replica_id); - - // Getters - std::unique_ptr clone(); - const std::string digest() const; - std::string identify() const; - std::string pre_signature() const; - std::vector signers() const; - PlTerm signers_as_plterm() const; - MSG_TYPE type() const { return MSG_TYPE::ROAST_PRE_SIGNATURE; } - - // Serialization - std::string ToBinBuffer() const; - - private: - std::vector m_signers; - std::string m_pre_signature; - - bool equals(const Message& other) const; +public: + RoastPreSignature(uint32_t sender_id, std::vector signers, std::string pre_signature); + RoastPreSignature(PlTerm Sender_id, PlTerm Signers, PlTerm Pre_signature); + RoastPreSignature(const Json::Value& root); + ~RoastPreSignature(); + + // Builders + static std::vector> BuildToBeSent(uint32_t replica_id); + + // Getters + std::unique_ptr clone(); + const std::string digest() const; + std::string identify() const; + std::string pre_signature() const; + std::vector signers() const; + PlTerm signers_as_plterm() const; + MSG_TYPE type() const { return MSG_TYPE::ROAST_PRE_SIGNATURE; } + + // Serialization + std::string ToBinBuffer() const; + +private: + std::vector m_signers; + std::string m_pre_signature; + + bool equals(const Message& other) const; }; class RoastSignatureShare : public Message { - public: - RoastSignatureShare(uint32_t sender_id, - std::string signature_share, std::string next_pre_signature_share); - RoastSignatureShare(PlTerm Sender_id, - PlTerm Signature_share, PlTerm Next_pre_signature_share); - RoastSignatureShare(const Json::Value& root); - ~RoastSignatureShare(); - - // Builders - static std::vector> BuildToBeSent(uint32_t replica_id); - - // Getters - std::unique_ptr clone(); - const std::string digest() const; - std::string identify() const; - std::string signature_share() const; - std::string next_pre_signature_share() const; - MSG_TYPE type() const { return MSG_TYPE::ROAST_SIGNATURE_SHARE; } - - // Serialization - std::string ToBinBuffer() const; - - private: - std::string m_signature_share; - std::string m_next_pre_signature_share; - - bool equals(const Message& other) const; +public: + RoastSignatureShare(uint32_t sender_id, std::string signature_share, std::string next_pre_signature_share); + RoastSignatureShare(PlTerm Sender_id, PlTerm Signature_share, PlTerm Next_pre_signature_share); + RoastSignatureShare(const Json::Value& root); + ~RoastSignatureShare(); + + // Builders + static std::vector> BuildToBeSent(uint32_t replica_id); + + // Getters + std::unique_ptr clone(); + const std::string digest() const; + std::string identify() const; + std::string signature_share() const; + std::string next_pre_signature_share() const; + MSG_TYPE type() const { return MSG_TYPE::ROAST_SIGNATURE_SHARE; } + + // Serialization + std::string ToBinBuffer() const; + +private: + std::string m_signature_share; + std::string m_next_pre_signature_share; + + bool equals(const Message& other) const; }; -} -} -} +} // namespace messages +} // namespace fbft +} // namespace itcoin #endif // ITCOIN_FBFT_MESSAGES_MESSAGES_H diff --git a/src/fbft/state/ReplicaState.cpp b/src/fbft/state/ReplicaState.cpp index 3535225..4a7f984 100644 --- a/src/fbft/state/ReplicaState.cpp +++ b/src/fbft/state/ReplicaState.cpp @@ -3,10 +3,10 @@ #include "state.h" +#include #include #include #include -#include #include "../../blockchain/blockchain.h" #include "../../wallet/wallet.h" @@ -19,15 +19,11 @@ using namespace itcoin::wallet; // utilities -static int prolog_engine_one_shot_call(const string predicate, const PlTermv args) -{ - try - { +static int prolog_engine_one_shot_call(const string predicate, const PlTermv args) { + try { return PlCall(predicate.c_str(), args); - } - catch ( PlException &ex ) - { - BOOST_LOG_TRIVIAL(error) << (char *) ex; + } catch (PlException& ex) { + BOOST_LOG_TRIVIAL(error) << (char*)ex; throw ex; } } @@ -36,27 +32,18 @@ namespace itcoin { namespace fbft { namespace state { -ReplicaState::ReplicaState(const itcoin::FbftConfig& conf, -Blockchain& blockchain, -RoastWallet& wallet, -uint32_t start_height, -std::string start_hash, -uint32_t start_time): -m_conf(conf), -m_blockchain(blockchain), -m_wallet(wallet) -{ +ReplicaState::ReplicaState(const itcoin::FbftConfig& conf, Blockchain& blockchain, RoastWallet& wallet, + uint32_t start_height, std::string start_hash, uint32_t start_time) + : m_conf(conf), m_blockchain(blockchain), m_wallet(wallet) { Init(start_height, start_hash, start_time); } -void ReplicaState::Init(uint32_t start_height, std::string start_hash, uint32_t start_time) -{ +void ReplicaState::Init(uint32_t start_height, std::string start_hash, uint32_t start_time) { uint32_t replica_id = m_conf.id(); uint32_t cluster_size = m_conf.cluster_size(); uint32_t target_block_time = m_conf.target_block_time(); - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% creating PL database with \ + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% creating PL database with \ cluster_size=%2% \ start_height=%3%, \ start_hash=%4%, \ @@ -64,33 +51,18 @@ void ReplicaState::Init(uint32_t start_height, std::string start_hash, uint32_t genesis_block_timestamp=%6%, \ target_block_time=%7%, \ db_filename=%8%, \ - db_reset=%9%") - % m_conf.id() - % m_conf.cluster_size() - % start_height - % start_hash - % start_time - % m_conf.genesis_block_timestamp() - % m_conf.target_block_time() - % m_conf.fbft_db_filename() - % m_conf.fbft_db_reset() - ); - PlTermv args( - PlTerm((long) replica_id), - PlTerm((long) cluster_size), - PlTerm((long) start_height), - PlString(start_hash.c_str()), - PlTerm((long) start_time), - PlTerm((long) m_conf.genesis_block_timestamp()), - PlTerm((long) target_block_time), - PlString(m_conf.fbft_db_filename().c_str()), - PlTerm(m_conf.fbft_db_reset()) - ); + db_reset=%9%") % m_conf.id() % m_conf.cluster_size() % + start_height % start_hash % start_time % m_conf.genesis_block_timestamp() % + m_conf.target_block_time() % m_conf.fbft_db_filename() % + m_conf.fbft_db_reset()); + PlTermv args(PlTerm((long)replica_id), PlTerm((long)cluster_size), PlTerm((long)start_height), + PlString(start_hash.c_str()), PlTerm((long)start_time), + PlTerm((long)m_conf.genesis_block_timestamp()), PlTerm((long)target_block_time), + PlString(m_conf.fbft_db_filename().c_str()), PlTerm(m_conf.fbft_db_reset())); prolog_engine_one_shot_call("init", args); } -void ReplicaState::ReceiveIncomingMessage(std::unique_ptr msg) -{ +void ReplicaState::ReceiveIncomingMessage(std::unique_ptr msg) { // Adds the received message to the input message buffer m_in_msg_buffer.emplace_back(std::move(msg)); @@ -98,8 +70,7 @@ void ReplicaState::ReceiveIncomingMessage(std::unique_ptr msg UpdateActiveActions(); } -void ReplicaState::UpdateActiveActions() -{ +void ReplicaState::UpdateActiveActions() { // Clear the current active actions vector. m_active_actions.clear(); @@ -107,74 +78,73 @@ void ReplicaState::UpdateActiveActions() * Fill result actions that depend on the input message buffer * The switch in the loop translate from Message to the corresponding ReceiveMessage action. */ - for (auto &msg : m_in_msg_buffer) - { + for (auto& msg : m_in_msg_buffer) { switch (msg->type()) { - case messages::MSG_TYPE::BLOCK: - { - messages::Block typed_msg{ dynamic_cast(*msg) }; - std::unique_ptr action = std::make_unique(m_conf.id(), typed_msg); + case messages::MSG_TYPE::BLOCK: { + messages::Block typed_msg{dynamic_cast(*msg)}; + std::unique_ptr action = + std::make_unique(m_conf.id(), typed_msg); m_active_actions.emplace_back(std::move(action)); break; } - case messages::MSG_TYPE::REQUEST: - { - messages::Request typed_msg = messages::Request( dynamic_cast(*msg) ); - std::unique_ptr action = std::make_unique(m_conf.id(), typed_msg); + case messages::MSG_TYPE::REQUEST: { + messages::Request typed_msg = messages::Request(dynamic_cast(*msg)); + std::unique_ptr action = + std::make_unique(m_conf.id(), typed_msg); m_active_actions.emplace_back(std::move(action)); break; } - case messages::MSG_TYPE::PREPARE: - { - messages::Prepare typed_msg = messages::Prepare( dynamic_cast(*msg) ); - std::unique_ptr action = std::make_unique(m_conf.id(), typed_msg); + case messages::MSG_TYPE::PREPARE: { + messages::Prepare typed_msg = messages::Prepare(dynamic_cast(*msg)); + std::unique_ptr action = + std::make_unique(m_conf.id(), typed_msg); m_active_actions.emplace_back(std::move(action)); break; } - case messages::MSG_TYPE::PRE_PREPARE: - { - messages::PrePrepare typed_msg = messages::PrePrepare( dynamic_cast(*msg) ); + case messages::MSG_TYPE::PRE_PREPARE: { + messages::PrePrepare typed_msg = messages::PrePrepare(dynamic_cast(*msg)); double current_time = this->current_time(); double pre_prepare_time_tolerance_delta = m_conf.C_PRE_PREPARE_ACCEPT_UNTIL_CURRENT_TIME_PLUS(); std::unique_ptr action = std::make_unique( - m_conf.id(), m_blockchain, current_time, pre_prepare_time_tolerance_delta, typed_msg - ); + m_conf.id(), m_blockchain, current_time, pre_prepare_time_tolerance_delta, typed_msg); m_active_actions.emplace_back(std::move(action)); break; } - case messages::MSG_TYPE::COMMIT: - { - messages::Commit typed_msg = messages::Commit( dynamic_cast(*msg) ); - std::unique_ptr action = std::make_unique(m_conf.id(), typed_msg); + case messages::MSG_TYPE::COMMIT: { + messages::Commit typed_msg = messages::Commit(dynamic_cast(*msg)); + std::unique_ptr action = + std::make_unique(m_conf.id(), typed_msg); m_active_actions.emplace_back(std::move(action)); break; } - case messages::MSG_TYPE::VIEW_CHANGE: - { - messages::ViewChange typed_msg = messages::ViewChange( dynamic_cast(*msg) ); - std::unique_ptr action = std::make_unique(m_conf.id(), typed_msg); + case messages::MSG_TYPE::VIEW_CHANGE: { + messages::ViewChange typed_msg = messages::ViewChange(dynamic_cast(*msg)); + std::unique_ptr action = + std::make_unique(m_conf.id(), typed_msg); m_active_actions.emplace_back(std::move(action)); break; } - case messages::MSG_TYPE::NEW_VIEW: - { - messages::NewView typed_msg = messages::NewView( dynamic_cast(*msg) ); - std::unique_ptr action = std::make_unique(m_wallet, m_conf.id(), typed_msg); + case messages::MSG_TYPE::NEW_VIEW: { + messages::NewView typed_msg = messages::NewView(dynamic_cast(*msg)); + std::unique_ptr action = + std::make_unique(m_wallet, m_conf.id(), typed_msg); m_active_actions.emplace_back(std::move(action)); break; } - case messages::MSG_TYPE::ROAST_PRE_SIGNATURE: - { - messages::RoastPreSignature typed_msg = messages::RoastPreSignature( dynamic_cast(*msg) ); + case messages::MSG_TYPE::ROAST_PRE_SIGNATURE: { + messages::RoastPreSignature typed_msg = + messages::RoastPreSignature(dynamic_cast(*msg)); RoastWallet& wallet = dynamic_cast(m_wallet); - std::unique_ptr action = std::make_unique(wallet, m_conf.id(), typed_msg); + std::unique_ptr action = + std::make_unique(wallet, m_conf.id(), typed_msg); m_active_actions.emplace_back(std::move(action)); break; } - case messages::MSG_TYPE::ROAST_SIGNATURE_SHARE: - { - messages::RoastSignatureShare typed_msg = messages::RoastSignatureShare( dynamic_cast(*msg) ); - std::unique_ptr action = std::make_unique(m_conf.id(), typed_msg); + case messages::MSG_TYPE::ROAST_SIGNATURE_SHARE: { + messages::RoastSignatureShare typed_msg = + messages::RoastSignatureShare(dynamic_cast(*msg)); + std::unique_ptr action = + std::make_unique(m_conf.id(), typed_msg); m_active_actions.emplace_back(std::move(action)); break; } @@ -184,65 +154,44 @@ void ReplicaState::UpdateActiveActions() /* * Fill result with actions that depend on the current state */ - try - { - for (auto& p_action : - actions::Execute::BuildActives(m_conf, m_blockchain, m_wallet) ) - { + try { + for (auto& p_action : actions::Execute::BuildActives(m_conf, m_blockchain, m_wallet)) { m_active_actions.emplace_back(std::move(p_action)); } - for (auto& p_action : - actions::SendCommit::BuildActives(m_conf, m_blockchain, m_wallet) ) - { + for (auto& p_action : actions::SendCommit::BuildActives(m_conf, m_blockchain, m_wallet)) { m_active_actions.emplace_back(std::move(p_action)); } - for (auto& p_action : - actions::SendPrepare::BuildActives(m_conf, m_blockchain, m_wallet) ) - { + for (auto& p_action : actions::SendPrepare::BuildActives(m_conf, m_blockchain, m_wallet)) { m_active_actions.emplace_back(std::move(p_action)); } - for (auto& p_action : - actions::SendPrePrepare::BuildActives(m_conf, m_blockchain, m_wallet) ) - { + for (auto& p_action : actions::SendPrePrepare::BuildActives(m_conf, m_blockchain, m_wallet)) { m_active_actions.emplace_back(std::move(p_action)); } - for (auto& p_action : - actions::SendViewChange::BuildActives(m_conf, m_blockchain, m_wallet) ) - { + for (auto& p_action : actions::SendViewChange::BuildActives(m_conf, m_blockchain, m_wallet)) { m_active_actions.emplace_back(std::move(p_action)); } - for (auto& p_action : - actions::RecoverView::BuildActives(m_conf, m_blockchain, m_wallet) ) - { + for (auto& p_action : actions::RecoverView::BuildActives(m_conf, m_blockchain, m_wallet)) { m_active_actions.emplace_back(std::move(p_action)); } - for (auto& p_action : - actions::SendNewView::BuildActives(m_conf, m_blockchain, m_wallet) ) - { + for (auto& p_action : actions::SendNewView::BuildActives(m_conf, m_blockchain, m_wallet)) { m_active_actions.emplace_back(std::move(p_action)); } - for (auto& p_action : - actions::ProcessNewView::BuildActives(m_conf, m_blockchain, m_wallet) ) - { + for (auto& p_action : actions::ProcessNewView::BuildActives(m_conf, m_blockchain, m_wallet)) { m_active_actions.emplace_back(std::move(p_action)); } - for (auto& p_action : - actions::RoastInit::BuildActives(m_conf, m_blockchain, m_wallet) ) - { + for (auto& p_action : actions::RoastInit::BuildActives(m_conf, m_blockchain, m_wallet)) { m_active_actions.emplace_back(std::move(p_action)); } - } - catch ( PlException &ex ) - { - BOOST_LOG_TRIVIAL(error) << (char *) ex; + } catch (PlException& ex) { + BOOST_LOG_TRIVIAL(error) << (char*)ex; throw ex; } @@ -250,155 +199,118 @@ void ReplicaState::UpdateActiveActions() // 15398 [2022-Nov-30 16:04:57.933528] [error] error(resource_error(stack), stack_overflow{ // choicepoints:3,depth:2,environments:3,globalused:895048,localused:2692, // stack:[frame(2,user:msg_log_commit(2,2,62,_192953056,2,_192953060),[]), - // frame(1,user:pre_SEND_COMMIT("(H=62, T=1669820690)",2,62,2),[]),frame(0,system:'$c_call_prolog',[])],stack_limit:1048576,trailused:618 + // frame(1,user:pre_SEND_COMMIT("(H=62, + // T=1669820690)",2,62,2),[]),frame(0,system:'$c_call_prolog',[])],stack_limit:1048576,trailused:618 // }) terminate called after throwing an instance of 'PlException' // Similar to: // https://discourse.swi-prolog.org/t/stack-overflow-problem/520/4 prolog_engine_one_shot_call("garbage_collect", PlTermv(0)); - for(unique_ptr& action: m_active_actions) - { - BOOST_LOG_TRIVIAL(debug) << - "R" << m_conf.id() << " action " << - *action << " is active."; + for (unique_ptr& action : m_active_actions) { + BOOST_LOG_TRIVIAL(debug) << "R" << m_conf.id() << " action " << *action << " is active."; } } -void ReplicaState::UpdateOutMessageBuffer() -{ - try - { +void ReplicaState::UpdateOutMessageBuffer() { + try { // Clear the current out buffer vector. m_out_msg_buffer.clear(); - for (auto& p_msg : messages::PrePrepare::BuildToBeSent(m_conf.id()) ) - { + for (auto& p_msg : messages::PrePrepare::BuildToBeSent(m_conf.id())) { m_out_msg_buffer.emplace_back(std::move(p_msg)); } - for (auto& p_msg : messages::Prepare::BuildToBeSent(m_conf.id()) ) - { + for (auto& p_msg : messages::Prepare::BuildToBeSent(m_conf.id())) { m_out_msg_buffer.emplace_back(std::move(p_msg)); } - for (auto& p_msg : messages::Commit::BuildToBeSent(m_conf.id()) ) - { + for (auto& p_msg : messages::Commit::BuildToBeSent(m_conf.id())) { m_out_msg_buffer.emplace_back(std::move(p_msg)); } - for (auto& p_msg : messages::ViewChange::BuildToBeSent(m_conf.id()) ) - { + for (auto& p_msg : messages::ViewChange::BuildToBeSent(m_conf.id())) { m_out_msg_buffer.emplace_back(std::move(p_msg)); } - for (auto& p_msg : messages::NewView::BuildToBeSent(m_conf.id()) ) - { + for (auto& p_msg : messages::NewView::BuildToBeSent(m_conf.id())) { m_out_msg_buffer.emplace_back(std::move(p_msg)); } - for (auto& p_msg : messages::RoastPreSignature::BuildToBeSent(m_conf.id()) ) - { + for (auto& p_msg : messages::RoastPreSignature::BuildToBeSent(m_conf.id())) { m_out_msg_buffer.emplace_back(std::move(p_msg)); } - for (auto& p_msg : messages::RoastSignatureShare::BuildToBeSent(m_conf.id()) ) - { + for (auto& p_msg : messages::RoastSignatureShare::BuildToBeSent(m_conf.id())) { m_out_msg_buffer.emplace_back(std::move(p_msg)); } - } - catch ( PlException &ex ) - { - BOOST_LOG_TRIVIAL(error) << (char *) ex; + } catch (PlException& ex) { + BOOST_LOG_TRIVIAL(error) << (char*)ex; throw ex; } - for(unique_ptr& message: m_out_msg_buffer) - { - BOOST_LOG_TRIVIAL(trace) << - "R" << m_conf.id() << - " has " << *message << - " in the output buffer"; - } + for (unique_ptr& message : m_out_msg_buffer) { + BOOST_LOG_TRIVIAL(trace) << "R" << m_conf.id() << " has " << *message << " in the output buffer"; + } } -void ReplicaState::Apply(const actions::Action& action) -{ +void ReplicaState::Apply(const actions::Action& action) { /* * Apply the effect of the action */ int action_execution_success = 0; - try - { - BOOST_LOG_TRIVIAL(debug) << - "R" << m_conf.id() << - " applying " << action.identify() << " effect."; + try { + BOOST_LOG_TRIVIAL(debug) << "R" << m_conf.id() << " applying " << action.identify() << " effect."; action_execution_success = action.effect(); - if (!action_execution_success) - { - string error_msg = str( - boost::format("R%1% cannot execute %2%") - % m_conf.id() - % action.identify() - ); + if (!action_execution_success) { + string error_msg = str(boost::format("R%1% cannot execute %2%") % m_conf.id() % action.identify()); BOOST_LOG_TRIVIAL(error) << error_msg; } - } - catch ( PlException &ex ) - { - BOOST_LOG_TRIVIAL(error) << (char *) ex; + } catch (PlException& ex) { + BOOST_LOG_TRIVIAL(error) << (char*)ex; throw ex; } /* - * If the action was a ReceiveMessage type, update the two input buffers (normal one and awaiting checkpoint one) accordingly + * If the action was a ReceiveMessage type, update the two input buffers (normal one and awaiting checkpoint + * one) accordingly */ std::optional> processed_msg_opt = action.message(); - if (processed_msg_opt.has_value()) - { + if (processed_msg_opt.has_value()) { const messages::Message& processed_msg = processed_msg_opt.value().get(); - // If the message was a succesfully applied BLOCK, we move all messages from the awaiting_checkpoint buffer to the input buffer - if ( action_execution_success && processed_msg.type() == messages::MSG_TYPE::BLOCK ) - { - // Perhaps this could be improved by having a map (height -> set of messages), or a specialized data structure, rather than a vector. - // Still, since the number of messages in the buffers will be relatively low, this could possibly perform even better than a map, - // despite the worse complexity. - for (size_t i=0; i set of messages), or a specialized data + // structure, rather than a vector. Still, since the number of messages in the buffers will be + // relatively low, this could possibly perform even better than a map, despite the worse complexity. + for (size_t i = 0; i < m_in_msg_awaiting_checkpoint_buffer.size(); i++) { unique_ptr msg = move(m_in_msg_awaiting_checkpoint_buffer.at(i)); - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% moving %2% from the awaiting checkpoint buffer") - % std::to_string(m_conf.id()) - % msg->identify() - ); + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% moving %2% from the awaiting checkpoint buffer") % + std::to_string(m_conf.id()) % msg->identify()); m_in_msg_buffer.emplace_back(move(msg)); } m_in_msg_awaiting_checkpoint_buffer.clear(); } // In any case we remove the corresponding message from the input message buffer - for (size_t i=0; ih(); - if ( !action_execution_success && processed_msg.seq_number_as_opt().has_value() && processed_msg.seq_number_as_opt().value() == h + 2 ) - { - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% moving %2% to the awaiting checkpoint buffer") - % std::to_string(m_conf.id()) - % msg.identify() - ); - m_in_msg_awaiting_checkpoint_buffer.emplace_back(std::move(m_in_msg_buffer.at(i))); // This makes msg a nullptr, not an issue, it will be removed + if (!action_execution_success && processed_msg.seq_number_as_opt().has_value() && + processed_msg.seq_number_as_opt().value() == h + 2) { + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% moving %2% to the awaiting checkpoint buffer") % + std::to_string(m_conf.id()) % msg.identify()); + m_in_msg_awaiting_checkpoint_buffer.emplace_back( + std::move(m_in_msg_buffer.at(i))); // This makes msg a nullptr, not an issue, it will be removed } - m_in_msg_buffer.erase(m_in_msg_buffer.begin()+i); + m_in_msg_buffer.erase(m_in_msg_buffer.begin() + i); break; } } - } /* @@ -413,114 +325,76 @@ void ReplicaState::Apply(const actions::Action& action) } void ReplicaState::ClearOutMessageBuffer() { - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% clearing the output buffer") - % std::to_string(m_conf.id()) - ); + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% clearing the output buffer") % + std::to_string(m_conf.id())); // Clean the message out buffer both on the engine and on the vector - prolog_engine_one_shot_call("msg_out_clear_all", PlTermv(PlTerm{(long) m_conf.id()})); + prolog_engine_one_shot_call("msg_out_clear_all", PlTermv(PlTerm{(long)m_conf.id()})); m_out_msg_buffer.clear(); - } -double ReplicaState::latest_request_time() const -{ +double ReplicaState::latest_request_time() const { PlTerm Max_t; - int result = prolog_engine_one_shot_call("get_latest_request_time", PlTermv( - PlTerm{(long) m_conf.id()}, - Max_t - )); + int result = + prolog_engine_one_shot_call("get_latest_request_time", PlTermv(PlTerm{(long)m_conf.id()}, Max_t)); if (result) - return (double) Max_t; - else - { + return (double)Max_t; + else { return m_conf.genesis_block_timestamp(); } } -double ReplicaState::latest_reply_time() const -{ +double ReplicaState::latest_reply_time() const { PlTerm Last_rep_t; - int result = prolog_engine_one_shot_call("last_rep", PlTermv( - PlTerm{(long) m_conf.id()}, - Last_rep_t - )); + int result = prolog_engine_one_shot_call("last_rep", PlTermv(PlTerm{(long)m_conf.id()}, Last_rep_t)); if (result) - return (double) Last_rep_t; - else - { + return (double)Last_rep_t; + else { return m_conf.genesis_block_timestamp(); } } -double ReplicaState::current_time() const -{ +double ReplicaState::current_time() const { PlTerm Synthetic_time; - prolog_engine_one_shot_call("get_synthetic_time", PlTermv( - PlTerm{(long) m_conf.id()}, - Synthetic_time - )); - return (double) Synthetic_time; + prolog_engine_one_shot_call("get_synthetic_time", PlTermv(PlTerm{(long)m_conf.id()}, Synthetic_time)); + return (double)Synthetic_time; } -uint32_t ReplicaState::h() const -{ +uint32_t ReplicaState::h() const { PlTerm H; - prolog_engine_one_shot_call("get_h", PlTermv( - PlTerm{(long) m_conf.id()}, - H - )); - return (long) H; + prolog_engine_one_shot_call("get_h", PlTermv(PlTerm{(long)m_conf.id()}, H)); + return (long)H; } -uint32_t ReplicaState::primary() const -{ +uint32_t ReplicaState::primary() const { PlTerm Primary; - prolog_engine_one_shot_call("primary", PlTermv( - PlTerm{(long) view()}, - Primary - )); - return (long) Primary; + prolog_engine_one_shot_call("primary", PlTermv(PlTerm{(long)view()}, Primary)); + return (long)Primary; } -uint32_t ReplicaState::view() const -{ +uint32_t ReplicaState::view() const { PlTerm View_i; - prolog_engine_one_shot_call("view", PlTermv( - PlTerm{(long) m_conf.id()}, - View_i - )); - return (long) View_i; + prolog_engine_one_shot_call("view", PlTermv(PlTerm{(long)m_conf.id()}, View_i)); + return (long)View_i; } -const std::vector>& ReplicaState::in_msg_buffer() const -{ +const std::vector>& ReplicaState::in_msg_buffer() const { return m_in_msg_buffer; } -const std::vector>& ReplicaState::out_msg_buffer() const -{ +const std::vector>& ReplicaState::out_msg_buffer() const { return m_out_msg_buffer; } -const std::vector>& ReplicaState::active_actions() const -{ +const std::vector>& ReplicaState::active_actions() const { return m_active_actions; } // Setters -void ReplicaState::set_synthetic_time(double time) -{ - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% setting synthetic time = %2%") - % std::to_string(m_conf.id()) - % std::to_string(time) - ); - prolog_engine_one_shot_call("set_synthetic_time", PlTermv( - PlTerm{(long) m_conf.id()}, - PlTerm{(double) time} - )); +void ReplicaState::set_synthetic_time(double time) { + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% setting synthetic time = %2%") % + std::to_string(m_conf.id()) % std::to_string(time)); + prolog_engine_one_shot_call("set_synthetic_time", PlTermv(PlTerm{(long)m_conf.id()}, PlTerm{(double)time})); /* * Update active actions @@ -529,6 +403,6 @@ void ReplicaState::set_synthetic_time(double time) UpdateActiveActions(); } -} -} -} +} // namespace state +} // namespace fbft +} // namespace itcoin diff --git a/src/fbft/state/state.h b/src/fbft/state/state.h index 490853e..a759730 100644 --- a/src/fbft/state/state.h +++ b/src/fbft/state/state.h @@ -4,17 +4,21 @@ #ifndef ITCOIN_FBFT_STATE_STATE_H #define ITCOIN_FBFT_STATE_STATE_H -#include "config/FbftConfig.h" #include "../actions/actions.h" #include "../messages/messages.h" +#include "config/FbftConfig.h" -namespace itcoin { namespace blockchain { - class Blockchain; -}} +namespace itcoin { +namespace blockchain { +class Blockchain; +} +} // namespace itcoin -namespace itcoin { namespace wallet { - class Wallet; -}} +namespace itcoin { +namespace wallet { +class Wallet; +} +} // namespace itcoin namespace actions = itcoin::fbft::actions; namespace messages = itcoin::fbft::messages; @@ -25,62 +29,57 @@ namespace state { // A replica state class ReplicaState { - public: - ReplicaState( - const itcoin::FbftConfig& conf, - blockchain::Blockchain& blockchain, - wallet::RoastWallet& wallet, - uint32_t start_height, - std::string start_hash, - uint32_t start_time - ); - ~ReplicaState() {}; - - // Getters - const std::vector>& in_msg_buffer() const; - const std::vector>& out_msg_buffer() const; - const std::vector>& active_actions() const; - double current_time() const; - double latest_request_time() const; - double latest_reply_time() const; - uint32_t h() const; - uint32_t primary() const; - uint32_t view() const; - - // Setters - // Synthetic time is a floating point number expressing the time in seconds since the Epoch at 1970-01-01. - void set_synthetic_time(double time); - - // Operations - void Init(uint32_t start_height, std::string start_hash, uint32_t start_time); - void Apply(const actions::Action& action); - void ClearOutMessageBuffer(); - void ReceiveIncomingMessage(std::unique_ptr msg); - void UpdateActiveActions(); - - protected: - // Configuration - const itcoin::FbftConfig& m_conf; - blockchain::Blockchain& m_blockchain; - wallet::RoastWallet& m_wallet; - - // Buffer of incoming messages - std::vector> m_in_msg_buffer; - std::vector> m_in_msg_awaiting_checkpoint_buffer; - - // Buffer of outgoing messages - std::vector> m_out_msg_buffer; - - // Active actions - std::vector> m_active_actions; - - private: - // Update the set of messages to be sent - void UpdateOutMessageBuffer(); +public: + ReplicaState(const itcoin::FbftConfig& conf, blockchain::Blockchain& blockchain, + wallet::RoastWallet& wallet, uint32_t start_height, std::string start_hash, + uint32_t start_time); + ~ReplicaState(){}; + + // Getters + const std::vector>& in_msg_buffer() const; + const std::vector>& out_msg_buffer() const; + const std::vector>& active_actions() const; + double current_time() const; + double latest_request_time() const; + double latest_reply_time() const; + uint32_t h() const; + uint32_t primary() const; + uint32_t view() const; + + // Setters + // Synthetic time is a floating point number expressing the time in seconds since the Epoch at 1970-01-01. + void set_synthetic_time(double time); + + // Operations + void Init(uint32_t start_height, std::string start_hash, uint32_t start_time); + void Apply(const actions::Action& action); + void ClearOutMessageBuffer(); + void ReceiveIncomingMessage(std::unique_ptr msg); + void UpdateActiveActions(); + +protected: + // Configuration + const itcoin::FbftConfig& m_conf; + blockchain::Blockchain& m_blockchain; + wallet::RoastWallet& m_wallet; + + // Buffer of incoming messages + std::vector> m_in_msg_buffer; + std::vector> m_in_msg_awaiting_checkpoint_buffer; + + // Buffer of outgoing messages + std::vector> m_out_msg_buffer; + + // Active actions + std::vector> m_active_actions; + +private: + // Update the set of messages to be sent + void UpdateOutMessageBuffer(); }; -} -} -} +} // namespace state +} // namespace fbft +} // namespace itcoin #endif // ITCOIN_FBFT_STATE_STATE_H diff --git a/src/main-test.cpp b/src/main-test.cpp index 3f6e711..aaffebc 100644 --- a/src/main-test.cpp +++ b/src/main-test.cpp @@ -30,21 +30,20 @@ using namespace boost::unit_test; // otherwise cmake depend.make will not include the header files that follow the first program instruction. const std::function G_TRANSLATION_FUN = nullptr; -int BOOST_TEST_CALL_DECL main( int argc, char* argv[] ) -{ +int BOOST_TEST_CALL_DECL main(int argc, char* argv[]) { // Setup logger itcoin::utils::configure_boost_logging(); // Print boost version - BOOST_LOG_TRIVIAL(trace) << "Using Boost " - << BOOST_VERSION / 100000 << "." // major version - << BOOST_VERSION / 100 % 1000 << "." // minor version - << BOOST_VERSION % 100; // patch level + BOOST_LOG_TRIVIAL(trace) << "Using Boost " << BOOST_VERSION / 100000 << "." // major version + << BOOST_VERSION / 100 % 1000 << "." // minor version + << BOOST_VERSION % 100; // patch level // Init prolog engine PL_set_resource_db_mem(resource_db_mem_bin, resource_db_mem_bin_len); - char *argv2[] = {(char*)"thisisnonsense", (char*)"-f", (char*)"none", (char*)"-F", (char*)"none", (char*)"-g", (char*)"true"}; + char* argv2[] = {(char*)"thisisnonsense", (char*)"-f", (char*)"none", (char*)"-F", + (char*)"none", (char*)"-g", (char*)"true"}; PlEngine engine(7, argv2); - return ::boost::unit_test::unit_test_main( init_unit_test, argc, argv ); + return ::boost::unit_test::unit_test_main(init_unit_test, argc, argv); } diff --git a/src/main.cpp b/src/main.cpp index 7322361..418ff6d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,36 +5,36 @@ #include -#include "utils/utils.h" #include "../src/blockchain/blockchain.h" +#include "../src/fbft/Replica2.h" +#include "../src/fbft/messages/messages.h" #include "../src/transport/btcclient.h" #include "../src/transport/zcomm.h" #include "../src/wallet/wallet.h" -#include "../src/fbft/messages/messages.h" -#include "../src/fbft/Replica2.h" +#include "utils/utils.h" #include #include -#include #include +#include using namespace itcoin; const std::function G_TRANSLATION_FUN = nullptr; -const std::string DEFAULT_DATADIR = (std::filesystem::current_path() / "infra" / "node02" ).string(); +const std::string DEFAULT_DATADIR = (std::filesystem::current_path() / "infra" / "node02").string(); /** * Returns: * - datadir */ -std::tuple parse_cmdline(int argc, char* argv[]) -{ +std::tuple parse_cmdline(int argc, char* argv[]) { // Configure the command line args ArgsManager argsManager; - argsManager.AddArg("-datadir=", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsManager.AddArg("-datadir=", "Specify data directory", ArgsManager::ALLOW_ANY, + OptionsCategory::OPTIONS); // Parse the command line args std::string error; @@ -49,11 +49,11 @@ std::tuple parse_cmdline(int argc, char* argv[]) return {datadir}; } // parse_cmdline() -int main(int argc, char* argv[]) -{ +int main(int argc, char* argv[]) { // Init prolog engine PL_set_resource_db_mem(resource_db_mem_bin, resource_db_mem_bin_len); - char *argv2[] = {(char*)"thisisnonsense", (char*)"-f", (char*)"none", (char*)"-F", (char*)"none", (char*)"-g", (char*)"true"}; + char* argv2[] = {(char*)"thisisnonsense", (char*)"-f", (char*)"none", (char*)"-F", + (char*)"none", (char*)"-g", (char*)"true"}; PlEngine engine(7, argv2); // Setup logger @@ -74,7 +74,7 @@ int main(int argc, char* argv[]) std::unique_ptr pWallet; pWallet = std::make_unique(config, btc_client); - //network::NetworkTransport& transport + // network::NetworkTransport& transport transport::ZComm zcomm{config}; @@ -84,33 +84,28 @@ int main(int argc, char* argv[]) std::string start_hash = config.genesis_block_hash(); uint32_t start_time = config.genesis_block_timestamp(); - if (start_height>0) - { + if (start_height > 0) { start_hash = current_blockchain_info["bestblockhash"].asString(); start_time = current_blockchain_info["time"].asUInt(); } - fbft::Replica2 replica{ - config, - blockchain, - *pWallet, - zcomm, - start_height, - start_hash, - start_time - }; + fbft::Replica2 replica{config, blockchain, *pWallet, zcomm, start_height, start_hash, start_time}; // Start the replica - zcomm.replica_message_received.connect([&replica](const std::string& group_name, const std::string& bin_buffer) { - auto p_msg = fbft::messages::Message::BuildFromBinBuffer(bin_buffer); - // TODO: far ritornare direttamente unique_ptr e fare check per nullptr - replica.ReceiveIncomingMessage(std::move(p_msg.value())); - }); - - zcomm.itcoinblock_received.connect([&replica](const std::string& hash_hex_string, int32_t block_height, uint32_t block_time, uint32_t seq_number) { - BOOST_LOG_TRIVIAL(info) << "Ricevuto nuovo blocco. Hash: " << hash_hex_string << ", altezza: " << block_height << ", block_time: " << block_time << ", seq_number " << seq_number; - auto p_msg = std::make_unique(block_height, block_time, hash_hex_string); - replica.ReceiveIncomingMessage(std::move(p_msg)); + zcomm.replica_message_received.connect( + [&replica](const std::string& group_name, const std::string& bin_buffer) { + auto p_msg = fbft::messages::Message::BuildFromBinBuffer(bin_buffer); + // TODO: far ritornare direttamente unique_ptr e fare check per nullptr + replica.ReceiveIncomingMessage(std::move(p_msg.value())); + }); + + zcomm.itcoinblock_received.connect([&replica](const std::string& hash_hex_string, int32_t block_height, + uint32_t block_time, uint32_t seq_number) { + BOOST_LOG_TRIVIAL(info) << "Ricevuto nuovo blocco. Hash: " << hash_hex_string + << ", altezza: " << block_height << ", block_time: " << block_time + << ", seq_number " << seq_number; + auto p_msg = std::make_unique(block_height, block_time, hash_hex_string); + replica.ReceiveIncomingMessage(std::move(p_msg)); }); zcomm.network_timeout_expired.connect([&replica]() { diff --git a/src/test/boilerplate.h b/src/test/boilerplate.h index 4d1eb38..8f9449a 100644 --- a/src/test/boilerplate.h +++ b/src/test/boilerplate.h @@ -16,16 +16,13 @@ namespace std { * * modified from: https://gist.github.com/mhamrah/79ed07a00209754a0ab1 */ -inline std::ostream& operator<<(std::ostream &ostr, nullopt_t const &nope) -{ +inline std::ostream& operator<<(std::ostream& ostr, nullopt_t const& nope) { ostr << "std::nullopt"; return ostr; } // operator<< for nullopt_t -template -inline std::ostream &operator<<(std::ostream &ostr, std::optional const &maybeItem) -{ +template inline std::ostream& operator<<(std::ostream& ostr, std::optional const& maybeItem) { if (maybeItem.has_value() == false) { ostr << std::nullopt; @@ -42,24 +39,21 @@ inline std::ostream &operator<<(std::ostream &ostr, std::optional const &mayb * * source: https://gist.github.com/mhamrah/79ed07a00209754a0ab1 */ -template -inline std::ostream &operator<<(std::ostream &str, std::vector const &items) -{ - str << '['; - bool first = true; - for (auto const& element : items) { - str << (!first ? "," : "") << element; - first = false; - } - return str << ']'; +template inline std::ostream& operator<<(std::ostream& str, std::vector const& items) { + str << '['; + bool first = true; + for (auto const& element : items) { + str << (!first ? "," : "") << element; + first = false; + } + return str << ']'; } // operator<< for std::vector /** * teach Boost.Test how to print std::unique_ptr */ template -inline std::ostream &operator<<(std::ostream &ostr, std::unique_ptr const &uniquePtr) -{ +inline std::ostream& operator<<(std::ostream& ostr, std::unique_ptr const& uniquePtr) { if (uniquePtr == nullptr) { ostr << "nullptr"; diff --git a/src/test/fixtures/BitcoinInfraFixture.cpp b/src/test/fixtures/BitcoinInfraFixture.cpp index 5f985a1..a44b0bb 100644 --- a/src/test/fixtures/BitcoinInfraFixture.cpp +++ b/src/test/fixtures/BitcoinInfraFixture.cpp @@ -3,25 +3,18 @@ #include "fixtures.h" -BitcoinInfraFixture::BitcoinInfraFixture(): -m_latest_block_time(0) -{ +BitcoinInfraFixture::BitcoinInfraFixture() : m_latest_block_time(0) { BOOST_LOG_TRIVIAL(info) << "Setup fixture BitcoinInfraFixture"; currentDirectory = boost::filesystem::absolute(boost::filesystem::path(".")); - for (size_t nodeId = 0; nodeId < CLUSTER_SIZE; ++nodeId) - { - try - { + for (size_t nodeId = 0; nodeId < CLUSTER_SIZE; ++nodeId) { + try { // If the node is not started, this will raise an exception m_bitcoinds.at(nodeId)->getblockchaininfo(); - } - catch (const std::exception &e) - { + } catch (const std::exception& e) { // We start the node only if it is not yet started auto currentBitcoinDir = currentDirectory / "infra" / getBitcoinNodeDirName(nodeId) / "signet"; // TODO, check how to handle reset=true; - if (m_reset) - { + if (m_reset) { resetBlockchain(currentBitcoinDir); } nodes.emplace_back( @@ -32,60 +25,51 @@ m_latest_block_time(0) sleep(4); } // BitcoinInfraFixture() -std::string BitcoinInfraFixture::getBitcoinNodeDirName(size_t nodeId) -{ +std::string BitcoinInfraFixture::getBitcoinNodeDirName(size_t nodeId) { std::stringstream ss; ss << "node" << std::setw(2) << std::setfill('0') << nodeId; return ss.str(); } // getBitcoinNodeDirName() -void BitcoinInfraFixture::resetBlockchain(boost::filesystem::path bitcoinDir) -{ +void BitcoinInfraFixture::resetBlockchain(boost::filesystem::path bitcoinDir) { boost::filesystem::directory_iterator end; // default construction yields past-the-end BOOST_LOG_TRIVIAL(info) << "Processing path " << bitcoinDir; - for (auto &entry : boost::make_iterator_range(boost::filesystem::directory_iterator(bitcoinDir), {})) - { + for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(bitcoinDir), {})) { auto curPath = entry.path(); auto curPathFilename = curPath.filename().string(); - if (curPathFilename != "wallets" and curPathFilename != "settings.json") - { + if (curPathFilename != "wallets" and curPathFilename != "settings.json") { BOOST_LOG_TRIVIAL(info) << "deleting " << curPathFilename; boost::filesystem::remove_all(curPath); } } } // resetBlockchain() -void BitcoinInfraFixture::stopProc(boost::process::child &nodeProc) -{ +void BitcoinInfraFixture::stopProc(boost::process::child& nodeProc) { auto pid = nodeProc.id(); BOOST_LOG_TRIVIAL(info) << "Sending SIGINT to pid " << pid; kill(pid, SIGINT); } // stopProc() -uint32_t BitcoinInfraFixture::get_present_block_time() -{ +uint32_t BitcoinInfraFixture::get_present_block_time() { const auto p1 = std::chrono::system_clock::now(); - uint32_t candidate_block_time = std::chrono::duration_cast(p1.time_since_epoch()).count(); - if (candidate_block_time<=m_latest_block_time) - { - candidate_block_time=m_latest_block_time+1; + uint32_t candidate_block_time = + std::chrono::duration_cast(p1.time_since_epoch()).count(); + if (candidate_block_time <= m_latest_block_time) { + candidate_block_time = m_latest_block_time + 1; } m_latest_block_time = candidate_block_time; return candidate_block_time; } -BitcoinInfraFixture::~BitcoinInfraFixture() -{ - for (auto &nodeProc : nodes) - { +BitcoinInfraFixture::~BitcoinInfraFixture() { + for (auto& nodeProc : nodes) { stopProc(nodeProc); } - for (auto &nodeProc : nodes) - { + for (auto& nodeProc : nodes) { nodeProc.wait(); } diff --git a/src/test/fixtures/BitcoinRpcTestFixture.cpp b/src/test/fixtures/BitcoinRpcTestFixture.cpp index 2c8a56f..e93cf37 100644 --- a/src/test/fixtures/BitcoinRpcTestFixture.cpp +++ b/src/test/fixtures/BitcoinRpcTestFixture.cpp @@ -3,16 +3,17 @@ #include "fixtures.h" -BitcoinRpcTestFixture::BitcoinRpcTestFixture() -{ - for (int i = 0; i < CLUSTER_SIZE; i++) - { +BitcoinRpcTestFixture::BitcoinRpcTestFixture() { + for (int i = 0; i < CLUSTER_SIZE; i++) { std::string config_suffix = str(boost::format("infra/node0%1%") % i); std::string config_path = (boost::filesystem::current_path() / config_suffix).string(); std::unique_ptr config = std::make_unique(config_path); - std::unique_ptr bitcoin = std::make_unique(config->itcoin_uri()); - std::unique_ptr wallet = std::make_unique(*config, *bitcoin); - std::unique_ptr blockchain = std::make_unique(*config, *bitcoin); + std::unique_ptr bitcoin = + std::make_unique(config->itcoin_uri()); + std::unique_ptr wallet = + std::make_unique(*config, *bitcoin); + std::unique_ptr blockchain = + std::make_unique(*config, *bitcoin); m_configs.emplace_back(move(config)); m_bitcoinds.emplace_back(move(bitcoin)); @@ -21,13 +22,11 @@ BitcoinRpcTestFixture::BitcoinRpcTestFixture() } } -BitcoinRpcTestFixture::~BitcoinRpcTestFixture() -{ +BitcoinRpcTestFixture::~BitcoinRpcTestFixture() { BOOST_LOG_TRIVIAL(info) << "Teardown BitcoinRpcTestFixture"; } -std::string BitcoinRpcTestFixture::address_at(uint32_t replica_id) -{ - auto &config = *m_configs.at(replica_id); +std::string BitcoinRpcTestFixture::address_at(uint32_t replica_id) { + auto& config = *m_configs.at(replica_id); return config.replica_set_v().at(config.id()).p2pkh(); } diff --git a/src/test/fixtures/BtcClientFixture.cpp b/src/test/fixtures/BtcClientFixture.cpp index 2562168..acae057 100644 --- a/src/test/fixtures/BtcClientFixture.cpp +++ b/src/test/fixtures/BtcClientFixture.cpp @@ -3,13 +3,12 @@ #include "fixtures.h" -BtcClientFixture::BtcClientFixture(): -cfgNode0(itcoin::FbftConfig((boost::filesystem::current_path() / "infra/node00").string())), bitcoind0(cfgNode0.itcoin_uri()) -{ +BtcClientFixture::BtcClientFixture() + : cfgNode0(itcoin::FbftConfig((boost::filesystem::current_path() / "infra/node00").string())), + bitcoind0(cfgNode0.itcoin_uri()) { BOOST_LOG_TRIVIAL(info) << "Setup fixture BtcClientFixture"; } -BtcClientFixture::~BtcClientFixture() -{ +BtcClientFixture::~BtcClientFixture() { BOOST_LOG_TRIVIAL(info) << "Teardown fixture BtcClientFixture"; } // ~BtcClientFixture() diff --git a/src/test/fixtures/PrologTestFixture.cpp b/src/test/fixtures/PrologTestFixture.cpp index 08f7389..91a7d27 100644 --- a/src/test/fixtures/PrologTestFixture.cpp +++ b/src/test/fixtures/PrologTestFixture.cpp @@ -3,16 +3,12 @@ #include "fixtures.h" -PrologTestFixture::PrologTestFixture() -{ -} +PrologTestFixture::PrologTestFixture() {} -PrologTestFixture::~PrologTestFixture() -{ +PrologTestFixture::~PrologTestFixture() { utf::test_case::id_t id = utf::framework::current_test_case().p_id; utf::test_results rez = utf::results_collector.results(id); - if (!rez.passed()) - { + if (!rez.passed()) { BOOST_LOG_TRIVIAL(debug) << "Test did not pass, dumping all the dynamic facts that I know..."; std::cout << std::endl << std::endl; PlCall("print_all_dynamics"); diff --git a/src/test/fixtures/ReplicaSetFixture.cpp b/src/test/fixtures/ReplicaSetFixture.cpp index 96560ec..ba7804f 100644 --- a/src/test/fixtures/ReplicaSetFixture.cpp +++ b/src/test/fixtures/ReplicaSetFixture.cpp @@ -3,10 +3,10 @@ #include "fixtures.h" -ReplicaSetFixture::ReplicaSetFixture(uint32_t cluster_size, uint32_t genesis_block_timestamp, uint32_t target_block_time): -ReplicaStateFixture(cluster_size, genesis_block_timestamp, target_block_time) { - for (int i = 0; i < CLUSTER_SIZE; i++) - { +ReplicaSetFixture::ReplicaSetFixture(uint32_t cluster_size, uint32_t genesis_block_timestamp, + uint32_t target_block_time) + : ReplicaStateFixture(cluster_size, genesis_block_timestamp, target_block_time) { + for (int i = 0; i < CLUSTER_SIZE; i++) { auto transport = std::make_unique(*m_configs.at(i)); m_transports.emplace_back(move(transport)); @@ -14,31 +14,27 @@ ReplicaStateFixture(cluster_size, genesis_block_timestamp, target_block_time) { uint32_t start_height = 0; uint32_t start_time = m_configs.at(i)->genesis_block_timestamp(); std::shared_ptr replica = - std::make_shared(*m_configs.at(i), *m_blockchain, *m_wallets.at(i), *m_transports.at(i), start_height, start_hash, start_time); + std::make_shared(*m_configs.at(i), *m_blockchain, *m_wallets.at(i), *m_transports.at(i), + start_height, start_hash, start_time); m_replica.emplace_back(replica); } - for (auto p_replica : m_replica) - { + for (auto p_replica : m_replica) { p_replica->set_synthetic_time(0); m_blockchain->listeners.push_back(p_replica); - for (int i = 0; i < CLUSTER_SIZE; i++) - { + for (int i = 0; i < CLUSTER_SIZE; i++) { m_transports.at(i)->listeners.push_back(p_replica); } } } void ReplicaSetFixture::kill(uint32_t replica_id) { - if (!m_transports.at(replica_id)->active) - { - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% is already sleeping.") % replica_id); + if (!m_transports.at(replica_id)->active) { + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% is already sleeping.") % replica_id); return; } - BOOST_LOG_TRIVIAL(info) << str( - boost::format("R%1% going to sleep now.") % replica_id); + BOOST_LOG_TRIVIAL(info) << str(boost::format("R%1% going to sleep now.") % replica_id); auto replica_to_remove = m_replica[replica_id]; @@ -48,58 +44,47 @@ void ReplicaSetFixture::kill(uint32_t replica_id) { m_transports.at(replica_id)->active = false; - for (auto &transport : m_transports) - { + for (auto& transport : m_transports) { transport->listeners.erase( std::remove(transport->listeners.begin(), transport->listeners.end(), replica_to_remove), transport->listeners.end()); } } -void ReplicaSetFixture::wake(uint32_t replica_id) -{ - if (m_transports.at(replica_id)->active) - { - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% is already awake.") % replica_id); +void ReplicaSetFixture::wake(uint32_t replica_id) { + if (m_transports.at(replica_id)->active) { + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% is already awake.") % replica_id); return; } - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% wakes up.") % replica_id); + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% wakes up.") % replica_id); auto replica_to_add = m_replica[replica_id]; m_transports.at(replica_id)->active = true; - for (auto &transport : m_transports) - { + for (auto& transport : m_transports) { transport->listeners.insert(transport->listeners.begin() + replica_id, replica_to_add); } // Reactivate blockchain and sync last block m_blockchain->listeners.insert(m_blockchain->listeners.begin() + replica_id, m_replica[replica_id]); - for (size_t i = std::max((int)m_blockchain->chain.size() - 3, 0); i < m_blockchain->chain.size(); i++) - { - std::unique_ptr p_msg = std::make_unique(i, m_blockchain->chain[i].nTime, m_blockchain->chain[i].GetHash().GetHex()); + for (size_t i = std::max((int)m_blockchain->chain.size() - 3, 0); i < m_blockchain->chain.size(); i++) { + std::unique_ptr p_msg = + std::make_unique(i, m_blockchain->chain[i].nTime, m_blockchain->chain[i].GetHash().GetHex()); m_blockchain->listeners[replica_id]->ReceiveIncomingMessage(move(p_msg)); } } -void ReplicaSetFixture::move_forward(int time_delta) -{ - for (size_t i = 0; i < CLUSTER_SIZE; i++) - { - if (m_transports[i]->active) - { +void ReplicaSetFixture::move_forward(int time_delta) { + for (size_t i = 0; i < CLUSTER_SIZE; i++) { + if (m_transports[i]->active) { m_replica[i]->CheckTimedActions(); } } // SimulateReceiveMessages all transports N times - for (uint32_t N = 0; N < 10; N++) - { - for (size_t i = 0; i < CLUSTER_SIZE; i++) - { + for (uint32_t N = 0; N < 10; N++) { + for (size_t i = 0; i < CLUSTER_SIZE; i++) { m_transports[i]->SimulateReceiveMessages(); } } diff --git a/src/test/fixtures/ReplicaStateFixture.cpp b/src/test/fixtures/ReplicaStateFixture.cpp index 952e26e..d00b44a 100644 --- a/src/test/fixtures/ReplicaStateFixture.cpp +++ b/src/test/fixtures/ReplicaStateFixture.cpp @@ -3,16 +3,16 @@ #include "fixtures.h" -ReplicaStateFixture::ReplicaStateFixture(uint32_t cluster_size, uint32_t genesis_block_timestamp, uint32_t target_block_time): -PrologTestFixture(), CLUSTER_SIZE(cluster_size), GENESIS_BLOCK_TIMESTAMP(genesis_block_timestamp), TARGET_BLOCK_TIME(target_block_time) -{ +ReplicaStateFixture::ReplicaStateFixture(uint32_t cluster_size, uint32_t genesis_block_timestamp, + uint32_t target_block_time) + : PrologTestFixture(), CLUSTER_SIZE(cluster_size), GENESIS_BLOCK_TIMESTAMP(genesis_block_timestamp), + TARGET_BLOCK_TIME(target_block_time) { BOOST_LOG_TRIVIAL(trace) << "Setup fixture ReplicaSetFixture"; m_blockchain_config = std::make_unique("infra/node00"); m_blockchain_config->set_genesis_block_timestamp(GENESIS_BLOCK_TIMESTAMP); m_blockchain = std::make_unique(*m_blockchain_config); - for (int i = 0; i < CLUSTER_SIZE; i++) - { + for (int i = 0; i < CLUSTER_SIZE; i++) { auto config = std::make_unique("infra/node00"); config->set_replica_id(i); config->set_cluster_size(CLUSTER_SIZE); @@ -29,18 +29,16 @@ PrologTestFixture(), CLUSTER_SIZE(cluster_size), GENESIS_BLOCK_TIMESTAMP(genesis std::string start_hash = m_configs.at(i)->genesis_block_hash(); uint32_t start_height = 0; uint32_t start_time = m_configs.at(i)->genesis_block_timestamp(); - std::unique_ptr state = - std::make_unique(*m_configs.at(i), *m_blockchain, *m_wallets.at(i), start_height, start_hash, start_time); + std::unique_ptr state = std::make_unique( + *m_configs.at(i), *m_blockchain, *m_wallets.at(i), start_height, start_hash, start_time); state->set_synthetic_time(0); m_states.emplace_back(move(state)); } } -void ReplicaStateFixture::set_synthetic_time(double time) -{ - for (auto &p_state : m_states) - { +void ReplicaStateFixture::set_synthetic_time(double time) { + for (auto& p_state : m_states) { p_state->set_synthetic_time(time); } } diff --git a/src/test/fixtures/fixtures.h b/src/test/fixtures/fixtures.h index 159c2aa..a1cefc8 100644 --- a/src/test/fixtures/fixtures.h +++ b/src/test/fixtures/fixtures.h @@ -6,8 +6,8 @@ #include #include -#include #include +#include /* * As of boost 1.75, boost::process relies on boost::filesystem and is not able * to deal with std::filesystem @@ -19,11 +19,11 @@ #include -#include "config/FbftConfig.h" #include "../../fbft/Replica2.h" #include "../../fbft/actions/actions.h" #include "../../fbft/state/state.h" #include "../../transport/btcclient.h" +#include "config/FbftConfig.h" #include "../stubs/stubs.h" @@ -35,8 +35,7 @@ using namespace itcoin::fbft::messages; using namespace itcoin::fbft::state; using namespace itcoin::test; -struct BtcClientFixture -{ +struct BtcClientFixture { itcoin::FbftConfig cfgNode0; itcoin::transport::BtcClient bitcoind0; @@ -44,8 +43,7 @@ struct BtcClientFixture ~BtcClientFixture(); }; -struct BitcoinRpcTestFixture -{ +struct BitcoinRpcTestFixture { BitcoinRpcTestFixture(); ~BitcoinRpcTestFixture(); std::string address_at(uint32_t replica_id); @@ -57,14 +55,12 @@ struct BitcoinRpcTestFixture std::vector> m_blockchains; }; -struct PrologTestFixture -{ +struct PrologTestFixture { PrologTestFixture(); ~PrologTestFixture(); }; -struct ReplicaStateFixture : PrologTestFixture -{ +struct ReplicaStateFixture : PrologTestFixture { ReplicaStateFixture(uint32_t cluster_size, uint32_t genesis_block_timestamp, uint32_t target_block_time); void set_synthetic_time(double time); @@ -82,8 +78,7 @@ struct ReplicaStateFixture : PrologTestFixture std::vector> m_states; }; // ReplicaStateFixture -struct ReplicaSetFixture : ReplicaStateFixture -{ +struct ReplicaSetFixture : ReplicaStateFixture { ReplicaSetFixture(uint32_t cluster_size, uint32_t genesis_block_timestamp, uint32_t target_block_time); void kill(uint32_t replica_id); @@ -94,8 +89,7 @@ struct ReplicaSetFixture : ReplicaStateFixture std::vector> m_replica; }; -struct BitcoinInfraFixture : public BitcoinRpcTestFixture -{ +struct BitcoinInfraFixture : public BitcoinRpcTestFixture { std::vector nodes; boost::filesystem::path currentDirectory; @@ -109,7 +103,7 @@ struct BitcoinInfraFixture : public BitcoinRpcTestFixture void resetBlockchain(boost::filesystem::path bitcoinDir); - void stopProc(boost::process::child &nodeProc); + void stopProc(boost::process::child& nodeProc); uint32_t get_present_block_time(); diff --git a/src/test/stubs/DummyBlockchain.cpp b/src/test/stubs/DummyBlockchain.cpp index b7c5bdb..f66fed6 100644 --- a/src/test/stubs/DummyBlockchain.cpp +++ b/src/test/stubs/DummyBlockchain.cpp @@ -16,14 +16,9 @@ using namespace itcoin::network; namespace itcoin { namespace test { -DummyBlockchain::DummyBlockchain(const itcoin::FbftConfig& conf): -Blockchain(conf) -{ - Init(); -} +DummyBlockchain::DummyBlockchain(const itcoin::FbftConfig& conf) : Blockchain(conf) { Init(); } -void DummyBlockchain::Init() -{ +void DummyBlockchain::Init() { chain.clear(); CBlock genesis = CBlock{}; genesis.nTime = m_conf.genesis_block_timestamp(); @@ -36,37 +31,32 @@ CBlock DummyBlockchain::GenerateBlock(uint32_t block_timestamp) { return block; } -bool DummyBlockchain::TestBlockValidity(const uint32_t height, const CBlock& block, bool check_signet_solution) -{ +bool DummyBlockchain::TestBlockValidity(const uint32_t height, const CBlock& block, + bool check_signet_solution) { return true; } -void DummyBlockchain::SubmitBlock(const uint32_t height, const CBlock& block) -{ +void DummyBlockchain::SubmitBlock(const uint32_t height, const CBlock& block) { BOOST_LOG_TRIVIAL(debug) << "Submitting a block to blockchain"; CBlock b_copy{block}; - if( height < chain.size() && chain[height].GetHash() != block.GetHash() ) - { + if (height < chain.size() && chain[height].GetHash() != block.GetHash()) { throw runtime_error("submitting a different block at same height, double spending!"); } - if( height < chain.size() && chain[height].GetHash() == block.GetHash() ) - { + if (height < chain.size() && chain[height].GetHash() == block.GetHash()) { BOOST_LOG_TRIVIAL(debug) << "Block already present in the blockchain"; return; } - if (height > chain.size()) - { + if (height > chain.size()) { throw runtime_error("submitting a block at height too far in the future, invalid chain!"); } chain.emplace_back(b_copy); - for (shared_ptr p_listener: listeners) - { + for (shared_ptr p_listener : listeners) { unique_ptr p_msg = make_unique(height, b_copy.nTime, b_copy.GetHash().GetHex()); p_listener->ReceiveIncomingMessage(move(p_msg)); } } -} -} +} // namespace test +} // namespace itcoin diff --git a/src/test/stubs/DummyNetwork.cpp b/src/test/stubs/DummyNetwork.cpp index a0d98ca..14f512c 100644 --- a/src/test/stubs/DummyNetwork.cpp +++ b/src/test/stubs/DummyNetwork.cpp @@ -8,7 +8,7 @@ #include "config/FbftConfig.h" -namespace msgs=itcoin::fbft::messages; +namespace msgs = itcoin::fbft::messages; using namespace std; using namespace itcoin::network; @@ -16,39 +16,26 @@ using namespace itcoin::network; namespace itcoin { namespace test { -NetworkStub::NetworkStub(): -active(true) -{ +NetworkStub::NetworkStub() : active(true) {} -} - -DummyNetwork::DummyNetwork(const itcoin::FbftConfig& conf): -NetworkTransport(conf) -{ -} +DummyNetwork::DummyNetwork(const itcoin::FbftConfig& conf) : NetworkTransport(conf) {} -void DummyNetwork::BroadcastMessage(std::unique_ptr p_msg) -{ - if (!active) return; +void DummyNetwork::BroadcastMessage(std::unique_ptr p_msg) { + if (!active) + return; - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% Transport, broadcasting %2% to other replicas.") - % p_msg->sender_id() - % p_msg->identify() - ); + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% Transport, broadcasting %2% to other replicas.") % + p_msg->sender_id() % p_msg->identify()); m_buffer.emplace_back(move(p_msg)); } -void DummyNetwork::SimulateReceiveMessages() -{ - if (!active) return; +void DummyNetwork::SimulateReceiveMessages() { + if (!active) + return; - for (auto& p_msg: m_buffer) - { - for (shared_ptr p_listener: listeners) - { - if (p_listener->id() != m_conf.id()) - { + for (auto& p_msg : m_buffer) { + for (shared_ptr p_listener : listeners) { + if (p_listener->id() != m_conf.id()) { unique_ptr p_msg_clone = p_msg->clone(); p_listener->ReceiveIncomingMessage(move(p_msg_clone)); } @@ -57,5 +44,5 @@ void DummyNetwork::SimulateReceiveMessages() m_buffer.clear(); } -} -} +} // namespace test +} // namespace itcoin diff --git a/src/test/stubs/DummyRoastWallet.cpp b/src/test/stubs/DummyRoastWallet.cpp index 6a9af0d..a32f9a8 100644 --- a/src/test/stubs/DummyRoastWallet.cpp +++ b/src/test/stubs/DummyRoastWallet.cpp @@ -15,121 +15,85 @@ using namespace std; namespace itcoin { namespace test { -DummyRoastWallet::DummyRoastWallet(const itcoin::FbftConfig& conf): -Wallet(conf), RoastWallet(conf) -{ +DummyRoastWallet::DummyRoastWallet(const itcoin::FbftConfig& conf) : Wallet(conf), RoastWallet(conf) { // Init state state_i = 0; // Declare the dynamic wallets predicates - PlCall("assertz", PlTermv(PlCompound( - "(roast_crypto_pre_sig_aggregate(Replica_id, Pre_signature_shares, Pre_signature) :- roast_crypto_pre_sig_aggregate_dummy(Replica_id, Pre_signature_shares, Pre_signature))" - ))); + PlCall("assertz", + PlTermv(PlCompound( + "(roast_crypto_pre_sig_aggregate(Replica_id, Pre_signature_shares, Pre_signature) :- " + "roast_crypto_pre_sig_aggregate_dummy(Replica_id, Pre_signature_shares, Pre_signature))"))); } -void DummyRoastWallet::AppendSignature(msgs::Message& message) const -{ - string sig = str( - boost::format("Sig_%1%") - % message.sender_id() - ); +void DummyRoastWallet::AppendSignature(msgs::Message& message) const { + string sig = str(boost::format("Sig_%1%") % message.sender_id()); message.set_signature(sig); } -bool DummyRoastWallet::VerifySignature(const msgs::Message& message) const -{ - string expected_sig = str( - boost::format("Sig_%1%") - % message.sender_id() - ); - if ( message.signature() == expected_sig ) - { +bool DummyRoastWallet::VerifySignature(const msgs::Message& message) const { + string expected_sig = str(boost::format("Sig_%1%") % message.sender_id()); + if (message.signature() == expected_sig) { return true; - } - else - { + } else { return false; } } -CBlock DummyRoastWallet::FinalizeBlock(const CBlock& block, const std::string pre_sig, const std::vector sig_shares) const -{ +CBlock DummyRoastWallet::FinalizeBlock(const CBlock& block, const std::string pre_sig, + const std::vector sig_shares) const { string msg = str( - boost::format("FinalizeBlock Replica_id=%1%, state=%2%, presig=%3%, shares=%4%, block=%5%") - % m_conf.id() - % state_i - % pre_sig - % boost::algorithm::join(sig_shares, ",") - % block.GetHash().GetHex() - ); + boost::format("FinalizeBlock Replica_id=%1%, state=%2%, presig=%3%, shares=%4%, block=%5%") % + m_conf.id() % state_i % pre_sig % boost::algorithm::join(sig_shares, ",") % block.GetHash().GetHex()); BOOST_LOG_TRIVIAL(trace) << msg; CBlock signed_block(block); return signed_block; } -std::string DummyRoastWallet::GetPreSignatureShare() -{ - string presig = str( - boost::format("Pre_share_%1%_%2%") - % m_conf.id() - % state_i - ); +std::string DummyRoastWallet::GetPreSignatureShare() { + string presig = str(boost::format("Pre_share_%1%_%2%") % m_conf.id() % state_i); - string msg = str( - boost::format("GetPreSignatureShare Replica_id=%1%, State_i=%2%, Presig=%3%") - % m_conf.id() - % state_i - % presig - ); + string msg = str(boost::format("GetPreSignatureShare Replica_id=%1%, State_i=%2%, Presig=%3%") % + m_conf.id() % state_i % presig); BOOST_LOG_TRIVIAL(trace) << msg; state_i++; return presig; } -std::string DummyRoastWallet::GetSignatureShare(std::vector signers, std::string pre_signature, const CBlock& block) -{ +std::string DummyRoastWallet::GetSignatureShare(std::vector signers, std::string pre_signature, + const CBlock& block) { std::stringstream signers_stream; std::copy(signers.begin(), signers.end(), std::ostream_iterator(signers_stream, ",")); string signers_str = signers_stream.str(); signers_str.pop_back(); - string sig_share = str( - boost::format("Sig_share_%1%_[%2%]") - % m_conf.id() - % signers_str - ); + string sig_share = str(boost::format("Sig_share_%1%_[%2%]") % m_conf.id() % signers_str); - string msg = str( - boost::format("GetSignatureShare Replica_id=%1%, State_i=%2%, Signers=%3%, pre_signature=%4%, block=%5%, sigshare=%6%") - % m_conf.id() - % state_i - % signers_str - % pre_signature - % block.GetHash().GetHex() - % sig_share - ); + string msg = + str(boost::format("GetSignatureShare Replica_id=%1%, State_i=%2%, Signers=%3%, pre_signature=%4%, " + "block=%5%, sigshare=%6%") % + m_conf.id() % state_i % signers_str % pre_signature % block.GetHash().GetHex() % sig_share); BOOST_LOG_TRIVIAL(trace) << msg; return sig_share; } -PREDICATE(roast_crypto_pre_sig_aggregate_dummy, 3) -{ +PREDICATE(roast_crypto_pre_sig_aggregate_dummy, 3) { BOOST_LOG_TRIVIAL(debug) << "I am in the prolog predicate roast_crypto_pre_sig_aggregate"; string a3_result = ""; - PlTail Presig_shares{PL_A2}; PlTerm Presig_elem; - while(Presig_shares.next(Presig_elem)) - { - string presig = std::string{(const char*) Presig_elem}; + PlTail Presig_shares{PL_A2}; + PlTerm Presig_elem; + while (Presig_shares.next(Presig_elem)) { + string presig = std::string{(const char*)Presig_elem}; a3_result += presig; a3_result += "+"; } a3_result.pop_back(); PlTerm Pre_signature = PL_A3; - PL_A3 = PlString((const char*) a3_result.c_str()); + PL_A3 = PlString((const char*)a3_result.c_str()); return true; } -} -} +} // namespace test +} // namespace itcoin diff --git a/src/test/stubs/DummyWallet.cpp b/src/test/stubs/DummyWallet.cpp index a3056d2..a8e7461 100644 --- a/src/test/stubs/DummyWallet.cpp +++ b/src/test/stubs/DummyWallet.cpp @@ -14,39 +14,23 @@ using namespace std; namespace itcoin { namespace test { -DummyWallet::DummyWallet(const itcoin::FbftConfig& conf): -Wallet(conf) -{ +DummyWallet::DummyWallet(const itcoin::FbftConfig& conf) : Wallet(conf) {} -} - -void DummyWallet::AppendSignature(msgs::Message& message) const -{ - string sig = str( - boost::format("Sig_%1%") - % message.sender_id() - ); +void DummyWallet::AppendSignature(msgs::Message& message) const { + string sig = str(boost::format("Sig_%1%") % message.sender_id()); message.set_signature(sig); } -bool DummyWallet::VerifySignature(const msgs::Message& message) const -{ - string expected_sig = str( - boost::format("Sig_%1%") - % message.sender_id() - ); - if ( message.signature() == expected_sig ) - { +bool DummyWallet::VerifySignature(const msgs::Message& message) const { + string expected_sig = str(boost::format("Sig_%1%") % message.sender_id()); + if (message.signature() == expected_sig) { return true; - } - else - { + } else { return false; } } -std::string DummyWallet::GetBlockSignature(const CBlock& block) -{ +std::string DummyWallet::GetBlockSignature(const CBlock& block) { auto rawTx = CMutableTransaction(); rawTx.nVersion = 0; rawTx.nLockTime = 0; @@ -55,12 +39,10 @@ std::string DummyWallet::GetBlockSignature(const CBlock& block) return "psbtx"; } -CBlock DummyWallet::FinalizeBlock(const CBlock& block, - const std::vector signatures) const -{ +CBlock DummyWallet::FinalizeBlock(const CBlock& block, const std::vector signatures) const { CBlock signed_block(block); return signed_block; } -} -} +} // namespace test +} // namespace itcoin diff --git a/src/test/stubs/stubs.h b/src/test/stubs/stubs.h index b8fe5fe..5a2a750 100644 --- a/src/test/stubs/stubs.h +++ b/src/test/stubs/stubs.h @@ -10,7 +10,7 @@ #include "../../transport/network.h" #include "../../wallet/wallet.h" -namespace messages=itcoin::fbft::messages; +namespace messages = itcoin::fbft::messages; namespace blockchain = itcoin::blockchain; namespace network = itcoin::network; @@ -19,73 +19,69 @@ namespace wallet = itcoin::wallet; namespace itcoin { namespace test { -class NetworkStub -{ - public: - NetworkStub(); +class NetworkStub { +public: + NetworkStub(); - std::vector> listeners; - bool active; + std::vector> listeners; + bool active; }; -class DummyNetwork: public network::NetworkTransport, public NetworkStub -{ - public: - DummyNetwork(const itcoin::FbftConfig& conf); - void BroadcastMessage(std::unique_ptr p_msg); - void SimulateReceiveMessages(); +class DummyNetwork : public network::NetworkTransport, public NetworkStub { +public: + DummyNetwork(const itcoin::FbftConfig& conf); + void BroadcastMessage(std::unique_ptr p_msg); + void SimulateReceiveMessages(); - private: - std::vector> m_buffer; +private: + std::vector> m_buffer; }; -class DummyBlockchain: public blockchain::Blockchain, public NetworkStub -{ - public: - DummyBlockchain(const itcoin::FbftConfig& conf); +class DummyBlockchain : public blockchain::Blockchain, public NetworkStub { +public: + DummyBlockchain(const itcoin::FbftConfig& conf); - void set_genesis_block_timestamp(double genesis_block_timestamp); + void set_genesis_block_timestamp(double genesis_block_timestamp); - CBlock GenerateBlock(uint32_t block_timestamp); - bool TestBlockValidity(const uint32_t height, const CBlock&, bool check_signet_solution); - void SubmitBlock(const uint32_t height, const CBlock&); - uint32_t height(){ return chain.size()-1; } + CBlock GenerateBlock(uint32_t block_timestamp); + bool TestBlockValidity(const uint32_t height, const CBlock&, bool check_signet_solution); + void SubmitBlock(const uint32_t height, const CBlock&); + uint32_t height() { return chain.size() - 1; } - // Public attributes - std::vector chain; + // Public attributes + std::vector chain; - private: - void Init(); +private: + void Init(); }; -class DummyWallet: public wallet::Wallet -{ - public: - DummyWallet(const itcoin::FbftConfig& conf); - void AppendSignature(messages::Message& message) const; - bool VerifySignature(const messages::Message& message) const; +class DummyWallet : public wallet::Wallet { +public: + DummyWallet(const itcoin::FbftConfig& conf); + void AppendSignature(messages::Message& message) const; + bool VerifySignature(const messages::Message& message) const; - std::string GetBlockSignature(const CBlock&); - CBlock FinalizeBlock(const CBlock&, const std::vector) const; + std::string GetBlockSignature(const CBlock&); + CBlock FinalizeBlock(const CBlock&, const std::vector) const; }; -class DummyRoastWallet: public wallet::RoastWallet -{ +class DummyRoastWallet : public wallet::RoastWallet { int state_i; - public: - DummyRoastWallet(const itcoin::FbftConfig& conf); +public: + DummyRoastWallet(const itcoin::FbftConfig& conf); - void AppendSignature(messages::Message& message) const override; - bool VerifySignature(const messages::Message& message) const override; + void AppendSignature(messages::Message& message) const override; + bool VerifySignature(const messages::Message& message) const override; - CBlock FinalizeBlock(const CBlock&, const std::string, const std::vector) const override; + CBlock FinalizeBlock(const CBlock&, const std::string, const std::vector) const override; - std::string GetPreSignatureShare() override; - std::string GetSignatureShare(std::vector signers, std::string pre_signature, const CBlock&) override; + std::string GetPreSignatureShare() override; + std::string GetSignatureShare(std::vector signers, std::string pre_signature, + const CBlock&) override; }; -} -} +} // namespace test +} // namespace itcoin #endif diff --git a/src/test/test_blockchain_frost_wallet_bitcoin.cpp b/src/test/test_blockchain_frost_wallet_bitcoin.cpp index fba0f10..8682e4d 100644 --- a/src/test/test_blockchain_frost_wallet_bitcoin.cpp +++ b/src/test/test_blockchain_frost_wallet_bitcoin.cpp @@ -3,11 +3,11 @@ #include +#include +#include #include #include #include -#include -#include #include "fixtures/fixtures.h" @@ -18,17 +18,15 @@ BOOST_AUTO_TEST_SUITE(test_blockchain_frost_wallet_bitcoin, *utf::enabled()) using namespace itcoin::blockchain; using namespace itcoin::fbft::messages; -struct Replica4Fixture: BitcoinInfraFixture { Replica4Fixture(): BitcoinInfraFixture() {} }; +struct Replica4Fixture : BitcoinInfraFixture { + Replica4Fixture() : BitcoinInfraFixture() {} +}; -BOOST_FIXTURE_TEST_CASE(test_blockchain_frost_wallet_bitcoin_00, Replica4Fixture) -{ - boost::log::core::get()->set_filter ( - boost::log::trivial::severity >= boost::log::trivial::trace - ); +BOOST_FIXTURE_TEST_CASE(test_blockchain_frost_wallet_bitcoin_00, Replica4Fixture) { + boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::trace); std::vector> frost_wallets; - for (int i = 0; i < CLUSTER_SIZE; i++) - { + for (int i = 0; i < CLUSTER_SIZE; i++) { auto wallet = std::make_unique(*m_configs[i], *m_bitcoinds[i]); frost_wallets.emplace_back(move(wallet)); } @@ -37,20 +35,19 @@ BOOST_FIXTURE_TEST_CASE(test_blockchain_frost_wallet_bitcoin_00, Replica4Fixture { BOOST_LOG_TRIVIAL(debug) << "Testing presignature generation"; std::string preSignature = frost_wallets[0]->GetPreSignatureShare(); - BOOST_TEST( preSignature.empty() == false ); + BOOST_TEST(preSignature.empty() == false); } - { + { BOOST_LOG_TRIVIAL(debug) << "Testing subsequent presignatures to be different"; std::string preSignature1 = frost_wallets[0]->GetPreSignatureShare(); std::string preSignature2 = frost_wallets[0]->GetPreSignatureShare(); - BOOST_TEST( preSignature1 != preSignature2 ); + BOOST_TEST(preSignature1 != preSignature2); } { BOOST_LOG_TRIVIAL(debug) << "Testing presignature serialization format"; - for (int i = 0; i < CLUSTER_SIZE; i++) - { + for (int i = 0; i < CLUSTER_SIZE; i++) { std::string preSignature = frost_wallets[i]->GetPreSignatureShare(); - BOOST_TEST( preSignature.empty() == false ); + BOOST_TEST(preSignature.empty() == false); BOOST_LOG_TRIVIAL(debug) << "Deserializing commitments: " << preSignature; BOOST_TEST(preSignature.find(std::to_string(i + 1) + "::") != std::string::npos); } @@ -73,11 +70,13 @@ BOOST_FIXTURE_TEST_CASE(test_blockchain_frost_wallet_bitcoin_00, Replica4Fixture std::vector signers; std::string pre_signatures = ""; CBlock block; - BOOST_CHECK_THROW(frost_wallets[0]->GetSignatureShare(signers, pre_signatures, block), std::runtime_error); + BOOST_CHECK_THROW(frost_wallets[0]->GetSignatureShare(signers, pre_signatures, block), + std::runtime_error); } // GetSignatureShare: try to sign with less presignatures that needed { - BOOST_LOG_TRIVIAL(debug) << "Testing GetSignatureShare: generate signature share with below threshold presignatures (expect no error)"; + BOOST_LOG_TRIVIAL(debug) << "Testing GetSignatureShare: generate signature share with below threshold " + "presignatures (expect no error)"; std::vector signers; std::string pre_signatures = ""; CBlock block; @@ -91,20 +90,20 @@ BOOST_FIXTURE_TEST_CASE(test_blockchain_frost_wallet_bitcoin_00, Replica4Fixture } // GetSignatureShare: check that each participant generates its signature_response { - BOOST_LOG_TRIVIAL(debug) << "Testing GetSignatureShare: each participant should generate its signature_response"; + BOOST_LOG_TRIVIAL(debug) + << "Testing GetSignatureShare: each participant should generate its signature_response"; std::vector signers; std::string pre_signatures = ""; CBlock block; // Concatenate presignatures as done in prolog - for (int i = 0; i < CLUSTER_SIZE; i++) - { - if (i > 0) pre_signatures.append("+"); + for (int i = 0; i < CLUSTER_SIZE; i++) { + if (i > 0) + pre_signatures.append("+"); pre_signatures.append(frost_wallets[i]->GetPreSignatureShare()); } // GetSignatureShare - for (int i = 0; i < CLUSTER_SIZE; i++) - { + for (int i = 0; i < CLUSTER_SIZE; i++) { // FIXME: why do we need the set of signers? pre_signature already includes it. std::string nodeSignature = frost_wallets[i]->GetSignatureShare(signers, pre_signatures, block); @@ -122,15 +121,14 @@ BOOST_FIXTURE_TEST_CASE(test_blockchain_frost_wallet_bitcoin_00, Replica4Fixture CBlock block = m_blockchains.at(0)->GenerateBlock(get_present_block_time()); // Concatenate PreSignatures as done in prolog - for (int i = 0; i < CLUSTER_SIZE; i++) - { - if (i > 0) pre_signatures.append("+"); + for (int i = 0; i < CLUSTER_SIZE; i++) { + if (i > 0) + pre_signatures.append("+"); pre_signatures.append(frost_wallets[i]->GetPreSignatureShare()); } // GetSignatureShare std::vector signature_shares; - for (int i = 0; i < CLUSTER_SIZE; i++) - { + for (int i = 0; i < CLUSTER_SIZE; i++) { std::string nodeSignature = frost_wallets[i]->GetSignatureShare(signers, pre_signatures, block); BOOST_TEST(nodeSignature.empty() == false); signature_shares.push_back(nodeSignature); @@ -149,120 +147,118 @@ BOOST_FIXTURE_TEST_CASE(test_blockchain_frost_wallet_bitcoin_00, Replica4Fixture BOOST_TEST(height_1 == height_0 + 1); } - // FinalizeBlock: primary aggregates signatures of other participants - { // Assumption: we generated keys to allow a 2-4 threshold signature. Two participants can generate a valid signature. - BOOST_LOG_TRIVIAL(debug) << "Testing FinalizeBlock to aggregate signatures from other nodes but itself"; - std::vector signers; - std::string pre_signatures = ""; - CBlock block = m_blockchains.at(0)->GenerateBlock(get_present_block_time()); - - // Concatenate PreSignatures as done in prolog - for (int i = 0; i < CLUSTER_SIZE; i++) - { - auto presignature = frost_wallets[i]->GetPreSignatureShare(); - if (i == 1) - pre_signatures.append(presignature); - if (i == 2) - { - pre_signatures.append("+"); - pre_signatures.append(presignature); - } + // FinalizeBlock: primary aggregates signatures of other participants + { // Assumption: we generated keys to allow a 2-4 threshold signature. Two participants can generate a valid + // signature. + BOOST_LOG_TRIVIAL(debug) << "Testing FinalizeBlock to aggregate signatures from other nodes but itself"; + std::vector signers; + std::string pre_signatures = ""; + CBlock block = m_blockchains.at(0)->GenerateBlock(get_present_block_time()); + + // Concatenate PreSignatures as done in prolog + for (int i = 0; i < CLUSTER_SIZE; i++) { + auto presignature = frost_wallets[i]->GetPreSignatureShare(); + if (i == 1) + pre_signatures.append(presignature); + if (i == 2) { + pre_signatures.append("+"); + pre_signatures.append(presignature); } - // GetSignatureShare: only 1 node signs - std::vector signature_shares; - std::string nodeSignature1 = frost_wallets[1]->GetSignatureShare(signers, pre_signatures, block); - signature_shares.push_back(nodeSignature1); - std::string nodeSignature2 = frost_wallets[2]->GetSignatureShare(signers, pre_signatures, block); - signature_shares.push_back(nodeSignature2); + } + // GetSignatureShare: only 1 node signs + std::vector signature_shares; + std::string nodeSignature1 = frost_wallets[1]->GetSignatureShare(signers, pre_signatures, block); + signature_shares.push_back(nodeSignature1); + std::string nodeSignature2 = frost_wallets[2]->GetSignatureShare(signers, pre_signatures, block); + signature_shares.push_back(nodeSignature2); - CBlock final_block = frost_wallets[0]->FinalizeBlock(block, pre_signatures, signature_shares); + CBlock final_block = frost_wallets[0]->FinalizeBlock(block, pre_signatures, signature_shares); + + auto info_0 = m_bitcoinds.at(0)->getblockchaininfo(); + auto height_0 = info_0["blocks"].asUInt(); - auto info_0 = m_bitcoinds.at(0)->getblockchaininfo(); - auto height_0 = info_0["blocks"].asUInt(); + m_blockchains.at(0)->SubmitBlock(0, final_block); - m_blockchains.at(0)->SubmitBlock(0, final_block); + auto info_1 = m_bitcoinds.at(0)->getblockchaininfo(); + auto height_1 = info_1["blocks"].asUInt(); - auto info_1 = m_bitcoinds.at(0)->getblockchaininfo(); - auto height_1 = info_1["blocks"].asUInt(); + BOOST_TEST(height_1 == height_0 + 1); + } - BOOST_TEST(height_1 == height_0 + 1); - } + // FinalizeBlock: out of order presignatures + { // Assumption: we generated keys to allow a 2-4 threshold signature. Two participants can generate a valid + // signature. + BOOST_LOG_TRIVIAL(debug) << "Testing FinalizeBlock to aggregate signatures from other nodes but itself"; + std::vector signers; + std::string pre_signatures = ""; + CBlock block = m_blockchains.at(0)->GenerateBlock(get_present_block_time()); - // FinalizeBlock: out of order presignatures - { // Assumption: we generated keys to allow a 2-4 threshold signature. Two participants can generate a valid signature. - BOOST_LOG_TRIVIAL(debug) << "Testing FinalizeBlock to aggregate signatures from other nodes but itself"; - std::vector signers; - std::string pre_signatures = ""; - CBlock block = m_blockchains.at(0)->GenerateBlock(get_present_block_time()); - - // Concatenate PreSignatures as done in prolog - for (int i = 0; i < CLUSTER_SIZE; i++) - { - auto presignature = frost_wallets[i]->GetPreSignatureShare(); - if (i == 1) - { - pre_signatures.append("+"); - pre_signatures.append(presignature); - } - if (i == 2) - { - pre_signatures = presignature + pre_signatures; - } + // Concatenate PreSignatures as done in prolog + for (int i = 0; i < CLUSTER_SIZE; i++) { + auto presignature = frost_wallets[i]->GetPreSignatureShare(); + if (i == 1) { + pre_signatures.append("+"); + pre_signatures.append(presignature); } - // GetSignatureShare: only 1 node signs - std::vector signature_shares; - std::string nodeSignature1 = frost_wallets[1]->GetSignatureShare(signers, pre_signatures, block); - signature_shares.push_back(nodeSignature1); - std::string nodeSignature2 = frost_wallets[2]->GetSignatureShare(signers, pre_signatures, block); - signature_shares.push_back(nodeSignature2); + if (i == 2) { + pre_signatures = presignature + pre_signatures; + } + } + // GetSignatureShare: only 1 node signs + std::vector signature_shares; + std::string nodeSignature1 = frost_wallets[1]->GetSignatureShare(signers, pre_signatures, block); + signature_shares.push_back(nodeSignature1); + std::string nodeSignature2 = frost_wallets[2]->GetSignatureShare(signers, pre_signatures, block); + signature_shares.push_back(nodeSignature2); - CBlock final_block = frost_wallets[0]->FinalizeBlock(block, pre_signatures, signature_shares); + CBlock final_block = frost_wallets[0]->FinalizeBlock(block, pre_signatures, signature_shares); - auto info_0 = m_bitcoinds.at(0)->getblockchaininfo(); - auto height_0 = info_0["blocks"].asUInt(); + auto info_0 = m_bitcoinds.at(0)->getblockchaininfo(); + auto height_0 = info_0["blocks"].asUInt(); - m_blockchains.at(0)->SubmitBlock(0, final_block); + m_blockchains.at(0)->SubmitBlock(0, final_block); - auto info_1 = m_bitcoinds.at(0)->getblockchaininfo(); - auto height_1 = info_1["blocks"].asUInt(); + auto info_1 = m_bitcoinds.at(0)->getblockchaininfo(); + auto height_1 = info_1["blocks"].asUInt(); - BOOST_TEST(height_1 == height_0 + 1); - } + BOOST_TEST(height_1 == height_0 + 1); + } - // FinalizeBlock: primary aggregates signatures of other participants - { // Assumption: we generated keys to allow a 2-4 threshold signature. Two participants can generate a valid signature. - BOOST_LOG_TRIVIAL(debug) << "Testing FinalizeBlock to aggregate signatures from other nodes but itself"; - std::vector signers; - std::string pre_signatures = ""; - CBlock block = m_blockchains.at(0)->GenerateBlock(get_present_block_time()); - - // Concatenate PreSignatures as done in prolog - for (int i = 0; i < CLUSTER_SIZE; i++) - { - auto presignature = frost_wallets[i]->GetPreSignatureShare(); - if (i == 1) - pre_signatures.append(presignature); - } - // GetSignatureShare: only 1 node signs - std::vector signature_shares; - std::string nodeSignature1 = frost_wallets[1]->GetSignatureShare(signers, pre_signatures, block); - signature_shares.push_back(nodeSignature1); + // FinalizeBlock: primary aggregates signatures of other participants + { // Assumption: we generated keys to allow a 2-4 threshold signature. Two participants can generate a valid + // signature. + BOOST_LOG_TRIVIAL(debug) << "Testing FinalizeBlock to aggregate signatures from other nodes but itself"; + std::vector signers; + std::string pre_signatures = ""; + CBlock block = m_blockchains.at(0)->GenerateBlock(get_present_block_time()); - BOOST_CHECK_THROW(frost_wallets[0]->FinalizeBlock(block, pre_signatures, signature_shares), std::runtime_error); + // Concatenate PreSignatures as done in prolog + for (int i = 0; i < CLUSTER_SIZE; i++) { + auto presignature = frost_wallets[i]->GetPreSignatureShare(); + if (i == 1) + pre_signatures.append(presignature); } + // GetSignatureShare: only 1 node signs + std::vector signature_shares; + std::string nodeSignature1 = frost_wallets[1]->GetSignatureShare(signers, pre_signatures, block); + signature_shares.push_back(nodeSignature1); - // AppendSignature and VerifySignature - { - // Message signature - BOOST_LOG_TRIVIAL(debug) << "Testing AppendSignature to sign messages"; - uint32_t msg_sender_id = 0; - Prepare msg{msg_sender_id, 0, 0, "req_digest"}; - BOOST_CHECK_NO_THROW(frost_wallets[0]->AppendSignature(msg)); - - BOOST_LOG_TRIVIAL(debug) << "Testing VerifySignature to verify messages"; - bool is_sig_valid = frost_wallets[1]->VerifySignature(msg); - BOOST_TEST( is_sig_valid == true ); - } + BOOST_CHECK_THROW(frost_wallets[0]->FinalizeBlock(block, pre_signatures, signature_shares), + std::runtime_error); + } + + // AppendSignature and VerifySignature + { + // Message signature + BOOST_LOG_TRIVIAL(debug) << "Testing AppendSignature to sign messages"; + uint32_t msg_sender_id = 0; + Prepare msg{msg_sender_id, 0, 0, "req_digest"}; + BOOST_CHECK_NO_THROW(frost_wallets[0]->AppendSignature(msg)); + + BOOST_LOG_TRIVIAL(debug) << "Testing VerifySignature to verify messages"; + bool is_sig_valid = frost_wallets[1]->VerifySignature(msg); + BOOST_TEST(is_sig_valid == true); + } } // test_blockchain_frost_wallet_bitcoin_00 diff --git a/src/test/test_blockchain_generate.cpp b/src/test/test_blockchain_generate.cpp index 4769d43..84d2898 100644 --- a/src/test/test_blockchain_generate.cpp +++ b/src/test/test_blockchain_generate.cpp @@ -1,8 +1,8 @@ // Copyright (c) 2023 Bank of Italy // Distributed under the GNU AGPLv3 software license, see the accompanying COPYING file. -#include #include +#include #include #include @@ -13,13 +13,11 @@ namespace utf = boost::unit_test; - BOOST_AUTO_TEST_SUITE(test_blockchain_generate, *utf::enabled()) using namespace itcoin::blockchain; -bool isHashSmallerThanTarget(const CBlockHeader& header) -{ +bool isHashSmallerThanTarget(const CBlockHeader& header) { uint32_t defaultNBits = 0x207fffff; arith_uint256 target; bool neg, over; @@ -32,8 +30,7 @@ bool isHashSmallerThanTarget(const CBlockHeader& header) } // isHashSmallerThanTarget() // Integration test with Bitcoind for the block generation -BOOST_FIXTURE_TEST_CASE(test_block_generate_00, BitcoinInfraFixture) -{ +BOOST_FIXTURE_TEST_CASE(test_block_generate_00, BitcoinInfraFixture) { itcoin::transport::BtcClient& bitcoind0 = *m_bitcoinds.at(0); std::string address0 = address_at(0); @@ -43,7 +40,8 @@ BOOST_FIXTURE_TEST_CASE(test_block_generate_00, BitcoinInfraFixture) // test block { // check only coinbase tx (no tx in the pool) - BOOST_TEST(block.vtx.size() == 1, "only coinbase tx expected (empty pool), got nb of transactions " << block.vtx.size()); + BOOST_TEST(block.vtx.size() == 1, + "only coinbase tx expected (empty pool), got nb of transactions " << block.vtx.size()); // check grinding worked BOOST_TEST(isHashSmallerThanTarget(CBlockHeader(block)), "block nonce is not valid"); @@ -59,8 +57,7 @@ BOOST_FIXTURE_TEST_CASE(test_block_generate_00, BitcoinInfraFixture) // test first input scriptSig; see miner.cpp, CreateNewBlock function, around line 189 unsigned int height = m_bitcoinds.at(0)->getblockchaininfo()["blocks"].asUInt() + 1; auto expectedScript = (CScript() << height); - if(height<16) - { + if (height < 16) { expectedScript << OP_1; } auto& actualScript = coinbaseTx->vin[0].scriptSig; @@ -69,7 +66,8 @@ BOOST_FIXTURE_TEST_CASE(test_block_generate_00, BitcoinInfraFixture) // test first input nSequence auto expectedNSequence = CTxIn::SEQUENCE_FINAL; auto& actualNSequence = coinbaseTx->vin[0].nSequence; - BOOST_TEST(expectedNSequence == actualNSequence, "expected nSequence " << expectedNSequence << ", got " << actualNSequence); + BOOST_TEST(expectedNSequence == actualNSequence, + "expected nSequence " << expectedNSequence << ", got " << actualNSequence); // test first input scriptWitness const uint256 witNonce = uint256(0); @@ -83,22 +81,28 @@ BOOST_FIXTURE_TEST_CASE(test_block_generate_00, BitcoinInfraFixture) // test nb outputs of the coinbase tx auto actualNbOutputs = coinbaseTx->vout.size(); auto expectedNbOutputs = 2; - BOOST_TEST(expectedNbOutputs == actualNbOutputs, "expected number of outputs is " << expectedNbOutputs << ", got " << actualNbOutputs); + BOOST_TEST(expectedNbOutputs == actualNbOutputs, + "expected number of outputs is " << expectedNbOutputs << ", got " << actualNbOutputs); // test scriptPubKey in first output is set correctly const CScript expectedScriptPubKey = getScriptPubKey(bitcoind0, address0); - BOOST_TEST(coinbaseTx->vout[0].scriptPubKey == expectedScriptPubKey, "actual scriptPubKey of first output does not match with expected one"); + BOOST_TEST(coinbaseTx->vout[0].scriptPubKey == expectedScriptPubKey, + "actual scriptPubKey of first output does not match with expected one"); // test coinbase value in first output is set correctly auto defaultCoinbaseValue = 10000000000; - BOOST_TEST(coinbaseTx->vout[0].nValue == defaultCoinbaseValue, "expected value of first output is " << defaultCoinbaseValue << ", got " << coinbaseTx->vout[0].nValue); + BOOST_TEST(coinbaseTx->vout[0].nValue == defaultCoinbaseValue, "expected value of first output is " + << defaultCoinbaseValue << ", got " + << coinbaseTx->vout[0].nValue); // test out script in second output is set correctly CScript newOutScriptWithSignetHeader = newOutScript << SIGNET_HEADER_VEC; - BOOST_TEST((coinbaseTx->vout[1].scriptPubKey == newOutScriptWithSignetHeader), "actual scriptPubKey of second output does not match with expected one"); + BOOST_TEST((coinbaseTx->vout[1].scriptPubKey == newOutScriptWithSignetHeader), + "actual scriptPubKey of second output does not match with expected one"); // test value in second output is set correctly - BOOST_TEST(coinbaseTx->vout[1].nValue == 0, "expected value of second output is 0, got " << coinbaseTx->vout[1].nValue); + BOOST_TEST(coinbaseTx->vout[1].nValue == 0, + "expected value of second output is 0, got " << coinbaseTx->vout[1].nValue); } } // test_generate_block diff --git a/src/test/test_blockchain_wallet_bitcoin.cpp b/src/test/test_blockchain_wallet_bitcoin.cpp index 7cb03a3..740af7f 100644 --- a/src/test/test_blockchain_wallet_bitcoin.cpp +++ b/src/test/test_blockchain_wallet_bitcoin.cpp @@ -3,14 +3,14 @@ #include +#include +#include #include #include #include -#include -#include -#include "fixtures/fixtures.h" #include "../blockchain/blockchain.h" +#include "fixtures/fixtures.h" namespace utf = boost::unit_test; @@ -19,26 +19,23 @@ BOOST_AUTO_TEST_SUITE(test_blockchain_wallet_bitcoin, *utf::enabled()) using namespace itcoin::blockchain; using namespace itcoin::fbft::messages; -BOOST_FIXTURE_TEST_CASE(test_blockchain_wallet_bitcoin_00, BitcoinInfraFixture) -{ - boost::log::core::get()->set_filter ( - boost::log::trivial::severity >= boost::log::trivial::trace - ); +BOOST_FIXTURE_TEST_CASE(test_blockchain_wallet_bitcoin_00, BitcoinInfraFixture) { + boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::trace); { // Blockchain block creation and validity testing - BOOST_LOG_TRIVIAL(debug) << "Testing blockchain bitcoin with replica = 0"; - CBlock new_block = m_blockchains.at(0)->GenerateBlock(get_present_block_time()); - // check_signet_solution=false because at this point we do not have the final signature - bool is_new_block_valid = m_blockchains.at(1)->TestBlockValidity(0, new_block, false); - BOOST_TEST( is_new_block_valid == true ); + BOOST_LOG_TRIVIAL(debug) << "Testing blockchain bitcoin with replica = 0"; + CBlock new_block = m_blockchains.at(0)->GenerateBlock(get_present_block_time()); + // check_signet_solution=false because at this point we do not have the final signature + bool is_new_block_valid = m_blockchains.at(1)->TestBlockValidity(0, new_block, false); + BOOST_TEST(is_new_block_valid == true); } { // Message signature - uint32_t msg_sender_id = 0; - Prepare msg{msg_sender_id, 0, 0, "req_digest"}; - msg.Sign(*m_wallets[0]); - bool is_sig_valid = m_wallets[1]->VerifySignature(msg); - BOOST_TEST( is_sig_valid == true ); + uint32_t msg_sender_id = 0; + Prepare msg{msg_sender_id, 0, 0, "req_digest"}; + msg.Sign(*m_wallets[0]); + bool is_sig_valid = m_wallets[1]->VerifySignature(msg); + BOOST_TEST(is_sig_valid == true); } } // test_blockchain_wallet_bitcoin_00 diff --git a/src/test/test_fbft_normal_operation.cpp b/src/test/test_fbft_normal_operation.cpp index 7d25795..3264df3 100644 --- a/src/test/test_fbft_normal_operation.cpp +++ b/src/test/test_fbft_normal_operation.cpp @@ -9,17 +9,20 @@ using namespace itcoin::fbft::messages; namespace state = itcoin::fbft::state; -struct NormalOperationFixture: ReplicaStateFixture { NormalOperationFixture(): ReplicaStateFixture(4,0,60) {} }; +struct NormalOperationFixture : ReplicaStateFixture { + NormalOperationFixture() : ReplicaStateFixture(4, 0, 60) {} +}; BOOST_AUTO_TEST_SUITE(test_fbft_normal_operation, *utf::enabled()) -BOOST_FIXTURE_TEST_CASE(test_fbft_normal_operation_00, NormalOperationFixture) -{ +BOOST_FIXTURE_TEST_CASE(test_fbft_normal_operation_00, NormalOperationFixture) { // Step 1. Simulate Receipt of a REQUEST message by replica 0 uint32_t req_timestamp = 60; - Request request = Request(m_configs[0]->genesis_block_timestamp(), m_configs[0]->target_block_time(), req_timestamp); + Request request = + Request(m_configs[0]->genesis_block_timestamp(), m_configs[0]->target_block_time(), req_timestamp); - BOOST_LOG_TRIVIAL(debug) << "Simulating the creation of request with digest at all replicas = " << request.digest(); + BOOST_LOG_TRIVIAL(debug) << "Simulating the creation of request with digest at all replicas = " + << request.digest(); m_states[0]->set_synthetic_time(req_timestamp); m_states[1]->set_synthetic_time(req_timestamp); m_states[2]->set_synthetic_time(req_timestamp); @@ -155,8 +158,10 @@ BOOST_FIXTURE_TEST_CASE(test_fbft_normal_operation_00, NormalOperationFixture) BOOST_CHECK(m_states[0]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_PREPARE); BOOST_CHECK(m_states[0]->active_actions().at(1)->type() == ACTION_TYPE::RECEIVE_PREPARE); - ReceivePrepare receive_prepare_0 = ReceivePrepare(dynamic_cast(*m_states[0]->active_actions().at(0))); - ReceivePrepare receive_prepare_1 = ReceivePrepare(dynamic_cast(*m_states[0]->active_actions().at(1))); + ReceivePrepare receive_prepare_0 = + ReceivePrepare(dynamic_cast(*m_states[0]->active_actions().at(0))); + ReceivePrepare receive_prepare_1 = + ReceivePrepare(dynamic_cast(*m_states[0]->active_actions().at(1))); m_states[0]->Apply(receive_prepare_0); m_states[0]->Apply(receive_prepare_1); @@ -224,8 +229,10 @@ BOOST_FIXTURE_TEST_CASE(test_fbft_normal_operation_00, NormalOperationFixture) BOOST_CHECK(m_states[0]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_COMMIT); BOOST_CHECK(m_states[0]->active_actions().at(1)->type() == ACTION_TYPE::RECEIVE_COMMIT); - ReceiveCommit receive_commit_0 = ReceiveCommit(dynamic_cast(*m_states[0]->active_actions().at(0))); - ReceiveCommit receive_commit_1 = ReceiveCommit(dynamic_cast(*m_states[0]->active_actions().at(1))); + ReceiveCommit receive_commit_0 = + ReceiveCommit(dynamic_cast(*m_states[0]->active_actions().at(0))); + ReceiveCommit receive_commit_1 = + ReceiveCommit(dynamic_cast(*m_states[0]->active_actions().at(1))); m_states[0]->Apply(receive_commit_0); m_states[0]->Apply(receive_commit_1); diff --git a/src/test/test_fbft_replica2.cpp b/src/test/test_fbft_replica2.cpp index c81edb9..2600f08 100644 --- a/src/test/test_fbft_replica2.cpp +++ b/src/test/test_fbft_replica2.cpp @@ -14,174 +14,147 @@ using namespace std; -struct Replica2Fixture: ReplicaSetFixture { Replica2Fixture(): ReplicaSetFixture(4,0,60) {} }; +struct Replica2Fixture : ReplicaSetFixture { + Replica2Fixture() : ReplicaSetFixture(4, 0, 60) {} +}; BOOST_AUTO_TEST_SUITE(test_fbft_replica2, *utf::enabled()) -BOOST_FIXTURE_TEST_CASE(test_fbft_replica2_00, Replica2Fixture) -{ -try -{ - boost::log::core::get()->set_filter ( - boost::log::trivial::severity >= boost::log::trivial::debug - ); - - // ... At the beginning of the test, we kill a single, random replica each KILL_PERIOD_DELTA. - // Say KILL_PERIOD_DELTA=3*TBT, and we want to kill 5 replica, i.e. MAX_KILLS=5. - // We need 5 kill periods to kill 5 replica. - // Then, we need 15*TBT time to kill a replica at most 5 times, i.e. KILL_WINDOW = 15*TBT. - // ... Then we wait until the whole network recoveries. - // We killed the primary at most MAX_KILLS times. - // This means that the max view change timeout is 2^MAX_KILLS*(TBT/2) = 16*TBT - // In order for the algorithm to converge, three replica should work without interruption for at least 16*TBT - // The residual time should be bigger than the max timeout, we set RECOVERY_WINDOW = 16*TBT +1*TBT = 17*TBT - // In total, we have (15 + 17)*TBT = total test time. - int KILL_PERIOD_DELTA = 3*TARGET_BLOCK_TIME; - int MAX_KILLS = 5; - - // - int KILL_WINDOW = MAX_KILLS*KILL_PERIOD_DELTA; - int RECOVERY_WINDOW = pow(2, MAX_KILLS)*TARGET_BLOCK_TIME/2 + 1*TARGET_BLOCK_TIME; - int MAX_SYNTHETIC_TIME = KILL_WINDOW+RECOVERY_WINDOW; - int TARGET_HEIGHT = MAX_SYNTHETIC_TIME/TARGET_BLOCK_TIME -1; - - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("KILL_WINDOW = %1%, RECOVERY_WINDOW = %2%, MAX_SYNTHETIC_TIME = %3%, TARGET_HEIGHT = %4%.") - % KILL_WINDOW - % RECOVERY_WINDOW - % MAX_SYNTHETIC_TIME - % TARGET_HEIGHT - ); - - // Dead replica - int dead_replica = -1; - int dead_replica_time = 0; - - // Move time at the beginning of the block round - int test_time = 0; - set_synthetic_time(test_time); - while(test_timeset_filter(boost::log::trivial::severity >= boost::log::trivial::debug); + + // ... At the beginning of the test, we kill a single, random replica each KILL_PERIOD_DELTA. + // Say KILL_PERIOD_DELTA=3*TBT, and we want to kill 5 replica, i.e. MAX_KILLS=5. + // We need 5 kill periods to kill 5 replica. + // Then, we need 15*TBT time to kill a replica at most 5 times, i.e. KILL_WINDOW = 15*TBT. + // ... Then we wait until the whole network recoveries. + // We killed the primary at most MAX_KILLS times. + // This means that the max view change timeout is 2^MAX_KILLS*(TBT/2) = 16*TBT + // In order for the algorithm to converge, three replica should work without interruption for at least + // 16*TBT The residual time should be bigger than the max timeout, we set RECOVERY_WINDOW = 16*TBT +1*TBT + // = 17*TBT In total, we have (15 + 17)*TBT = total test time. + int KILL_PERIOD_DELTA = 3 * TARGET_BLOCK_TIME; + int MAX_KILLS = 5; + + // + int KILL_WINDOW = MAX_KILLS * KILL_PERIOD_DELTA; + int RECOVERY_WINDOW = pow(2, MAX_KILLS) * TARGET_BLOCK_TIME / 2 + 1 * TARGET_BLOCK_TIME; + int MAX_SYNTHETIC_TIME = KILL_WINDOW + RECOVERY_WINDOW; + int TARGET_HEIGHT = MAX_SYNTHETIC_TIME / TARGET_BLOCK_TIME - 1; + + BOOST_LOG_TRIVIAL(debug) << str( + boost::format( + "KILL_WINDOW = %1%, RECOVERY_WINDOW = %2%, MAX_SYNTHETIC_TIME = %3%, TARGET_HEIGHT = %4%.") % + KILL_WINDOW % RECOVERY_WINDOW % MAX_SYNTHETIC_TIME % TARGET_HEIGHT); + + // Dead replica + int dead_replica = -1; + int dead_replica_time = 0; + + // Move time at the beginning of the block round + int test_time = 0; + set_synthetic_time(test_time); + while (test_time < MAX_SYNTHETIC_TIME) { + if (test_time < KILL_WINDOW) { + if (test_time - dead_replica_time < KILL_PERIOD_DELTA) { + // Do nothing + } else { + int new_dead_replica = (std::rand() % CLUSTER_SIZE); + if (new_dead_replica != dead_replica) { + if (dead_replica != -1) + wake(dead_replica); + kill(new_dead_replica); + dead_replica = new_dead_replica; + dead_replica_time = test_time; + } } + } else { + // Eventually + wake(dead_replica); } - } - else - { - // Eventually - wake(dead_replica); + + move_forward(10); + test_time = m_replica[0]->current_time(); } - move_forward(10); - test_time = m_replica[0]->current_time(); + BOOST_TEST(m_blockchain->height() == TARGET_HEIGHT); + // BOOST_FAIL("Test DID NOT FAIL. This is a failure placeholder used just to print all dynamic + // predicates"); + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << e.what(); + BOOST_CHECK_NO_THROW(throw e); } - - BOOST_TEST(m_blockchain->height() == TARGET_HEIGHT); - // BOOST_FAIL("Test DID NOT FAIL. This is a failure placeholder used just to print all dynamic predicates"); } -catch(const std::exception& e) -{ - BOOST_LOG_TRIVIAL(error) << e.what(); - BOOST_CHECK_NO_THROW( throw e ); -} -} - -BOOST_FIXTURE_TEST_CASE(test_fbft_replica2_01, Replica2Fixture) -{ -try -{ - boost::log::core::get()->set_filter ( - boost::log::trivial::severity >= boost::log::trivial::debug - ); - - m_replica[0]->CheckTimedActions(); - BOOST_TEST( m_replica[0]->active_actions().size() == 0u); - BOOST_TEST( m_replica[0]->out_msg_buffer().size() == 0u); - BOOST_TEST( m_replica[0]->latest_request_time() == 5*TARGET_BLOCK_TIME); - - set_synthetic_time(1); - m_replica[0]->CheckTimedActions(); - BOOST_TEST( m_replica[0]->active_actions().size() == 0u); - BOOST_TEST( m_replica[0]->out_msg_buffer().size() == 0u); - BOOST_TEST( m_replica[0]->latest_request_time() == 5*TARGET_BLOCK_TIME); - - // Test that even if multiple requests are generated, pre_prepare are sent one by one; - set_synthetic_time(TARGET_BLOCK_TIME+1); - m_replica[0]->CheckTimedActions(); - m_replica[1]->CheckTimedActions(); - m_replica[2]->CheckTimedActions(); - m_replica[3]->CheckTimedActions(); - BOOST_TEST( m_replica[0]->latest_request_time() == 5*TARGET_BLOCK_TIME); - - for (int i=0; i<10; i++) - { - m_transports[0]->SimulateReceiveMessages(); - m_transports[1]->SimulateReceiveMessages(); - m_transports[2]->SimulateReceiveMessages(); - m_transports[3]->SimulateReceiveMessages(); - } - BOOST_TEST(m_blockchain->height() == 1); - - // Mine other blocks - int TARGET_HEIGHT = 9; - int MAX_SYNTHETIC_TIME = (TARGET_HEIGHT+1)*TARGET_BLOCK_TIME; - - // Move time at the beginning of the block round - int test_time = 2*TARGET_BLOCK_TIME+1; - set_synthetic_time(test_time); - while(test_time=121 && test_time<181) - { - // Killing R1, a non primary - kill(1); +BOOST_FIXTURE_TEST_CASE(test_fbft_replica2_01, Replica2Fixture) { + try { + boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::debug); + + m_replica[0]->CheckTimedActions(); + BOOST_TEST(m_replica[0]->active_actions().size() == 0u); + BOOST_TEST(m_replica[0]->out_msg_buffer().size() == 0u); + BOOST_TEST(m_replica[0]->latest_request_time() == 5 * TARGET_BLOCK_TIME); + + set_synthetic_time(1); + m_replica[0]->CheckTimedActions(); + BOOST_TEST(m_replica[0]->active_actions().size() == 0u); + BOOST_TEST(m_replica[0]->out_msg_buffer().size() == 0u); + BOOST_TEST(m_replica[0]->latest_request_time() == 5 * TARGET_BLOCK_TIME); + + // Test that even if multiple requests are generated, pre_prepare are sent one by one; + set_synthetic_time(TARGET_BLOCK_TIME + 1); + m_replica[0]->CheckTimedActions(); + m_replica[1]->CheckTimedActions(); + m_replica[2]->CheckTimedActions(); + m_replica[3]->CheckTimedActions(); + BOOST_TEST(m_replica[0]->latest_request_time() == 5 * TARGET_BLOCK_TIME); + + for (int i = 0; i < 10; i++) { + m_transports[0]->SimulateReceiveMessages(); + m_transports[1]->SimulateReceiveMessages(); + m_transports[2]->SimulateReceiveMessages(); + m_transports[3]->SimulateReceiveMessages(); } - else if (test_time>=181 && test_time<241) - { - // Killing the primary R0, triggers VC, new primary will be R1 - wake(1); - kill(0); - } - else if (test_time>=241 && test_time<301) - { - // Killing the new primary R1, triggers VC, new primary will be R2 - wake(0); - kill(1); - } - else if (test_time>=301) - { - // Killing R3 a non primary - wake(1); - kill(3); + + BOOST_TEST(m_blockchain->height() == 1); + + // Mine other blocks + int TARGET_HEIGHT = 9; + int MAX_SYNTHETIC_TIME = (TARGET_HEIGHT + 1) * TARGET_BLOCK_TIME; + + // Move time at the beginning of the block round + int test_time = 2 * TARGET_BLOCK_TIME + 1; + set_synthetic_time(test_time); + while (test_time < MAX_SYNTHETIC_TIME) { + if (test_time >= 121 && test_time < 181) { + // Killing R1, a non primary + kill(1); + } else if (test_time >= 181 && test_time < 241) { + // Killing the primary R0, triggers VC, new primary will be R1 + wake(1); + kill(0); + } else if (test_time >= 241 && test_time < 301) { + // Killing the new primary R1, triggers VC, new primary will be R2 + wake(0); + kill(1); + } else if (test_time >= 301) { + // Killing R3 a non primary + wake(1); + kill(3); + } + + move_forward(10); + test_time = m_replica[0]->current_time(); } - move_forward(10); - test_time = m_replica[0]->current_time(); + BOOST_TEST(m_blockchain->height() == TARGET_HEIGHT); + // BOOST_FAIL("Test DID NOT FAIL. This is a failure placeholder used just to print all dynamic + // predicates"); + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << e.what(); + BOOST_CHECK_NO_THROW(throw e); } - - BOOST_TEST(m_blockchain->height() == TARGET_HEIGHT); - // BOOST_FAIL("Test DID NOT FAIL. This is a failure placeholder used just to print all dynamic predicates"); -} -catch(const std::exception& e) -{ - BOOST_LOG_TRIVIAL(error) << e.what(); - BOOST_CHECK_NO_THROW( throw e ); -} } BOOST_AUTO_TEST_SUITE_END() // test_fbft_replica2 diff --git a/src/test/test_fbft_signing_with_roast.cpp b/src/test/test_fbft_signing_with_roast.cpp index 896d936..85349cd 100644 --- a/src/test/test_fbft_signing_with_roast.cpp +++ b/src/test/test_fbft_signing_with_roast.cpp @@ -11,21 +11,20 @@ namespace utf = boost::unit_test; namespace state = itcoin::fbft::state; -struct V5FrostedBftFixture: ReplicaStateFixture { V5FrostedBftFixture(): ReplicaStateFixture(4,0,60) {} }; +struct V5FrostedBftFixture : ReplicaStateFixture { + V5FrostedBftFixture() : ReplicaStateFixture(4, 0, 60) {} +}; BOOST_AUTO_TEST_SUITE(test_fbft_signing_with_roast, *utf::enabled()) -BOOST_FIXTURE_TEST_CASE(test_fbft_signing_with_roast_00, V5FrostedBftFixture) -{ - boost::log::core::get()->set_filter ( - boost::log::trivial::severity >= boost::log::trivial::trace - ); +BOOST_FIXTURE_TEST_CASE(test_fbft_signing_with_roast_00, V5FrostedBftFixture) { + boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::trace); // Receive REQUEST at all replicas uint32_t REQ_TS = 60; - Request request = Request(m_configs[0]->genesis_block_timestamp(), m_configs[0]->target_block_time(), REQ_TS); - for (int i=0; i<4; i++) - { + Request request = + Request(m_configs[0]->genesis_block_timestamp(), m_configs[0]->target_block_time(), REQ_TS); + for (int i = 0; i < 4; i++) { m_states[i]->Apply(ReceiveRequest(i, request)); } @@ -42,28 +41,23 @@ BOOST_FIXTURE_TEST_CASE(test_fbft_signing_with_roast_00, V5FrostedBftFixture) PrePrepare pre_prepare_0{dynamic_cast(*m_states[0]->out_msg_buffer().at(0))}; m_states[0]->ClearOutMessageBuffer(); - for (int rid=1; rid<4; rid++) - { + for (int rid = 1; rid < 4; rid++) { m_states[rid]->ReceiveIncomingMessage(std::make_unique(pre_prepare_0)); m_states[rid]->Apply(*m_states[rid]->active_actions().at(0)); } // Step 7. We apply the SEND_PREPARE to all replicas - for (int rid=1; rid<4; rid++) - { + for (int rid = 1; rid < 4; rid++) { m_states[rid]->Apply(*m_states[rid]->active_actions().at(0)); } // Receive PREPARE at all replica - for (int sid=1; sid<4; sid++) - { + for (int sid = 1; sid < 4; sid++) { Prepare prepare{dynamic_cast(*m_states[sid]->out_msg_buffer().at(0))}; - for (int rid=0; rid<4; rid++) - { - if (rid != sid) - { + for (int rid = 0; rid < 4; rid++) { + if (rid != sid) { m_states[rid]->ReceiveIncomingMessage(std::make_unique(prepare)); m_states[rid]->Apply(*m_states[rid]->active_actions().at(0)); } @@ -73,20 +67,16 @@ BOOST_FIXTURE_TEST_CASE(test_fbft_signing_with_roast_00, V5FrostedBftFixture) // Step 7. We apply the SEND_PREPARE to all replicas - for (int rid=0; rid<4; rid++) - { + for (int rid = 0; rid < 4; rid++) { m_states[rid]->Apply(*m_states[rid]->active_actions().at(0)); } // Receive COMMIT at all replica - for (int sid=0; sid<4; sid++) - { + for (int sid = 0; sid < 4; sid++) { Commit commit{dynamic_cast(*m_states[sid]->out_msg_buffer().at(0))}; - for (int rid=0; rid<4; rid++) - { - if (rid != sid) - { + for (int rid = 0; rid < 4; rid++) { + if (rid != sid) { m_states[rid]->ReceiveIncomingMessage(std::make_unique(commit)); m_states[rid]->Apply(*m_states[rid]->active_actions().at(0)); } @@ -96,8 +86,7 @@ BOOST_FIXTURE_TEST_CASE(test_fbft_signing_with_roast_00, V5FrostedBftFixture) // At this stage PRE_ROAST_INIT should be active for all replica - for (int rid=0; rid<4; rid++) - { + for (int rid = 0; rid < 4; rid++) { BOOST_TEST(m_states[rid]->out_msg_buffer().size() == 0u); BOOST_TEST(m_states[rid]->active_actions().size() == 1u); BOOST_CHECK(m_states[rid]->active_actions().at(0)->type() == ACTION_TYPE::ROAST_INIT); @@ -134,13 +123,15 @@ BOOST_FIXTURE_TEST_CASE(test_fbft_signing_with_roast_00, V5FrostedBftFixture) m_states[0]->Apply(*m_states[0]->active_actions().at(0)); BOOST_TEST(m_states[0]->out_msg_buffer().size() == 1u); BOOST_CHECK(m_states[0]->out_msg_buffer().at(0)->type() == MSG_TYPE::ROAST_SIGNATURE_SHARE); - RoastSignatureShare roast_sig_share_0{dynamic_cast(*m_states[0]->out_msg_buffer().at(0))}; + RoastSignatureShare roast_sig_share_0{ + dynamic_cast(*m_states[0]->out_msg_buffer().at(0))}; m_states[0]->ClearOutMessageBuffer(); m_states[2]->Apply(*m_states[2]->active_actions().at(0)); BOOST_TEST(m_states[2]->out_msg_buffer().size() == 1u); BOOST_CHECK(m_states[2]->out_msg_buffer().at(0)->type() == MSG_TYPE::ROAST_SIGNATURE_SHARE); - RoastSignatureShare roast_sig_share_2{dynamic_cast(*m_states[2]->out_msg_buffer().at(0))}; + RoastSignatureShare roast_sig_share_2{ + dynamic_cast(*m_states[2]->out_msg_buffer().at(0))}; m_states[2]->ClearOutMessageBuffer(); // Coordinator R0 receives signature share from R0 @@ -175,13 +166,15 @@ BOOST_FIXTURE_TEST_CASE(test_fbft_signing_with_roast_00, V5FrostedBftFixture) m_states[0]->Apply(*m_states[0]->active_actions().at(0)); BOOST_TEST(m_states[0]->out_msg_buffer().size() == 1u); BOOST_CHECK(m_states[0]->out_msg_buffer().at(0)->type() == MSG_TYPE::ROAST_SIGNATURE_SHARE); - RoastSignatureShare roast_sig_share_0_bis{dynamic_cast(*m_states[0]->out_msg_buffer().at(0))}; + RoastSignatureShare roast_sig_share_0_bis{ + dynamic_cast(*m_states[0]->out_msg_buffer().at(0))}; m_states[0]->ClearOutMessageBuffer(); m_states[2]->Apply(*m_states[2]->active_actions().at(0)); BOOST_TEST(m_states[2]->out_msg_buffer().size() == 1u); BOOST_CHECK(m_states[2]->out_msg_buffer().at(0)->type() == MSG_TYPE::ROAST_SIGNATURE_SHARE); - RoastSignatureShare roast_sig_share_2_bis{dynamic_cast(*m_states[2]->out_msg_buffer().at(0))}; + RoastSignatureShare roast_sig_share_2_bis{ + dynamic_cast(*m_states[2]->out_msg_buffer().at(0))}; m_states[2]->ClearOutMessageBuffer(); m_states[0]->ReceiveIncomingMessage(std::make_unique(roast_sig_share_0_bis)); @@ -201,18 +194,17 @@ BOOST_FIXTURE_TEST_CASE(test_fbft_signing_with_roast_00, V5FrostedBftFixture) m_states[0]->Apply(*m_states[0]->active_actions().at(0)); // Other replica should not have active actions - for (int rid=0; rid<4; rid++) - { + for (int rid = 0; rid < 4; rid++) { BOOST_TEST(m_states[rid]->active_actions().size() == 0u); BOOST_TEST(m_states[rid]->out_msg_buffer().size() == 0u); } // Finally propagate the block - Block propagated_block{pre_prepare_0.seq_number(), pre_prepare_0.proposed_block().nTime, pre_prepare_0.proposed_block().GetHash().GetHex()}; + Block propagated_block{pre_prepare_0.seq_number(), pre_prepare_0.proposed_block().nTime, + pre_prepare_0.proposed_block().GetHash().GetHex()}; - for (int rid=0; rid<4; rid++) - { + for (int rid = 0; rid < 4; rid++) { m_states[rid]->ReceiveIncomingMessage(std::make_unique(propagated_block)); BOOST_TEST(m_states[rid]->active_actions().size() == 1u); BOOST_TEST(m_states[rid]->out_msg_buffer().size() == 0u); diff --git a/src/test/test_fbft_view_change_empty.cpp b/src/test/test_fbft_view_change_empty.cpp index 60cf1e7..e7c881e 100644 --- a/src/test/test_fbft_view_change_empty.cpp +++ b/src/test/test_fbft_view_change_empty.cpp @@ -7,187 +7,187 @@ using namespace std; using namespace itcoin::fbft::actions; using namespace itcoin::fbft::messages; -struct ViewChangeEmptyFixture: ReplicaStateFixture { ViewChangeEmptyFixture(): ReplicaStateFixture(4,0,60) {} }; +struct ViewChangeEmptyFixture : ReplicaStateFixture { + ViewChangeEmptyFixture() : ReplicaStateFixture(4, 0, 60) {} +}; BOOST_AUTO_TEST_SUITE(test_fbft_view_change_empty, *utf::enabled()) -BOOST_FIXTURE_TEST_CASE(test_fbft_view_change_empty_00, ViewChangeEmptyFixture) -{ -try -{ - // Simulate receipt of a REQUEST message - uint32_t req_timestamp = 60; - Request request = Request(m_configs[0]->genesis_block_timestamp(), m_configs[0]->target_block_time(), req_timestamp); - - BOOST_LOG_TRIVIAL(debug) << "Create Request with digest " << request.digest() << "at R0, R1, R2, R3"; - m_states[0]->ReceiveIncomingMessage(std::make_unique(request)); - m_states[1]->ReceiveIncomingMessage(std::make_unique(request)); - m_states[2]->ReceiveIncomingMessage(std::make_unique(request)); - m_states[3]->ReceiveIncomingMessage(std::make_unique(request)); - - BOOST_TEST(m_states[0]->active_actions().size() == 1u); - BOOST_CHECK(m_states[0]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_REQUEST); - BOOST_TEST(m_states[1]->active_actions().size() == 1u); - BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_REQUEST); - BOOST_TEST(m_states[2]->active_actions().size() == 1u); - BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_REQUEST); - BOOST_TEST(m_states[3]->active_actions().size() == 1u); - BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_REQUEST); - - BOOST_LOG_TRIVIAL(debug) << "Apply the receive request at R0, R1, R2, R3"; - m_states[0]->set_synthetic_time(req_timestamp); - m_states[1]->set_synthetic_time(req_timestamp); - m_states[2]->set_synthetic_time(req_timestamp); - m_states[3]->set_synthetic_time(req_timestamp); - - m_states[0]->Apply(*m_states[0]->active_actions().at(0)); - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - - BOOST_TEST(m_states[0]->active_actions().size() == 1u); - BOOST_CHECK(m_states[0]->active_actions().at(0)->type() == ACTION_TYPE::SEND_PRE_PREPARE); - BOOST_TEST(m_states[1]->active_actions().size() == 0u); - BOOST_TEST(m_states[2]->active_actions().size() == 0u); - - BOOST_LOG_TRIVIAL(debug) << "After 10+30 seconds, all backups should activate the view change"; - m_states[1]->set_synthetic_time(req_timestamp+m_configs[1]->target_block_time()/2+1); - m_states[2]->set_synthetic_time(req_timestamp+m_configs[2]->target_block_time()/2+1); - m_states[3]->set_synthetic_time(req_timestamp+m_configs[3]->target_block_time()/2+1); - - BOOST_TEST(m_states[0]->active_actions().size() == 1u); - BOOST_CHECK(m_states[0]->active_actions().at(0)->type() == ACTION_TYPE::SEND_PRE_PREPARE); - BOOST_TEST(m_states[1]->active_actions().size() == 1u); - BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); - BOOST_TEST(m_states[2]->active_actions().size() == 1u); - BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); - BOOST_TEST(m_states[3]->active_actions().size() == 1u); - BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); - - BOOST_LOG_TRIVIAL(debug) << "Apply SEND_VIEW_CHANGE at R1 and R2"; - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - - BOOST_TEST(m_states[1]->active_actions().size() == 0u); - BOOST_TEST(m_states[2]->active_actions().size() == 0u); - BOOST_TEST(m_states[1]->out_msg_buffer().size() == 1u); - BOOST_CHECK(m_states[1]->out_msg_buffer().at(0)->type() == MSG_TYPE::VIEW_CHANGE); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 1u); - BOOST_CHECK(m_states[2]->out_msg_buffer().at(0)->type() == MSG_TYPE::VIEW_CHANGE); - BOOST_TEST(m_states[3]->out_msg_buffer().size() == 1u); - BOOST_CHECK(m_states[3]->out_msg_buffer().at(0)->type() == MSG_TYPE::VIEW_CHANGE); - - BOOST_LOG_TRIVIAL(debug) << "R1 and R2 receive each other VIEW_CHANGE"; - ViewChange view_change_1{dynamic_cast(*m_states[1]->out_msg_buffer().at(0))}; - m_wallets[1]->AppendSignature(view_change_1); - ViewChange view_change_2{dynamic_cast(*m_states[2]->out_msg_buffer().at(0))}; - m_wallets[2]->AppendSignature(view_change_2); - ViewChange view_change_3{dynamic_cast(*m_states[3]->out_msg_buffer().at(0))}; - m_wallets[3]->AppendSignature(view_change_3); - m_states[1]->ClearOutMessageBuffer(); - m_states[2]->ClearOutMessageBuffer(); - m_states[3]->ClearOutMessageBuffer(); - - m_states[1]->ReceiveIncomingMessage(std::make_unique(view_change_2)); - BOOST_TEST(m_states[1]->active_actions().size() == 1u); - BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_VIEW_CHANGE); - BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); - - m_states[2]->ReceiveIncomingMessage(std::make_unique(view_change_1)); - BOOST_TEST(m_states[2]->active_actions().size() == 1u); - BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_VIEW_CHANGE); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - BOOST_LOG_TRIVIAL(debug) << "Apply the receive view change at R1, R2"; - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - - BOOST_LOG_TRIVIAL(debug) << "R1 and R2 and R3 receive VIEW_CHANGEs from each other"; - m_states[1]->ReceiveIncomingMessage(std::make_unique(view_change_3)); - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - - m_states[2]->ReceiveIncomingMessage(std::make_unique(view_change_3)); - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - - m_states[3]->ReceiveIncomingMessage(std::make_unique(view_change_1)); - m_states[3]->ReceiveIncomingMessage(std::make_unique(view_change_2)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - - // R1, being the primary of the new view, should send the new view - BOOST_TEST(m_states[1]->active_actions().size() == 1u); - BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::SEND_NEW_VIEW); - BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); - - // R2 and R3, being backups of the new view, shoud do nothing - BOOST_TEST(m_states[2]->active_actions().size() == 0u); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - BOOST_TEST(m_states[3]->active_actions().size() == 0u); - BOOST_TEST(m_states[3]->out_msg_buffer().size() == 0u); - - BOOST_LOG_TRIVIAL(debug) << "Apply SEND_NEW_VIEW at R1"; - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - - BOOST_TEST(m_states[1]->active_actions().size() == 1u); - BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); - BOOST_TEST(m_states[1]->out_msg_buffer().size() == 1u); - BOOST_CHECK(m_states[1]->out_msg_buffer().at(0)->type() == MSG_TYPE::NEW_VIEW); - - BOOST_LOG_TRIVIAL(debug) << "R2 and R3 receive the NEW_VIEW message"; - NewView new_view_1{dynamic_cast(*m_states[1]->out_msg_buffer().at(0))}; - new_view_1.Sign(*m_wallets[1]); - m_states[1]->ClearOutMessageBuffer(); - - m_states[2]->ReceiveIncomingMessage(std::make_unique(new_view_1)); - BOOST_TEST(m_states[2]->active_actions().size() == 1u); - BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_NEW_VIEW); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - m_states[3]->ReceiveIncomingMessage(std::make_unique(new_view_1)); - BOOST_TEST(m_states[3]->active_actions().size() == 1u); - BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_NEW_VIEW); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - BOOST_LOG_TRIVIAL(debug) << "Apply RECEIVE_NEW_VIEW at R2 and R3"; - - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - BOOST_TEST(m_states[2]->active_actions().size() == 1u); - BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - BOOST_TEST(m_states[3]->active_actions().size() == 1u); - BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); - BOOST_TEST(m_states[3]->out_msg_buffer().size() == 0u); - - m_states[3]->Apply(*m_states[1]->active_actions().at(0)); - - BOOST_LOG_TRIVIAL(debug) << "Apply PROCESS_NEW_VIEW at R1"; - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - - BOOST_TEST(m_states[1]->active_actions().size() == 1u); - BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::SEND_PRE_PREPARE); - BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); - - BOOST_LOG_TRIVIAL(debug) << "Apply PROCESS_NEW_VIEW at R2 and R3"; - - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - BOOST_TEST(m_states[2]->active_actions().size() == 0u); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - BOOST_TEST(m_states[3]->active_actions().size() == 0u); - BOOST_TEST(m_states[3]->out_msg_buffer().size() == 0u); - - // BOOST_FAIL("Test DID NOT FAIL. This is a failure placeholder used just to print all dynamic predicates"); -} -catch(const std::exception& e) -{ - BOOST_LOG_TRIVIAL(error) << e.what(); - BOOST_CHECK_NO_THROW( throw e ); -} +BOOST_FIXTURE_TEST_CASE(test_fbft_view_change_empty_00, ViewChangeEmptyFixture) { + try { + // Simulate receipt of a REQUEST message + uint32_t req_timestamp = 60; + Request request = + Request(m_configs[0]->genesis_block_timestamp(), m_configs[0]->target_block_time(), req_timestamp); + + BOOST_LOG_TRIVIAL(debug) << "Create Request with digest " << request.digest() << "at R0, R1, R2, R3"; + m_states[0]->ReceiveIncomingMessage(std::make_unique(request)); + m_states[1]->ReceiveIncomingMessage(std::make_unique(request)); + m_states[2]->ReceiveIncomingMessage(std::make_unique(request)); + m_states[3]->ReceiveIncomingMessage(std::make_unique(request)); + + BOOST_TEST(m_states[0]->active_actions().size() == 1u); + BOOST_CHECK(m_states[0]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_REQUEST); + BOOST_TEST(m_states[1]->active_actions().size() == 1u); + BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_REQUEST); + BOOST_TEST(m_states[2]->active_actions().size() == 1u); + BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_REQUEST); + BOOST_TEST(m_states[3]->active_actions().size() == 1u); + BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_REQUEST); + + BOOST_LOG_TRIVIAL(debug) << "Apply the receive request at R0, R1, R2, R3"; + m_states[0]->set_synthetic_time(req_timestamp); + m_states[1]->set_synthetic_time(req_timestamp); + m_states[2]->set_synthetic_time(req_timestamp); + m_states[3]->set_synthetic_time(req_timestamp); + + m_states[0]->Apply(*m_states[0]->active_actions().at(0)); + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + + BOOST_TEST(m_states[0]->active_actions().size() == 1u); + BOOST_CHECK(m_states[0]->active_actions().at(0)->type() == ACTION_TYPE::SEND_PRE_PREPARE); + BOOST_TEST(m_states[1]->active_actions().size() == 0u); + BOOST_TEST(m_states[2]->active_actions().size() == 0u); + + BOOST_LOG_TRIVIAL(debug) << "After 10+30 seconds, all backups should activate the view change"; + m_states[1]->set_synthetic_time(req_timestamp + m_configs[1]->target_block_time() / 2 + 1); + m_states[2]->set_synthetic_time(req_timestamp + m_configs[2]->target_block_time() / 2 + 1); + m_states[3]->set_synthetic_time(req_timestamp + m_configs[3]->target_block_time() / 2 + 1); + + BOOST_TEST(m_states[0]->active_actions().size() == 1u); + BOOST_CHECK(m_states[0]->active_actions().at(0)->type() == ACTION_TYPE::SEND_PRE_PREPARE); + BOOST_TEST(m_states[1]->active_actions().size() == 1u); + BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); + BOOST_TEST(m_states[2]->active_actions().size() == 1u); + BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); + BOOST_TEST(m_states[3]->active_actions().size() == 1u); + BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); + + BOOST_LOG_TRIVIAL(debug) << "Apply SEND_VIEW_CHANGE at R1 and R2"; + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + + BOOST_TEST(m_states[1]->active_actions().size() == 0u); + BOOST_TEST(m_states[2]->active_actions().size() == 0u); + BOOST_TEST(m_states[1]->out_msg_buffer().size() == 1u); + BOOST_CHECK(m_states[1]->out_msg_buffer().at(0)->type() == MSG_TYPE::VIEW_CHANGE); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 1u); + BOOST_CHECK(m_states[2]->out_msg_buffer().at(0)->type() == MSG_TYPE::VIEW_CHANGE); + BOOST_TEST(m_states[3]->out_msg_buffer().size() == 1u); + BOOST_CHECK(m_states[3]->out_msg_buffer().at(0)->type() == MSG_TYPE::VIEW_CHANGE); + + BOOST_LOG_TRIVIAL(debug) << "R1 and R2 receive each other VIEW_CHANGE"; + ViewChange view_change_1{dynamic_cast(*m_states[1]->out_msg_buffer().at(0))}; + m_wallets[1]->AppendSignature(view_change_1); + ViewChange view_change_2{dynamic_cast(*m_states[2]->out_msg_buffer().at(0))}; + m_wallets[2]->AppendSignature(view_change_2); + ViewChange view_change_3{dynamic_cast(*m_states[3]->out_msg_buffer().at(0))}; + m_wallets[3]->AppendSignature(view_change_3); + m_states[1]->ClearOutMessageBuffer(); + m_states[2]->ClearOutMessageBuffer(); + m_states[3]->ClearOutMessageBuffer(); + + m_states[1]->ReceiveIncomingMessage(std::make_unique(view_change_2)); + BOOST_TEST(m_states[1]->active_actions().size() == 1u); + BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_VIEW_CHANGE); + BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); + + m_states[2]->ReceiveIncomingMessage(std::make_unique(view_change_1)); + BOOST_TEST(m_states[2]->active_actions().size() == 1u); + BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_VIEW_CHANGE); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + BOOST_LOG_TRIVIAL(debug) << "Apply the receive view change at R1, R2"; + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + + BOOST_LOG_TRIVIAL(debug) << "R1 and R2 and R3 receive VIEW_CHANGEs from each other"; + m_states[1]->ReceiveIncomingMessage(std::make_unique(view_change_3)); + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + + m_states[2]->ReceiveIncomingMessage(std::make_unique(view_change_3)); + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + + m_states[3]->ReceiveIncomingMessage(std::make_unique(view_change_1)); + m_states[3]->ReceiveIncomingMessage(std::make_unique(view_change_2)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + + // R1, being the primary of the new view, should send the new view + BOOST_TEST(m_states[1]->active_actions().size() == 1u); + BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::SEND_NEW_VIEW); + BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); + + // R2 and R3, being backups of the new view, shoud do nothing + BOOST_TEST(m_states[2]->active_actions().size() == 0u); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + BOOST_TEST(m_states[3]->active_actions().size() == 0u); + BOOST_TEST(m_states[3]->out_msg_buffer().size() == 0u); + + BOOST_LOG_TRIVIAL(debug) << "Apply SEND_NEW_VIEW at R1"; + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + + BOOST_TEST(m_states[1]->active_actions().size() == 1u); + BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); + BOOST_TEST(m_states[1]->out_msg_buffer().size() == 1u); + BOOST_CHECK(m_states[1]->out_msg_buffer().at(0)->type() == MSG_TYPE::NEW_VIEW); + + BOOST_LOG_TRIVIAL(debug) << "R2 and R3 receive the NEW_VIEW message"; + NewView new_view_1{dynamic_cast(*m_states[1]->out_msg_buffer().at(0))}; + new_view_1.Sign(*m_wallets[1]); + m_states[1]->ClearOutMessageBuffer(); + + m_states[2]->ReceiveIncomingMessage(std::make_unique(new_view_1)); + BOOST_TEST(m_states[2]->active_actions().size() == 1u); + BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_NEW_VIEW); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + m_states[3]->ReceiveIncomingMessage(std::make_unique(new_view_1)); + BOOST_TEST(m_states[3]->active_actions().size() == 1u); + BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_NEW_VIEW); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + BOOST_LOG_TRIVIAL(debug) << "Apply RECEIVE_NEW_VIEW at R2 and R3"; + + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + BOOST_TEST(m_states[2]->active_actions().size() == 1u); + BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + BOOST_TEST(m_states[3]->active_actions().size() == 1u); + BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); + BOOST_TEST(m_states[3]->out_msg_buffer().size() == 0u); + + m_states[3]->Apply(*m_states[1]->active_actions().at(0)); + + BOOST_LOG_TRIVIAL(debug) << "Apply PROCESS_NEW_VIEW at R1"; + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + + BOOST_TEST(m_states[1]->active_actions().size() == 1u); + BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::SEND_PRE_PREPARE); + BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); + + BOOST_LOG_TRIVIAL(debug) << "Apply PROCESS_NEW_VIEW at R2 and R3"; + + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + BOOST_TEST(m_states[2]->active_actions().size() == 0u); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + BOOST_TEST(m_states[3]->active_actions().size() == 0u); + BOOST_TEST(m_states[3]->out_msg_buffer().size() == 0u); + + // BOOST_FAIL("Test DID NOT FAIL. This is a failure placeholder used just to print all dynamic + // predicates"); + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << e.what(); + BOOST_CHECK_NO_THROW(throw e); + } } BOOST_AUTO_TEST_SUITE_END() // test_fbft_view_change_empty diff --git a/src/test/test_fbft_view_change_prepared.cpp b/src/test/test_fbft_view_change_prepared.cpp index 3194153..d928820 100644 --- a/src/test/test_fbft_view_change_prepared.cpp +++ b/src/test/test_fbft_view_change_prepared.cpp @@ -11,224 +11,223 @@ using namespace itcoin::fbft::messages; namespace state = itcoin::fbft::state; -struct ViewChangePreparedFixture: ReplicaSetFixture { ViewChangePreparedFixture(): ReplicaSetFixture(4,0,60) {} }; +struct ViewChangePreparedFixture : ReplicaSetFixture { + ViewChangePreparedFixture() : ReplicaSetFixture(4, 0, 60) {} +}; BOOST_AUTO_TEST_SUITE(test_fbft_view_change_prepared, *utf::enabled()) -BOOST_FIXTURE_TEST_CASE(test_fbft_view_change_prepared_00, ViewChangePreparedFixture) -{ -try -{ - boost::log::core::get()->set_filter ( - boost::log::trivial::severity >= boost::log::trivial::trace - ); - - // Simulate receipt of a REQUEST message - uint32_t req_timestamp = 60; - Request request = Request(m_configs[0]->genesis_block_timestamp(), m_configs[0]->target_block_time(), req_timestamp); - - BOOST_LOG_TRIVIAL(debug) << "---------- Create Request with digest " << request.digest() << "at R0, R1, R2, R3"; - m_states[0]->set_synthetic_time(req_timestamp); - m_states[1]->set_synthetic_time(req_timestamp); - m_states[2]->set_synthetic_time(req_timestamp); - m_states[3]->set_synthetic_time(req_timestamp); - - m_states[0]->ReceiveIncomingMessage(std::make_unique(request)); - m_states[1]->ReceiveIncomingMessage(std::make_unique(request)); - m_states[2]->ReceiveIncomingMessage(std::make_unique(request)); - m_states[3]->ReceiveIncomingMessage(std::make_unique(request)); - - // We apply the results of the Receive REQUEST at all replicas - - m_states[0]->Apply(*m_states[0]->active_actions().at(0)); - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - - // Step 3. We apply the results of the Send PRE-PREPARE at replica 0 - // Now there should be no more active actions, but we should have a message in the output buffer - - m_states[0]->Apply(*m_states[0]->active_actions().at(0)); - - // Step 4. We send the PRE-PREPARE to other replicas - PrePrepare pre_prepare_0{dynamic_cast(*m_states[0]->out_msg_buffer().at(0))}; - m_states[0]->ClearOutMessageBuffer(); - - m_states[1]->ReceiveIncomingMessage(std::make_unique(pre_prepare_0)); - m_states[2]->ReceiveIncomingMessage(std::make_unique(pre_prepare_0)); - m_states[3]->ReceiveIncomingMessage(std::make_unique(pre_prepare_0)); - - // Step 6. We Receive the PRE_PREPARE to other replicas - - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - - // Step 7. We apply the SEND_PREPARE to all replicas - - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - - // Step 8. We receive PREPARE by Replica1 and Replica2 on Replica3, then we trigger a view change - - Prepare prepare_1{dynamic_cast(*m_states[1]->out_msg_buffer().at(0))}; - m_states[1]->ClearOutMessageBuffer(); - - Prepare prepare_2{dynamic_cast(*m_states[2]->out_msg_buffer().at(0))}; - m_states[2]->ClearOutMessageBuffer(); - - m_states[3]->ReceiveIncomingMessage(std::make_unique(prepare_1)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - - m_states[3]->ReceiveIncomingMessage(std::make_unique(prepare_2)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - - BOOST_LOG_TRIVIAL(debug) << "---------- Trigger VIEW_CHANGE"; - m_states[0]->set_synthetic_time(req_timestamp+m_configs[0]->target_block_time()/2+1); - m_states[1]->set_synthetic_time(req_timestamp+m_configs[1]->target_block_time()/2+1); - m_states[2]->set_synthetic_time(req_timestamp+m_configs[2]->target_block_time()/2+1); - m_states[3]->set_synthetic_time(req_timestamp+m_configs[3]->target_block_time()/2+1); - - m_states[1]->UpdateActiveActions(); - m_states[2]->UpdateActiveActions(); - m_states[3]->UpdateActiveActions(); - - BOOST_TEST(m_states[1]->active_actions().size() == 1u); - BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); - BOOST_TEST(m_states[2]->active_actions().size() == 1u); - BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); - BOOST_TEST(m_states[3]->active_actions().size() == 2u); - BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::SEND_COMMIT); - BOOST_CHECK(m_states[3]->active_actions().at(1)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); - - BOOST_LOG_TRIVIAL(debug) << "---------- Apply SEND_VIEW_CHANGE at R1 and R2"; - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - m_states[3]->Apply(*m_states[3]->active_actions().at(1)); - - BOOST_TEST(m_states[1]->active_actions().size() == 0u); - BOOST_TEST(m_states[2]->active_actions().size() == 0u); - BOOST_TEST(m_states[1]->out_msg_buffer().size() == 1u); - BOOST_CHECK(m_states[1]->out_msg_buffer().at(0)->type() == MSG_TYPE::VIEW_CHANGE); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 1u); - BOOST_CHECK(m_states[2]->out_msg_buffer().at(0)->type() == MSG_TYPE::VIEW_CHANGE); - BOOST_TEST(m_states[3]->out_msg_buffer().size() == 2u); - BOOST_CHECK(m_states[3]->out_msg_buffer().at(0)->type() == MSG_TYPE::PREPARE); - BOOST_CHECK(m_states[3]->out_msg_buffer().at(1)->type() == MSG_TYPE::VIEW_CHANGE); - - BOOST_LOG_TRIVIAL(debug) << "---------- R1 and R2 receive each other VIEW_CHANGE"; - // NB: ViewChange messages need to be signed, otherwise they will be forwarded without signatures - ViewChange view_change_1{dynamic_cast(*m_states[1]->out_msg_buffer().at(0))}; - m_wallets[1]->AppendSignature(view_change_1); - ViewChange view_change_2{dynamic_cast(*m_states[2]->out_msg_buffer().at(0))}; - m_wallets[2]->AppendSignature(view_change_2); - ViewChange view_change_3{dynamic_cast(*m_states[3]->out_msg_buffer().at(1))}; - m_wallets[3]->AppendSignature(view_change_3); - m_states[1]->ClearOutMessageBuffer(); - m_states[2]->ClearOutMessageBuffer(); - m_states[3]->ClearOutMessageBuffer(); - - m_states[1]->ReceiveIncomingMessage(std::make_unique(view_change_2)); - BOOST_TEST(m_states[1]->active_actions().size() == 1u); - BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_VIEW_CHANGE); - BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); - - m_states[2]->ReceiveIncomingMessage(std::make_unique(view_change_1)); - BOOST_TEST(m_states[2]->active_actions().size() == 1u); - BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_VIEW_CHANGE); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - BOOST_LOG_TRIVIAL(debug) << "---------- Apply the receive view change at R1, R2"; - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - - BOOST_LOG_TRIVIAL(debug) << "---------- R1 and R2 and R3 receive VIEW_CHANGEs from each other"; - m_states[1]->ReceiveIncomingMessage(std::make_unique(view_change_3)); - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - - m_states[2]->ReceiveIncomingMessage(std::make_unique(view_change_3)); - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - - m_states[3]->ReceiveIncomingMessage(std::make_unique(view_change_1)); - m_states[3]->ReceiveIncomingMessage(std::make_unique(view_change_2)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - - // R1, being the primary of the new view, should send the new view - BOOST_TEST(m_states[1]->active_actions().size() == 1u); - BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::SEND_NEW_VIEW); - BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); - - // R2 and R3, being backups of the new view, shoud do nothing - BOOST_TEST(m_states[2]->active_actions().size() == 0u); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - BOOST_TEST(m_states[3]->active_actions().size() == 0u); - BOOST_TEST(m_states[3]->out_msg_buffer().size() == 0u); - - BOOST_LOG_TRIVIAL(debug) << "---------- Apply SEND_NEW_VIEW at R1"; - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - - BOOST_TEST(m_states[1]->active_actions().size() == 1u); - BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); - BOOST_TEST(m_states[1]->out_msg_buffer().size() == 1u); - BOOST_CHECK(m_states[1]->out_msg_buffer().at(0)->type() == MSG_TYPE::NEW_VIEW); - - BOOST_LOG_TRIVIAL(debug) << "---------- R2 and R3 receive the NEW_VIEW message"; - NewView new_view_1{dynamic_cast(*m_states[1]->out_msg_buffer().at(0))}; - new_view_1.Sign(*m_wallets[1]); - m_states[1]->ClearOutMessageBuffer(); - - m_states[2]->ReceiveIncomingMessage(std::make_unique(new_view_1)); - BOOST_TEST(m_states[2]->active_actions().size() == 1u); - BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_NEW_VIEW); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - m_states[3]->ReceiveIncomingMessage(std::make_unique(new_view_1)); - BOOST_TEST(m_states[3]->active_actions().size() == 1u); - BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_NEW_VIEW); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - BOOST_LOG_TRIVIAL(debug) << "---------- Apply RECEIVE_NEW_VIEW at R2 and R3"; - - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - BOOST_TEST(m_states[2]->active_actions().size() == 1u); - BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); - - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - BOOST_TEST(m_states[3]->active_actions().size() == 1u); - BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); - BOOST_TEST(m_states[3]->out_msg_buffer().size() == 0u); - - m_states[3]->Apply(*m_states[1]->active_actions().at(0)); - - BOOST_LOG_TRIVIAL(debug) << "---------- Apply PROCESS_NEW_VIEW at R1"; - m_states[1]->Apply(*m_states[1]->active_actions().at(0)); - - BOOST_TEST(m_states[1]->active_actions().size() == 0u); - BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); - - BOOST_LOG_TRIVIAL(debug) << "---------- Apply PROCESS_NEW_VIEW at R2 and R3"; - - m_states[2]->Apply(*m_states[2]->active_actions().at(0)); - BOOST_TEST(m_states[2]->active_actions().size() == 0u); - BOOST_TEST(m_states[2]->out_msg_buffer().size() == 1u); - BOOST_CHECK(m_states[2]->out_msg_buffer().at(0)->type() == MSG_TYPE::PREPARE); - - m_states[3]->Apply(*m_states[3]->active_actions().at(0)); - BOOST_TEST(m_states[3]->active_actions().size() == 0u); - BOOST_TEST(m_states[3]->out_msg_buffer().size() == 1u); - BOOST_CHECK(m_states[3]->out_msg_buffer().at(0)->type() == MSG_TYPE::PREPARE); - - // BOOST_FAIL("Test DID NOT FAIL. This is a failure placeholder used just to print all dynamic predicates"); -} -catch(const std::exception& e) -{ - BOOST_LOG_TRIVIAL(error) << e.what(); - BOOST_CHECK_NO_THROW( throw e ); -} +BOOST_FIXTURE_TEST_CASE(test_fbft_view_change_prepared_00, ViewChangePreparedFixture) { + try { + boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::trace); + + // Simulate receipt of a REQUEST message + uint32_t req_timestamp = 60; + Request request = + Request(m_configs[0]->genesis_block_timestamp(), m_configs[0]->target_block_time(), req_timestamp); + + BOOST_LOG_TRIVIAL(debug) << "---------- Create Request with digest " << request.digest() + << "at R0, R1, R2, R3"; + m_states[0]->set_synthetic_time(req_timestamp); + m_states[1]->set_synthetic_time(req_timestamp); + m_states[2]->set_synthetic_time(req_timestamp); + m_states[3]->set_synthetic_time(req_timestamp); + + m_states[0]->ReceiveIncomingMessage(std::make_unique(request)); + m_states[1]->ReceiveIncomingMessage(std::make_unique(request)); + m_states[2]->ReceiveIncomingMessage(std::make_unique(request)); + m_states[3]->ReceiveIncomingMessage(std::make_unique(request)); + + // We apply the results of the Receive REQUEST at all replicas + + m_states[0]->Apply(*m_states[0]->active_actions().at(0)); + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + + // Step 3. We apply the results of the Send PRE-PREPARE at replica 0 + // Now there should be no more active actions, but we should have a message in the output buffer + + m_states[0]->Apply(*m_states[0]->active_actions().at(0)); + + // Step 4. We send the PRE-PREPARE to other replicas + PrePrepare pre_prepare_0{dynamic_cast(*m_states[0]->out_msg_buffer().at(0))}; + m_states[0]->ClearOutMessageBuffer(); + + m_states[1]->ReceiveIncomingMessage(std::make_unique(pre_prepare_0)); + m_states[2]->ReceiveIncomingMessage(std::make_unique(pre_prepare_0)); + m_states[3]->ReceiveIncomingMessage(std::make_unique(pre_prepare_0)); + + // Step 6. We Receive the PRE_PREPARE to other replicas + + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + + // Step 7. We apply the SEND_PREPARE to all replicas + + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + + // Step 8. We receive PREPARE by Replica1 and Replica2 on Replica3, then we trigger a view change + + Prepare prepare_1{dynamic_cast(*m_states[1]->out_msg_buffer().at(0))}; + m_states[1]->ClearOutMessageBuffer(); + + Prepare prepare_2{dynamic_cast(*m_states[2]->out_msg_buffer().at(0))}; + m_states[2]->ClearOutMessageBuffer(); + + m_states[3]->ReceiveIncomingMessage(std::make_unique(prepare_1)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + + m_states[3]->ReceiveIncomingMessage(std::make_unique(prepare_2)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + + BOOST_LOG_TRIVIAL(debug) << "---------- Trigger VIEW_CHANGE"; + m_states[0]->set_synthetic_time(req_timestamp + m_configs[0]->target_block_time() / 2 + 1); + m_states[1]->set_synthetic_time(req_timestamp + m_configs[1]->target_block_time() / 2 + 1); + m_states[2]->set_synthetic_time(req_timestamp + m_configs[2]->target_block_time() / 2 + 1); + m_states[3]->set_synthetic_time(req_timestamp + m_configs[3]->target_block_time() / 2 + 1); + + m_states[1]->UpdateActiveActions(); + m_states[2]->UpdateActiveActions(); + m_states[3]->UpdateActiveActions(); + + BOOST_TEST(m_states[1]->active_actions().size() == 1u); + BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); + BOOST_TEST(m_states[2]->active_actions().size() == 1u); + BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); + BOOST_TEST(m_states[3]->active_actions().size() == 2u); + BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::SEND_COMMIT); + BOOST_CHECK(m_states[3]->active_actions().at(1)->type() == ACTION_TYPE::SEND_VIEW_CHANGE); + + BOOST_LOG_TRIVIAL(debug) << "---------- Apply SEND_VIEW_CHANGE at R1 and R2"; + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + m_states[3]->Apply(*m_states[3]->active_actions().at(1)); + + BOOST_TEST(m_states[1]->active_actions().size() == 0u); + BOOST_TEST(m_states[2]->active_actions().size() == 0u); + BOOST_TEST(m_states[1]->out_msg_buffer().size() == 1u); + BOOST_CHECK(m_states[1]->out_msg_buffer().at(0)->type() == MSG_TYPE::VIEW_CHANGE); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 1u); + BOOST_CHECK(m_states[2]->out_msg_buffer().at(0)->type() == MSG_TYPE::VIEW_CHANGE); + BOOST_TEST(m_states[3]->out_msg_buffer().size() == 2u); + BOOST_CHECK(m_states[3]->out_msg_buffer().at(0)->type() == MSG_TYPE::PREPARE); + BOOST_CHECK(m_states[3]->out_msg_buffer().at(1)->type() == MSG_TYPE::VIEW_CHANGE); + + BOOST_LOG_TRIVIAL(debug) << "---------- R1 and R2 receive each other VIEW_CHANGE"; + // NB: ViewChange messages need to be signed, otherwise they will be forwarded without signatures + ViewChange view_change_1{dynamic_cast(*m_states[1]->out_msg_buffer().at(0))}; + m_wallets[1]->AppendSignature(view_change_1); + ViewChange view_change_2{dynamic_cast(*m_states[2]->out_msg_buffer().at(0))}; + m_wallets[2]->AppendSignature(view_change_2); + ViewChange view_change_3{dynamic_cast(*m_states[3]->out_msg_buffer().at(1))}; + m_wallets[3]->AppendSignature(view_change_3); + m_states[1]->ClearOutMessageBuffer(); + m_states[2]->ClearOutMessageBuffer(); + m_states[3]->ClearOutMessageBuffer(); + + m_states[1]->ReceiveIncomingMessage(std::make_unique(view_change_2)); + BOOST_TEST(m_states[1]->active_actions().size() == 1u); + BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_VIEW_CHANGE); + BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); + + m_states[2]->ReceiveIncomingMessage(std::make_unique(view_change_1)); + BOOST_TEST(m_states[2]->active_actions().size() == 1u); + BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_VIEW_CHANGE); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + BOOST_LOG_TRIVIAL(debug) << "---------- Apply the receive view change at R1, R2"; + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + + BOOST_LOG_TRIVIAL(debug) << "---------- R1 and R2 and R3 receive VIEW_CHANGEs from each other"; + m_states[1]->ReceiveIncomingMessage(std::make_unique(view_change_3)); + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + + m_states[2]->ReceiveIncomingMessage(std::make_unique(view_change_3)); + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + + m_states[3]->ReceiveIncomingMessage(std::make_unique(view_change_1)); + m_states[3]->ReceiveIncomingMessage(std::make_unique(view_change_2)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + + // R1, being the primary of the new view, should send the new view + BOOST_TEST(m_states[1]->active_actions().size() == 1u); + BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::SEND_NEW_VIEW); + BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); + + // R2 and R3, being backups of the new view, shoud do nothing + BOOST_TEST(m_states[2]->active_actions().size() == 0u); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + BOOST_TEST(m_states[3]->active_actions().size() == 0u); + BOOST_TEST(m_states[3]->out_msg_buffer().size() == 0u); + + BOOST_LOG_TRIVIAL(debug) << "---------- Apply SEND_NEW_VIEW at R1"; + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + + BOOST_TEST(m_states[1]->active_actions().size() == 1u); + BOOST_CHECK(m_states[1]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); + BOOST_TEST(m_states[1]->out_msg_buffer().size() == 1u); + BOOST_CHECK(m_states[1]->out_msg_buffer().at(0)->type() == MSG_TYPE::NEW_VIEW); + + BOOST_LOG_TRIVIAL(debug) << "---------- R2 and R3 receive the NEW_VIEW message"; + NewView new_view_1{dynamic_cast(*m_states[1]->out_msg_buffer().at(0))}; + new_view_1.Sign(*m_wallets[1]); + m_states[1]->ClearOutMessageBuffer(); + + m_states[2]->ReceiveIncomingMessage(std::make_unique(new_view_1)); + BOOST_TEST(m_states[2]->active_actions().size() == 1u); + BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_NEW_VIEW); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + m_states[3]->ReceiveIncomingMessage(std::make_unique(new_view_1)); + BOOST_TEST(m_states[3]->active_actions().size() == 1u); + BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::RECEIVE_NEW_VIEW); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + BOOST_LOG_TRIVIAL(debug) << "---------- Apply RECEIVE_NEW_VIEW at R2 and R3"; + + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + BOOST_TEST(m_states[2]->active_actions().size() == 1u); + BOOST_CHECK(m_states[2]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 0u); + + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + BOOST_TEST(m_states[3]->active_actions().size() == 1u); + BOOST_CHECK(m_states[3]->active_actions().at(0)->type() == ACTION_TYPE::PROCESS_NEW_VIEW); + BOOST_TEST(m_states[3]->out_msg_buffer().size() == 0u); + + m_states[3]->Apply(*m_states[1]->active_actions().at(0)); + + BOOST_LOG_TRIVIAL(debug) << "---------- Apply PROCESS_NEW_VIEW at R1"; + m_states[1]->Apply(*m_states[1]->active_actions().at(0)); + + BOOST_TEST(m_states[1]->active_actions().size() == 0u); + BOOST_TEST(m_states[1]->out_msg_buffer().size() == 0u); + + BOOST_LOG_TRIVIAL(debug) << "---------- Apply PROCESS_NEW_VIEW at R2 and R3"; + + m_states[2]->Apply(*m_states[2]->active_actions().at(0)); + BOOST_TEST(m_states[2]->active_actions().size() == 0u); + BOOST_TEST(m_states[2]->out_msg_buffer().size() == 1u); + BOOST_CHECK(m_states[2]->out_msg_buffer().at(0)->type() == MSG_TYPE::PREPARE); + + m_states[3]->Apply(*m_states[3]->active_actions().at(0)); + BOOST_TEST(m_states[3]->active_actions().size() == 0u); + BOOST_TEST(m_states[3]->out_msg_buffer().size() == 1u); + BOOST_CHECK(m_states[3]->out_msg_buffer().at(0)->type() == MSG_TYPE::PREPARE); + + // BOOST_FAIL("Test DID NOT FAIL. This is a failure placeholder used just to print all dynamic + // predicates"); + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << e.what(); + BOOST_CHECK_NO_THROW(throw e); + } } BOOST_AUTO_TEST_SUITE_END() // test_fbft_view_change_prepared diff --git a/src/test/test_messages_encoding.cpp b/src/test/test_messages_encoding.cpp index 7f9d7c3..e552d28 100644 --- a/src/test/test_messages_encoding.cpp +++ b/src/test/test_messages_encoding.cpp @@ -13,220 +13,214 @@ using namespace std; using namespace boost::unit_test; using namespace itcoin::fbft::messages; -struct MessagesEncodingFixture: ReplicaStateFixture { MessagesEncodingFixture(): ReplicaStateFixture(4,0,60) {} }; +struct MessagesEncodingFixture : ReplicaStateFixture { + MessagesEncodingFixture() : ReplicaStateFixture(4, 0, 60) {} +}; BOOST_AUTO_TEST_SUITE(test_messages_encoding, *enabled()) -BOOST_FIXTURE_TEST_CASE(test_messages_encoding_00, MessagesEncodingFixture) -{ - boost::log::core::get()->set_filter ( - boost::log::trivial::severity >= boost::log::trivial::trace - ); +BOOST_FIXTURE_TEST_CASE(test_messages_encoding_00, MessagesEncodingFixture) { + boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::trace); // // Commit // { - uint32_t sender_id = 3, v = 11, n = 17; - string block_signature = "Hello block signature"; - Commit msg = Commit(sender_id, v, n, block_signature); + uint32_t sender_id = 3, v = 11, n = 17; + string block_signature = "Hello block signature"; + Commit msg = Commit(sender_id, v, n, block_signature); - m_wallets[sender_id]->AppendSignature(msg); - string msg_as_bin = msg.ToBinBuffer(); + m_wallets[sender_id]->AppendSignature(msg); + string msg_as_bin = msg.ToBinBuffer(); - optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); - BOOST_TEST(msg_built_opt.has_value()); + optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); + BOOST_TEST(msg_built_opt.has_value()); - unique_ptr& msg_built = msg_built_opt.value(); - BOOST_CHECK(msg_built->type() == MSG_TYPE::COMMIT); + unique_ptr& msg_built = msg_built_opt.value(); + BOOST_CHECK(msg_built->type() == MSG_TYPE::COMMIT); - Commit typed_msg_built{ dynamic_cast(*msg_built) }; - BOOST_CHECK(typed_msg_built.view() == v); - BOOST_CHECK(typed_msg_built.seq_number() == n); - BOOST_CHECK(typed_msg_built.pre_signature() == msg.pre_signature()); - BOOST_CHECK(typed_msg_built.signature() == msg.signature()); - BOOST_CHECK(typed_msg_built.digest() == msg.digest()); + Commit typed_msg_built{dynamic_cast(*msg_built)}; + BOOST_CHECK(typed_msg_built.view() == v); + BOOST_CHECK(typed_msg_built.seq_number() == n); + BOOST_CHECK(typed_msg_built.pre_signature() == msg.pre_signature()); + BOOST_CHECK(typed_msg_built.signature() == msg.signature()); + BOOST_CHECK(typed_msg_built.digest() == msg.digest()); } // // NewView // { - uint32_t sender_id = 3, v = 11; - - uint32_t sender_id_vc = 2, v_vc = 11, hi = 17; - std::string c = "This is the checkpoint digest"; - view_change_prepared_elem_t pi_elem = make_tuple(1, "req_digest", 10); - view_change_prepared_t pi = {pi_elem}; - view_change_pre_prepared_elem_t q_elem = make_tuple(1, "req_digest", "block_hex", 10); - view_change_pre_prepared_t qi = {q_elem}; - ViewChange vc_0 = ViewChange(sender_id_vc, v_vc, hi, c, pi, qi); - - uint32_t sender_id_ppp = 0, v_ppp = 11, n = 17; - string req_digest{"abcdef"}; - CBlock block = m_blockchain->GenerateBlock(0); - PrePrepare ppp_0 = PrePrepare( - sender_id_ppp, v_ppp, n, req_digest, block - ); - - NewView msg = NewView(sender_id, v, - vector{vc_0}, - vector{ppp_0} - ); - - m_wallets[sender_id]->AppendSignature(msg); - string msg_as_bin = msg.ToBinBuffer(); - - optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); - BOOST_TEST(msg_built_opt.has_value()); - - unique_ptr& msg_built = msg_built_opt.value(); - BOOST_CHECK(msg_built->type() == MSG_TYPE::NEW_VIEW); - - NewView typed_msg_built{ dynamic_cast(*msg_built) }; - BOOST_CHECK(typed_msg_built.view() == v); - BOOST_CHECK(typed_msg_built.view_changes() == msg.view_changes()); - BOOST_CHECK(typed_msg_built.pre_prepares() == msg.pre_prepares()); - BOOST_CHECK(typed_msg_built.signature() == msg.signature()); - BOOST_CHECK(typed_msg_built.digest() == msg.digest()); + uint32_t sender_id = 3, v = 11; + + uint32_t sender_id_vc = 2, v_vc = 11, hi = 17; + std::string c = "This is the checkpoint digest"; + view_change_prepared_elem_t pi_elem = make_tuple(1, "req_digest", 10); + view_change_prepared_t pi = {pi_elem}; + view_change_pre_prepared_elem_t q_elem = make_tuple(1, "req_digest", "block_hex", 10); + view_change_pre_prepared_t qi = {q_elem}; + ViewChange vc_0 = ViewChange(sender_id_vc, v_vc, hi, c, pi, qi); + + uint32_t sender_id_ppp = 0, v_ppp = 11, n = 17; + string req_digest{"abcdef"}; + CBlock block = m_blockchain->GenerateBlock(0); + PrePrepare ppp_0 = PrePrepare(sender_id_ppp, v_ppp, n, req_digest, block); + + NewView msg = NewView(sender_id, v, vector{vc_0}, vector{ppp_0}); + + m_wallets[sender_id]->AppendSignature(msg); + string msg_as_bin = msg.ToBinBuffer(); + + optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); + BOOST_TEST(msg_built_opt.has_value()); + + unique_ptr& msg_built = msg_built_opt.value(); + BOOST_CHECK(msg_built->type() == MSG_TYPE::NEW_VIEW); + + NewView typed_msg_built{dynamic_cast(*msg_built)}; + BOOST_CHECK(typed_msg_built.view() == v); + BOOST_CHECK(typed_msg_built.view_changes() == msg.view_changes()); + BOOST_CHECK(typed_msg_built.pre_prepares() == msg.pre_prepares()); + BOOST_CHECK(typed_msg_built.signature() == msg.signature()); + BOOST_CHECK(typed_msg_built.digest() == msg.digest()); } // // Prepare // { - uint32_t sender_id = 3, v = 11, n = 17; - string req_digest{"abcdef"}; - Prepare msg = Prepare(sender_id, v, n, req_digest); + uint32_t sender_id = 3, v = 11, n = 17; + string req_digest{"abcdef"}; + Prepare msg = Prepare(sender_id, v, n, req_digest); - m_wallets[sender_id]->AppendSignature(msg); - string msg_as_bin = msg.ToBinBuffer(); + m_wallets[sender_id]->AppendSignature(msg); + string msg_as_bin = msg.ToBinBuffer(); - optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); - BOOST_TEST(msg_built_opt.has_value()); + optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); + BOOST_TEST(msg_built_opt.has_value()); - unique_ptr& msg_built = msg_built_opt.value(); - BOOST_CHECK(msg_built->type() == MSG_TYPE::PREPARE); + unique_ptr& msg_built = msg_built_opt.value(); + BOOST_CHECK(msg_built->type() == MSG_TYPE::PREPARE); - Prepare typed_msg_built{ dynamic_cast(*msg_built) }; - BOOST_CHECK(typed_msg_built.view() == v); - BOOST_CHECK(typed_msg_built.seq_number() == n); - BOOST_CHECK(typed_msg_built.req_digest() == req_digest); - BOOST_CHECK(typed_msg_built.signature() == msg.signature()); - BOOST_CHECK(typed_msg_built.digest() == msg.digest()); + Prepare typed_msg_built{dynamic_cast(*msg_built)}; + BOOST_CHECK(typed_msg_built.view() == v); + BOOST_CHECK(typed_msg_built.seq_number() == n); + BOOST_CHECK(typed_msg_built.req_digest() == req_digest); + BOOST_CHECK(typed_msg_built.signature() == msg.signature()); + BOOST_CHECK(typed_msg_built.digest() == msg.digest()); } // // PrePrepare // { - uint32_t sender_id = 3, v = 11, n = 17; - string req_digest{"abcdef"}; - CBlock block = m_blockchain->GenerateBlock(666); - PrePrepare msg = PrePrepare(sender_id, v, n, req_digest, block); - - m_wallets[sender_id]->AppendSignature(msg); - string msg_as_bin = msg.ToBinBuffer(); - - optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); - BOOST_TEST(msg_built_opt.has_value()); - - unique_ptr& msg_built = msg_built_opt.value(); - BOOST_CHECK(msg_built->type() == MSG_TYPE::PRE_PREPARE); - - PrePrepare typed_msg_built{ dynamic_cast(*msg_built) }; - BOOST_CHECK(typed_msg_built.view() == v); - BOOST_CHECK(typed_msg_built.seq_number() == n); - BOOST_CHECK(typed_msg_built.req_digest() == req_digest); - BOOST_CHECK(typed_msg_built.proposed_block_hex() == msg.proposed_block_hex()); - BOOST_CHECK(typed_msg_built.signature() == msg.signature()); - BOOST_CHECK(typed_msg_built.digest() == msg.digest()); + uint32_t sender_id = 3, v = 11, n = 17; + string req_digest{"abcdef"}; + CBlock block = m_blockchain->GenerateBlock(666); + PrePrepare msg = PrePrepare(sender_id, v, n, req_digest, block); + + m_wallets[sender_id]->AppendSignature(msg); + string msg_as_bin = msg.ToBinBuffer(); + + optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); + BOOST_TEST(msg_built_opt.has_value()); + + unique_ptr& msg_built = msg_built_opt.value(); + BOOST_CHECK(msg_built->type() == MSG_TYPE::PRE_PREPARE); + + PrePrepare typed_msg_built{dynamic_cast(*msg_built)}; + BOOST_CHECK(typed_msg_built.view() == v); + BOOST_CHECK(typed_msg_built.seq_number() == n); + BOOST_CHECK(typed_msg_built.req_digest() == req_digest); + BOOST_CHECK(typed_msg_built.proposed_block_hex() == msg.proposed_block_hex()); + BOOST_CHECK(typed_msg_built.signature() == msg.signature()); + BOOST_CHECK(typed_msg_built.digest() == msg.digest()); } // // ViewChange // { - uint32_t sender_id = 3, v = 11, hi = 17; - std::string c = "This is the checkpoint digest"; - view_change_prepared_elem_t pi_elem = make_tuple(1, "req_digest", 10); - view_change_prepared_t pi = {pi_elem}; - view_change_pre_prepared_elem_t q_elem = make_tuple(1, "req_digest", "block_hex", 10); - view_change_pre_prepared_t qi = {q_elem}; - - ViewChange msg = ViewChange(sender_id, v, hi, c, pi, qi); - - m_wallets[sender_id]->AppendSignature(msg); - string msg_as_bin = msg.ToBinBuffer(); - - optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); - BOOST_TEST(msg_built_opt.has_value()); - - unique_ptr& msg_built = msg_built_opt.value(); - BOOST_CHECK(msg_built->type() == MSG_TYPE::VIEW_CHANGE); - - ViewChange typed_msg_built{ dynamic_cast(*msg_built) }; - BOOST_CHECK(typed_msg_built.view() == v); - BOOST_CHECK(typed_msg_built.hi() == hi); - BOOST_CHECK(typed_msg_built.c() == c); - BOOST_CHECK(typed_msg_built.pi() == pi); - BOOST_CHECK(typed_msg_built.qi() == qi); - BOOST_CHECK(typed_msg_built.signature() == msg.signature()); - BOOST_CHECK(typed_msg_built.digest() == msg.digest()); + uint32_t sender_id = 3, v = 11, hi = 17; + std::string c = "This is the checkpoint digest"; + view_change_prepared_elem_t pi_elem = make_tuple(1, "req_digest", 10); + view_change_prepared_t pi = {pi_elem}; + view_change_pre_prepared_elem_t q_elem = make_tuple(1, "req_digest", "block_hex", 10); + view_change_pre_prepared_t qi = {q_elem}; + + ViewChange msg = ViewChange(sender_id, v, hi, c, pi, qi); + + m_wallets[sender_id]->AppendSignature(msg); + string msg_as_bin = msg.ToBinBuffer(); + + optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); + BOOST_TEST(msg_built_opt.has_value()); + + unique_ptr& msg_built = msg_built_opt.value(); + BOOST_CHECK(msg_built->type() == MSG_TYPE::VIEW_CHANGE); + + ViewChange typed_msg_built{dynamic_cast(*msg_built)}; + BOOST_CHECK(typed_msg_built.view() == v); + BOOST_CHECK(typed_msg_built.hi() == hi); + BOOST_CHECK(typed_msg_built.c() == c); + BOOST_CHECK(typed_msg_built.pi() == pi); + BOOST_CHECK(typed_msg_built.qi() == qi); + BOOST_CHECK(typed_msg_built.signature() == msg.signature()); + BOOST_CHECK(typed_msg_built.digest() == msg.digest()); } // // RoastSignatureShare // { - uint32_t sender_id = 3; - std::string signature_share = "Sigshare"; - std::string next_presignature_share = "Presigshare"; + uint32_t sender_id = 3; + std::string signature_share = "Sigshare"; + std::string next_presignature_share = "Presigshare"; - RoastSignatureShare msg = RoastSignatureShare(sender_id, signature_share, next_presignature_share); + RoastSignatureShare msg = RoastSignatureShare(sender_id, signature_share, next_presignature_share); - m_wallets[sender_id]->AppendSignature(msg); - string msg_as_bin = msg.ToBinBuffer(); + m_wallets[sender_id]->AppendSignature(msg); + string msg_as_bin = msg.ToBinBuffer(); - optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); - BOOST_TEST(msg_built_opt.has_value()); + optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); + BOOST_TEST(msg_built_opt.has_value()); - unique_ptr& msg_built = msg_built_opt.value(); - BOOST_CHECK(msg_built->type() == MSG_TYPE::ROAST_SIGNATURE_SHARE); + unique_ptr& msg_built = msg_built_opt.value(); + BOOST_CHECK(msg_built->type() == MSG_TYPE::ROAST_SIGNATURE_SHARE); - RoastSignatureShare typed_msg_built{ dynamic_cast(*msg_built) }; - BOOST_CHECK(typed_msg_built.sender_id() == sender_id); - BOOST_CHECK(typed_msg_built.signature_share() == signature_share); - BOOST_CHECK(typed_msg_built.next_pre_signature_share() == next_presignature_share); - BOOST_CHECK(typed_msg_built.signature() == msg.signature()); - BOOST_CHECK(typed_msg_built.digest() == msg.digest()); + RoastSignatureShare typed_msg_built{dynamic_cast(*msg_built)}; + BOOST_CHECK(typed_msg_built.sender_id() == sender_id); + BOOST_CHECK(typed_msg_built.signature_share() == signature_share); + BOOST_CHECK(typed_msg_built.next_pre_signature_share() == next_presignature_share); + BOOST_CHECK(typed_msg_built.signature() == msg.signature()); + BOOST_CHECK(typed_msg_built.digest() == msg.digest()); } // // RoastPreSignature // { - uint32_t sender_id = 3; - std::string pre_signature = "Sigshare"; - std::vector signers = {0,1,2}; + uint32_t sender_id = 3; + std::string pre_signature = "Sigshare"; + std::vector signers = {0, 1, 2}; - RoastPreSignature msg = RoastPreSignature(sender_id, signers, pre_signature); + RoastPreSignature msg = RoastPreSignature(sender_id, signers, pre_signature); - m_wallets[sender_id]->AppendSignature(msg); - string msg_as_bin = msg.ToBinBuffer(); + m_wallets[sender_id]->AppendSignature(msg); + string msg_as_bin = msg.ToBinBuffer(); - optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); - BOOST_TEST(msg_built_opt.has_value()); + optional> msg_built_opt = Message::BuildFromBinBuffer(msg_as_bin); + BOOST_TEST(msg_built_opt.has_value()); - unique_ptr& msg_built = msg_built_opt.value(); - BOOST_CHECK(msg_built->type() == MSG_TYPE::ROAST_PRE_SIGNATURE); + unique_ptr& msg_built = msg_built_opt.value(); + BOOST_CHECK(msg_built->type() == MSG_TYPE::ROAST_PRE_SIGNATURE); - RoastPreSignature typed_msg_built{ dynamic_cast(*msg_built) }; - BOOST_CHECK(typed_msg_built.sender_id() == sender_id); - BOOST_CHECK(typed_msg_built.pre_signature() == pre_signature); - BOOST_CHECK(typed_msg_built.signers() == signers); - BOOST_CHECK(typed_msg_built.signature() == msg.signature()); - BOOST_CHECK(typed_msg_built.digest() == msg.digest()); + RoastPreSignature typed_msg_built{dynamic_cast(*msg_built)}; + BOOST_CHECK(typed_msg_built.sender_id() == sender_id); + BOOST_CHECK(typed_msg_built.pre_signature() == pre_signature); + BOOST_CHECK(typed_msg_built.signers() == signers); + BOOST_CHECK(typed_msg_built.signature() == msg.signature()); + BOOST_CHECK(typed_msg_built.digest() == msg.digest()); } } // test_messages_encoding_prepare diff --git a/src/test/test_transport_btcclient.cpp b/src/test/test_transport_btcclient.cpp index 7205235..55cbf12 100644 --- a/src/test/test_transport_btcclient.cpp +++ b/src/test/test_transport_btcclient.cpp @@ -1,8 +1,8 @@ // Copyright (c) 2023 Bank of Italy // Distributed under the GNU AGPLv3 software license, see the accompanying COPYING file. -#include #include +#include #include @@ -21,14 +21,15 @@ using std::vector; const std::string helloWorld{"hello world"}; // how bitcoind 0 would sign helloWorld using the wallet address of client00 -const std::string helloSignature{"IOzKScUZOETfXTwQFFNP+xMigAXMMTEZhLglGAe197ldMC15bnokhgMPR/l1QrCsJIgK0gCUW1NyemCy1ChHhfU="}; +const std::string helloSignature{ + "IOzKScUZOETfXTwQFFNP+xMigAXMMTEZhLglGAe197ldMC15bnokhgMPR/l1QrCsJIgK0gCUW1NyemCy1ChHhfU="}; /* -* The string "bWFsZm9ybWVkIHNpZ25hdHVyZQ==" is the base64 encoding of -* "malformed signature". It can be verified with: -* -* echo -n "malformed signature" | base64 -*/ + * The string "bWFsZm9ybWVkIHNpZ25hdHVyZQ==" is the base64 encoding of + * "malformed signature". It can be verified with: + * + * echo -n "malformed signature" | base64 + */ const std::string malformedSignature = "bWFsZm9ybWVkIHNpZ25hdHVyZQ=="; std::string buildEmptyPsbt() { @@ -51,8 +52,7 @@ BOOST_AUTO_TEST_SUITE(test_transport_btcclient, *utf::enabled()) using namespace itcoin; // Integration test with Bitcoind for the getblockchaininfo RPC method -BOOST_FIXTURE_TEST_CASE(test_getblockchaininfo, BtcClientFixture) -{ +BOOST_FIXTURE_TEST_CASE(test_getblockchaininfo, BtcClientFixture) { auto response = bitcoind0.getblockchaininfo(); // Test that the response is a Json::Value object @@ -67,8 +67,7 @@ BOOST_FIXTURE_TEST_CASE(test_getblockchaininfo, BtcClientFixture) } // Integration test with Bitcoind for the getblocktemplate RPC method -BOOST_FIXTURE_TEST_CASE(test_getblocktemplate, BtcClientFixture) -{ +BOOST_FIXTURE_TEST_CASE(test_getblocktemplate, BtcClientFixture) { Json::Value root; Json::Value rules; @@ -91,8 +90,7 @@ BOOST_FIXTURE_TEST_CASE(test_getblocktemplate, BtcClientFixture) } // Integration test with Bitcoind for the walletprocesspsbt RPC method -BOOST_FIXTURE_TEST_CASE(test_walletprocesspsbt, BtcClientFixture) -{ +BOOST_FIXTURE_TEST_CASE(test_walletprocesspsbt, BtcClientFixture) { auto psbtBase64 = buildEmptyPsbt(); BOOST_LOG_TRIVIAL(info) << "Sending a walletprocesspsbt request with argument " << psbtBase64; // send the walletprocesspsbt request @@ -108,30 +106,24 @@ BOOST_FIXTURE_TEST_CASE(test_walletprocesspsbt, BtcClientFixture) } // Integration test with Bitcoind for the combinepsbt RPC method -BOOST_FIXTURE_TEST_CASE(test_combinepsbt, BtcClientFixture) -{ +BOOST_FIXTURE_TEST_CASE(test_combinepsbt, BtcClientFixture) { auto psbtBase64 = buildEmptyPsbt(); Json::Value list; list.append(psbtBase64); list.append(psbtBase64); - BOOST_LOG_TRIVIAL(info) << "Sending a combinepsbt request with arguments " << psbtBase64 << " and " << psbtBase64; + BOOST_LOG_TRIVIAL(info) << "Sending a combinepsbt request with arguments " << psbtBase64 << " and " + << psbtBase64; std::string response = bitcoind0.combinepsbt(list); BOOST_TEST(psbtBase64 == response); } // Integration test with Bitcoind for the finalizepsbt RPC method -BOOST_DATA_TEST_CASE_F( - BtcClientFixture, - test_finalizepsbt, - bdata::make({ - true, false - }), - extractHex -) { +BOOST_DATA_TEST_CASE_F(BtcClientFixture, test_finalizepsbt, bdata::make({true, false}), extractHex) { auto psbtBase64 = buildEmptyPsbt(); Json::Value response; - BOOST_LOG_TRIVIAL(info) << "Sending a finalizepsbt request with arguments psbt=" << psbtBase64 << " and extract=" << extractHex; + BOOST_LOG_TRIVIAL(info) << "Sending a finalizepsbt request with arguments psbt=" << psbtBase64 + << " and extract=" << extractHex; response = bitcoind0.finalizepsbt(psbtBase64, extractHex); BOOST_TEST(response.isObject()); BOOST_TEST(response.isMember("psbt") == (!extractHex)); @@ -140,8 +132,7 @@ BOOST_DATA_TEST_CASE_F( } // Integration test with Bitcoind for the analyzepsbt RPC method -BOOST_FIXTURE_TEST_CASE(test_analyzepsbt, BtcClientFixture) -{ +BOOST_FIXTURE_TEST_CASE(test_analyzepsbt, BtcClientFixture) { auto psbtBase64 = buildEmptyPsbt(); BOOST_LOG_TRIVIAL(info) << "Sending a finalizepsbt request with arguments psbt=" << psbtBase64; auto response = bitcoind0.analyzepsbt(psbtBase64); @@ -155,13 +146,13 @@ BOOST_FIXTURE_TEST_CASE(test_analyzepsbt, BtcClientFixture) } // Integration test with Bitcoind for the submitblock RPC method (failure) -BOOST_FIXTURE_TEST_CASE(test_submitblock_fails, BtcClientFixture) -{ +BOOST_FIXTURE_TEST_CASE(test_submitblock_fails, BtcClientFixture) { const int expectedCode = -32603; auto isInvalidBlockError = [](jsonrpc::JsonRpcException e) -> bool { if (e.GetCode() != expectedCode) { - BOOST_LOG_TRIVIAL(error) << "Wrong code in exception: " + std::to_string(e.GetCode()) + " instead of " + std::to_string(expectedCode); + BOOST_LOG_TRIVIAL(error) << "Wrong code in exception: " + std::to_string(e.GetCode()) + " instead of " + + std::to_string(expectedCode); return false; } @@ -175,33 +166,37 @@ BOOST_FIXTURE_TEST_CASE(test_submitblock_fails, BtcClientFixture) }; // isInvalidBlockError() BOOST_LOG_TRIVIAL(info) << "Submitting an invalid block"; - BOOST_CHECK_EXCEPTION(bitcoind0.submitblock("INVALID BLOCK"), jsonrpc::JsonRpcException, isInvalidBlockError); + BOOST_CHECK_EXCEPTION(bitcoind0.submitblock("INVALID BLOCK"), jsonrpc::JsonRpcException, + isInvalidBlockError); } // Integration test with Bitcoind for the testblockvalidity RPC method -BOOST_FIXTURE_TEST_CASE(testblockvalidity, BtcClientFixture) -{ - const int expectedCode = -32603; - - auto isInvalidBlockError = [](const jsonrpc::JsonRpcException& e) -> bool { - if (e.GetCode() != expectedCode) { - BOOST_LOG_TRIVIAL(error) << "Wrong code in exception: " + std::to_string(e.GetCode()) + " instead of " + std::to_string(expectedCode); - return false; - } - - if (e.GetMessage().find("Block decode failed") == std::string::npos) { - BOOST_LOG_TRIVIAL(error) << "Wrong message in exception: " + e.GetMessage(); - return false; - } - - BOOST_LOG_TRIVIAL(debug) << "OK: received a 'Block decode failed' error"; - return true; - }; // isInvalidBlockError() - - BOOST_LOG_TRIVIAL(info) << "Test validity of an invalid block"; - BOOST_CHECK_EXCEPTION(bitcoind0.testblockvalidity("INVALID BLOCK"), jsonrpc::JsonRpcException, isInvalidBlockError); - BOOST_CHECK_EXCEPTION(bitcoind0.testblockvalidity("INVALID BLOCK", true), jsonrpc::JsonRpcException, isInvalidBlockError); - BOOST_CHECK_EXCEPTION(bitcoind0.testblockvalidity("INVALID BLOCK", false), jsonrpc::JsonRpcException, isInvalidBlockError); +BOOST_FIXTURE_TEST_CASE(testblockvalidity, BtcClientFixture) { + const int expectedCode = -32603; + + auto isInvalidBlockError = [](const jsonrpc::JsonRpcException& e) -> bool { + if (e.GetCode() != expectedCode) { + BOOST_LOG_TRIVIAL(error) << "Wrong code in exception: " + std::to_string(e.GetCode()) + " instead of " + + std::to_string(expectedCode); + return false; + } + + if (e.GetMessage().find("Block decode failed") == std::string::npos) { + BOOST_LOG_TRIVIAL(error) << "Wrong message in exception: " + e.GetMessage(); + return false; + } + + BOOST_LOG_TRIVIAL(debug) << "OK: received a 'Block decode failed' error"; + return true; + }; // isInvalidBlockError() + + BOOST_LOG_TRIVIAL(info) << "Test validity of an invalid block"; + BOOST_CHECK_EXCEPTION(bitcoind0.testblockvalidity("INVALID BLOCK"), jsonrpc::JsonRpcException, + isInvalidBlockError); + BOOST_CHECK_EXCEPTION(bitcoind0.testblockvalidity("INVALID BLOCK", true), jsonrpc::JsonRpcException, + isInvalidBlockError); + BOOST_CHECK_EXCEPTION(bitcoind0.testblockvalidity("INVALID BLOCK", false), jsonrpc::JsonRpcException, + isInvalidBlockError); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/test_utils.cpp b/src/test/test_utils.cpp index 15aa539..f7fc495 100644 --- a/src/test/test_utils.cpp +++ b/src/test/test_utils.cpp @@ -26,88 +26,146 @@ enum class SOME_ENUM { }; vector>> STRING_2_BYTEVECTOR = { - { "", {}, }, - { string("\x00", 1), { 0x00 }, }, - { string("\x01", 1), { 0x01 }, }, - { string("\x00\x01", 2), { 0x00, 0x01 }, }, - { string("\x01\x00", 2), { 0x01, 0x00 }, }, - { string("\xfe\xff", 2), { 0xfe, 0xff }, }, + { + "", + {}, + }, + { + string("\x00", 1), + {0x00}, + }, + { + string("\x01", 1), + {0x01}, + }, + { + string("\x00\x01", 2), + {0x00, 0x01}, + }, + { + string("\x01\x00", 2), + {0x01, 0x00}, + }, + { + string("\xfe\xff", 2), + {0xfe, 0xff}, + }, }; vector> STRING_2_HASH = { - { string(""), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", }, - { string("A"), "559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd", }, - { string("\x00", 1), "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", }, - { string("\x01", 1), "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a", }, - { string("\x00\x00", 2), "96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7", }, - { string("hello"), "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", }, - { string("hello🥸"), "38251e8670dfad8e88f3a63881e1a0c1e91170648bb26cf8300b8f5f17f79953", }, - { string("🥸hello"), "c6ebe1d2ad358fd30e720170d95a7216cf54c5eaf141d6d3c9f9ee049d1aadf0", }, + { + string(""), + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + }, + { + string("A"), + "559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd", + }, + { + string("\x00", 1), + "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", + }, + { + string("\x01", 1), + "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a", + }, + { + string("\x00\x00", 2), + "96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7", + }, + { + string("hello"), + "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", + }, + { + string("hello🥸"), + "38251e8670dfad8e88f3a63881e1a0c1e91170648bb26cf8300b8f5f17f79953", + }, + { + string("🥸hello"), + "c6ebe1d2ad358fd30e720170d95a7216cf54c5eaf141d6d3c9f9ee049d1aadf0", + }, }; BOOST_AUTO_TEST_SUITE(test_utils, *enabled()) -BOOST_DATA_TEST_CASE( - test_stringToHex, - bdata::make(vector>{ - { "", "", }, - { "A", "41", }, - { "utf-8 đ熃🥸", "7574662d3820c491e78683f09fa5b8", }, - { string("\x00", 1), "00", }, - { string("\x01", 1), "01", }, - { string("\x00\x01", 2), "0001", }, - { string("\x01\x00", 2), "0100", }, - { string("\x01\x00\x01", 3), "010001", }, - { string("\x00\x01\x00", 3), "000100", }, - { string("\x01\x02\x03", 3), "010203", }, - }), - inputString, - expectedHex -) { +BOOST_DATA_TEST_CASE(test_stringToHex, + bdata::make(vector>{ + { + "", + "", + }, + { + "A", + "41", + }, + { + "utf-8 đ熃🥸", + "7574662d3820c491e78683f09fa5b8", + }, + { + string("\x00", 1), + "00", + }, + { + string("\x01", 1), + "01", + }, + { + string("\x00\x01", 2), + "0001", + }, + { + string("\x01\x00", 2), + "0100", + }, + { + string("\x01\x00\x01", 3), + "010001", + }, + { + string("\x00\x01\x00", 3), + "000100", + }, + { + string("\x01\x02\x03", 3), + "010203", + }, + }), + inputString, expectedHex) { using itcoin::utils::stringToHex; BOOST_TEST(stringToHex(inputString) == expectedHex); } // test_stringToHex -BOOST_DATA_TEST_CASE( - test_string2byteVector, - bdata::make(STRING_2_BYTEVECTOR), - inputString, - expectedByteVector -) { +BOOST_DATA_TEST_CASE(test_string2byteVector, bdata::make(STRING_2_BYTEVECTOR), inputString, + expectedByteVector) { using itcoin::utils::string2byteVector; BOOST_TEST(string2byteVector(inputString) == expectedByteVector); } // test_string2byteVector -BOOST_DATA_TEST_CASE( - test_byteVector2string, - bdata::make(STRING_2_BYTEVECTOR), - expectedString, - inputByteVector -) { +BOOST_DATA_TEST_CASE(test_byteVector2string, bdata::make(STRING_2_BYTEVECTOR), expectedString, + inputByteVector) { using itcoin::utils::byteVector2string; BOOST_TEST(byteVector2string(inputByteVector) == expectedString); } // test_byteVector2string -BOOST_DATA_TEST_CASE( - test_string2byteVector_round_trip, - bdata::make({ - string("🥸hello"), // emoticon - string("\x00\x00\x00", 3), // manyNulls - string("\x00\xfe\xff", 3), // nonNullTerminated - }), - binBuffer -) { +BOOST_DATA_TEST_CASE(test_string2byteVector_round_trip, + bdata::make({ + string("🥸hello"), // emoticon + string("\x00\x00\x00", 3), // manyNulls + string("\x00\xfe\xff", 3), // nonNullTerminated + }), + binBuffer) { using itcoin::utils::byteVector2string; using itcoin::utils::string2byteVector; BOOST_TEST(byteVector2string(string2byteVector(binBuffer)) == binBuffer); } // test_string2byteVector_round_trip -BOOST_AUTO_TEST_CASE(test_enumToUnderlying) -{ +BOOST_AUTO_TEST_CASE(test_enumToUnderlying) { using itcoin::utils::enumToUnderlying; BOOST_TEST(enumToUnderlying(SOME_ENUM::ZERO) == 0); @@ -116,8 +174,7 @@ BOOST_AUTO_TEST_CASE(test_enumToUnderlying) BOOST_TEST(enumToUnderlying(SOME_ENUM::LAST) == 99); } // test_enumToUnderlying -BOOST_AUTO_TEST_CASE(test_enumValueToString) -{ +BOOST_AUTO_TEST_CASE(test_enumValueToString) { using itcoin::utils::enumValueToString; BOOST_TEST(enumValueToString(SOME_ENUM::ZERO) == "0"); @@ -126,121 +183,200 @@ BOOST_AUTO_TEST_CASE(test_enumValueToString) BOOST_TEST(enumValueToString(SOME_ENUM::LAST) == "99"); } // test_enumValueToString -BOOST_DATA_TEST_CASE( - test_join, - bdata::make(vector, string, string>>{ - { { "", }, "", "", }, - { { "", }, ",", "", }, - { { "a", }, ",", "a", }, - { { "", "a", }, ",", ",a", }, - { { "a", "b", }, ",", "a,b", }, - { { "a", "", "c", }, ",", "a,,c", }, - { { "a", "b", "c", }, ",", "a,b,c", }, - { { "a", "b", }, "-SEP-", "a-SEP-b", }, - { { "a", }, "", "a", }, - { { "a", "", }, "", "a", }, - { { "a", "b", }, "", "ab", }, - }), - v, - separator, - joined -) { +BOOST_DATA_TEST_CASE(test_join, + bdata::make(vector, string, string>>{ + { + { + "", + }, + "", + "", + }, + { + { + "", + }, + ",", + "", + }, + { + { + "a", + }, + ",", + "a", + }, + { + { + "", + "a", + }, + ",", + ",a", + }, + { + { + "a", + "b", + }, + ",", + "a,b", + }, + { + { + "a", + "", + "c", + }, + ",", + "a,,c", + }, + { + { + "a", + "b", + "c", + }, + ",", + "a,b,c", + }, + { + { + "a", + "b", + }, + "-SEP-", + "a-SEP-b", + }, + { + { + "a", + }, + "", + "a", + }, + { + { + "a", + "", + }, + "", + "a", + }, + { + { + "a", + "b", + }, + "", + "ab", + }, + }), + v, separator, joined) { using itcoin::utils::join; BOOST_TEST(join(v, separator) == joined); } // test_join -BOOST_DATA_TEST_CASE( - test_stoui_positive_base16, - // uIntAsString, base, expectedUInt - bdata::make(vector>{ - {"0x0", 16, 0, }, - {"0x01", 16, 1, }, - {"0x010", 16, 16, }, - {"0xffffffff", 16, std::numeric_limits::max(), }, - {"0x0ffffffff", 16, std::numeric_limits::max(), }, - }), - uIntAsString, - base, - expectedUInt -) { +BOOST_DATA_TEST_CASE(test_stoui_positive_base16, + // uIntAsString, base, expectedUInt + bdata::make(vector>{ + { + "0x0", + 16, + 0, + }, + { + "0x01", + 16, + 1, + }, + { + "0x010", + 16, + 16, + }, + { + "0xffffffff", + 16, + std::numeric_limits::max(), + }, + { + "0x0ffffffff", + 16, + std::numeric_limits::max(), + }, + }), + uIntAsString, base, expectedUInt) { using itcoin::utils::stoui; BOOST_TEST(stoui(uIntAsString, nullptr, base) == expectedUInt); } // test_stoui_positive_base16 -BOOST_DATA_TEST_CASE( - test_stoui_negative_base16, - bdata::make(vector>{ - {"0x100000000", 16, }, - {"0xffffffff1", 16, }, - }), - uIntAsString, - base -) { +BOOST_DATA_TEST_CASE(test_stoui_negative_base16, + bdata::make(vector>{ + { + "0x100000000", + 16, + }, + { + "0xffffffff1", + 16, + }, + }), + uIntAsString, base) { using itcoin::utils::stoui; BOOST_CHECK_THROW(stoui(uIntAsString, nullptr, base), std::out_of_range); } // test_stoui_negative_base16 -BOOST_DATA_TEST_CASE( - test_checkHex_positive, - bdata::make({ - "0123456789abcdef", - "0123456789ABCDEF", - "FEDCDBA9876543210", - "AbCdEf", - "0", - "00", - "1", - "01", - "000000000000", - "000000100000", - }), - hexStr -) { +BOOST_DATA_TEST_CASE(test_checkHex_positive, + bdata::make({ + "0123456789abcdef", + "0123456789ABCDEF", + "FEDCDBA9876543210", + "AbCdEf", + "0", + "00", + "1", + "01", + "000000000000", + "000000100000", + }), + hexStr) { using namespace itcoin::utils; BOOST_TEST(checkHex(hexStr) == hexStr, "hex str not valid"); } // test_checkHex_positive -BOOST_DATA_TEST_CASE( - test_checkHex_negative, - bdata::make({ - "0x123456789abcdefg", - "123456789abcdefg", - "AbCdEfG", - "0x", - "0x 1", - "0x00000000000z", - }), - hexStr -) { +BOOST_DATA_TEST_CASE(test_checkHex_negative, + bdata::make({ + "0x123456789abcdefg", + "123456789abcdefg", + "AbCdEfG", + "0x", + "0x 1", + "0x00000000000z", + }), + hexStr) { using namespace itcoin::utils; BOOST_CHECK_THROW(checkHex(hexStr), std::invalid_argument); } // test_checkHex_negative -BOOST_DATA_TEST_CASE( - test_checkHash_positive, - bdata::make({ - "00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000ABCDEF", - }), - hexStr -) { +BOOST_DATA_TEST_CASE(test_checkHash_positive, + bdata::make({ + "00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6", + "0000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000ABCDEF", + }), + hexStr) { using namespace itcoin::utils; BOOST_TEST(checkHash(hexStr) == hexStr, "hex str not valid"); } // test_checkHash_positive -BOOST_DATA_TEST_CASE( - test_checkHash_negative, - bdata::make({ - "g0000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6", - "00000000000000000000000000000000000000000000000000000000000000001", - "000000000000000000000000000000000000000000000000000000000000000", - "", - "0" - }), - hexStr -) { +BOOST_DATA_TEST_CASE(test_checkHash_negative, + bdata::make({"g0000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6", + "00000000000000000000000000000000000000000000000000000000000000001", + "000000000000000000000000000000000000000000000000000000000000000", "", + "0"}), + hexStr) { using namespace itcoin::utils; BOOST_CHECK_THROW(checkHash(hexStr), std::invalid_argument); } // test_checkHash_negative diff --git a/src/transport/NetworkListener.cpp b/src/transport/NetworkListener.cpp index 7a616e4..692e402 100644 --- a/src/transport/NetworkListener.cpp +++ b/src/transport/NetworkListener.cpp @@ -6,9 +6,7 @@ namespace itcoin { namespace network { -NetworkListener::NetworkListener() -{ -} +NetworkListener::NetworkListener() {} -} -} +} // namespace network +} // namespace itcoin diff --git a/src/transport/NetworkTransport.cpp b/src/transport/NetworkTransport.cpp index fa042b2..3053d80 100644 --- a/src/transport/NetworkTransport.cpp +++ b/src/transport/NetworkTransport.cpp @@ -6,10 +6,7 @@ namespace itcoin { namespace network { -NetworkTransport::NetworkTransport(const itcoin::FbftConfig& conf): -m_conf(conf) -{ -} +NetworkTransport::NetworkTransport(const itcoin::FbftConfig& conf) : m_conf(conf) {} -} -} +} // namespace network +} // namespace itcoin diff --git a/src/transport/btcclient.cpp b/src/transport/btcclient.cpp index 62b11ab..f883d5d 100644 --- a/src/transport/btcclient.cpp +++ b/src/transport/btcclient.cpp @@ -6,97 +6,84 @@ namespace itcoin { namespace transport { -BtcClient::BtcClient(const std::string itcoinJsonRpcUri): - httpClient(itcoinJsonRpcUri), - bitcoind(httpClient, jsonrpc::JSONRPC_CLIENT_V1) -{ +BtcClient::BtcClient(const std::string itcoinJsonRpcUri) + : httpClient(itcoinJsonRpcUri), bitcoind(httpClient, jsonrpc::JSONRPC_CLIENT_V1) { } // BtcClient::BtcClient() -std::string BtcClient::sendtoaddress(const std::string& address, int amount) -{ +std::string BtcClient::sendtoaddress(const std::string& address, int amount) { std::scoped_lock lock(this->mtx); - return this->bitcoind.sendtoaddress(address, amount, "comment", "comment_to", false, true, "null", "unset", false, 25); + return this->bitcoind.sendtoaddress(address, amount, "comment", "comment_to", false, true, "null", "unset", + false, 25); } -std::string BtcClient::signmessage(const std::string& address, const std::string& message) -{ +std::string BtcClient::signmessage(const std::string& address, const std::string& message) { std::scoped_lock lock(this->mtx); return this->bitcoind.signmessage(address, message); } // BtcClient::signmessage() -bool BtcClient::verifymessage(const std::string& address, const std::string& signature, const std::string& message) -{ +bool BtcClient::verifymessage(const std::string& address, const std::string& signature, + const std::string& message) { std::scoped_lock lock(this->mtx); return this->bitcoind.verifymessage(address, signature, message); } // BtcClient::verifymessage() -Json::Value BtcClient::getblockchaininfo() -{ +Json::Value BtcClient::getblockchaininfo() { std::scoped_lock lock(this->mtx); return this->bitcoind.getblockchaininfo(); } // BtcClient::getblockchaininfo() -Json::Value BtcClient::getaddressinfo(const std::string& address) -{ +Json::Value BtcClient::getaddressinfo(const std::string& address) { std::scoped_lock lock(this->mtx); return this->bitcoind.getaddressinfo(address); } // BtcClient::getaddressinfo() -Json::Value BtcClient::getblocktemplate(const Json::Value& templateRequest) -{ +Json::Value BtcClient::getblocktemplate(const Json::Value& templateRequest) { std::scoped_lock lock(this->mtx); return this->bitcoind.getblocktemplate(templateRequest); } // BtcClient::getblocktemplate() -Json::Value BtcClient::submitblock(const std::string &hexData) -{ +Json::Value BtcClient::submitblock(const std::string& hexData) { std::scoped_lock lock(this->mtx); return this->bitcoind.submitblock(hexData); } // BtcClient::getblocktemplate() -Json::Value BtcClient::testblockvalidity(const std::string &hexData, bool check_signet_solution) -{ +Json::Value BtcClient::testblockvalidity(const std::string& hexData, bool check_signet_solution) { std::scoped_lock lock(this->mtx); return this->bitcoind.testblockvalidity(hexData, check_signet_solution); } // BtcClient::testblockvalidity() -Json::Value BtcClient::walletprocesspsbt(const std::string& psbt) -{ +Json::Value BtcClient::walletprocesspsbt(const std::string& psbt) { std::scoped_lock lock(this->mtx); return this->bitcoind.walletprocesspsbt(psbt, true, "ALL"); } // BtcClient::walletprocesspsbt() -std::string BtcClient::combinepsbt(const Json::Value& psbts) -{ +std::string BtcClient::combinepsbt(const Json::Value& psbts) { std::scoped_lock lock(this->mtx); return this->bitcoind.combinepsbt(psbts); } // BtcClient::combinepsbt() -Json::Value BtcClient::finalizepsbt(const std::string& psbt, bool extract) -{ +Json::Value BtcClient::finalizepsbt(const std::string& psbt, bool extract) { std::scoped_lock lock(this->mtx); return this->bitcoind.finalizepsbt(psbt, extract); } // BtcClient::finalizepsbt() -Json::Value BtcClient::analyzepsbt(const std::string& psbt) -{ +Json::Value BtcClient::analyzepsbt(const std::string& psbt) { std::scoped_lock lock(this->mtx); return this->bitcoind.analyzepsbt(psbt); } // BtcClient::analyzepsbt() -std::string BtcClient::dumpprivkey(const std::string& address) -{ +std::string BtcClient::dumpprivkey(const std::string& address) { std::scoped_lock lock(this->mtx); return this->bitcoind.dumpprivkey(address); diff --git a/src/transport/btcclient.h b/src/transport/btcclient.h index 1e004fd..4fa2e05 100644 --- a/src/transport/btcclient.h +++ b/src/transport/btcclient.h @@ -21,42 +21,43 @@ namespace transport { * that serializes calls via the embedded mtx mutex. */ class BtcClient { - public: - BtcClient(const std::string itcoinJsonRpcUri); +public: + BtcClient(const std::string itcoinJsonRpcUri); - std::string sendtoaddress(const std::string& address, int amount); - std::string signmessage(const std::string& address, const std::string& message); - bool verifymessage(const std::string& address, const std::string& signature, const std::string& message); - Json::Value getblockchaininfo(); - Json::Value getaddressinfo(const std::string& address); - Json::Value getblocktemplate(const Json::Value& templateRequest); - Json::Value submitblock(const std::string& hexData); - Json::Value testblockvalidity(const std::string& hexData, bool check_signet_solution = true); - Json::Value walletprocesspsbt(const std::string& psbt); - std::string combinepsbt(const Json::Value& psbts); - Json::Value finalizepsbt(const std::string& psbt, bool extract); - Json::Value analyzepsbt(const std::string& psbt); - std::string dumpprivkey(const std::string& address); + std::string sendtoaddress(const std::string& address, int amount); + std::string signmessage(const std::string& address, const std::string& message); + bool verifymessage(const std::string& address, const std::string& signature, const std::string& message); + Json::Value getblockchaininfo(); + Json::Value getaddressinfo(const std::string& address); + Json::Value getblocktemplate(const Json::Value& templateRequest); + Json::Value submitblock(const std::string& hexData); + Json::Value testblockvalidity(const std::string& hexData, bool check_signet_solution = true); + Json::Value walletprocesspsbt(const std::string& psbt); + std::string combinepsbt(const Json::Value& psbts); + Json::Value finalizepsbt(const std::string& psbt, bool extract); + Json::Value analyzepsbt(const std::string& psbt); + std::string dumpprivkey(const std::string& address); - private: - std::mutex mtx; +private: + std::mutex mtx; - /* - * ACHTUNG: - * BitcoinClientStub sends the json-rpc auth credentials for each call. - * They might also be dumped on the screen from time to time. - * - * This is a potential security risk. - * - * EXAMPLE: - * [2021-Aug-09 15:58:10.295206] [0x0000d816 0x00007f4d5dec0a40] [...] - * terminate called after throwing an instance of 'jsonrpc::JsonRpcException' - * what(): Exception -32003 : Client connector error: libcurl error: 7 -> Could not connect to http://user:2KVNeKYRVrOo3xLMnr4oBkzWuNFEqcCrRHcBF1hQy9w=@127.0.0.1:38232 - * - * TODO: find a better way of securing the bitcoin-rpc credentials. - */ - jsonrpc::HttpClient httpClient; - BitcoinClientStub bitcoind; + /* + * ACHTUNG: + * BitcoinClientStub sends the json-rpc auth credentials for each call. + * They might also be dumped on the screen from time to time. + * + * This is a potential security risk. + * + * EXAMPLE: + * [2021-Aug-09 15:58:10.295206] [0x0000d816 0x00007f4d5dec0a40] [...] + * terminate called after throwing an instance of 'jsonrpc::JsonRpcException' + * what(): Exception -32003 : Client connector error: libcurl error: 7 -> Could not connect to + * http://user:2KVNeKYRVrOo3xLMnr4oBkzWuNFEqcCrRHcBF1hQy9w=@127.0.0.1:38232 + * + * TODO: find a better way of securing the bitcoin-rpc credentials. + */ + jsonrpc::HttpClient httpClient; + BitcoinClientStub bitcoind; }; // class Bitcoind } // namespace transport diff --git a/src/transport/network.h b/src/transport/network.h index 044bc23..16c7059 100644 --- a/src/transport/network.h +++ b/src/transport/network.h @@ -7,32 +7,30 @@ #include "../fbft/messages/messages.h" namespace itcoin { - class FbftConfig; +class FbftConfig; } namespace messages = itcoin::fbft::messages; namespace itcoin { namespace network { -class NetworkListener -{ - public: - NetworkListener(); - virtual const uint32_t id() const = 0; - virtual void ReceiveIncomingMessage(std::unique_ptr msg) = 0; +class NetworkListener { +public: + NetworkListener(); + virtual const uint32_t id() const = 0; + virtual void ReceiveIncomingMessage(std::unique_ptr msg) = 0; }; -class NetworkTransport -{ - public: - NetworkTransport(const itcoin::FbftConfig& conf); - virtual void BroadcastMessage(std::unique_ptr p_msg) = 0; +class NetworkTransport { +public: + NetworkTransport(const itcoin::FbftConfig& conf); + virtual void BroadcastMessage(std::unique_ptr p_msg) = 0; - protected: - const itcoin::FbftConfig& m_conf; +protected: + const itcoin::FbftConfig& m_conf; }; -} -} +} // namespace network +} // namespace itcoin #endif // ITCOIN_NETWORK_NETWORK_H \ No newline at end of file diff --git a/src/transport/zcomm.cpp b/src/transport/zcomm.cpp index 2a34584..5773385 100644 --- a/src/transport/zcomm.cpp +++ b/src/transport/zcomm.cpp @@ -5,14 +5,14 @@ #include +#include #include #include -#include #include "../fbft/messages/messages.h" -namespace{ - static volatile std::sig_atomic_t s_interrupted = 0; +namespace { +static volatile std::sig_atomic_t s_interrupted = 0; } void signal_handler(int signal_value) { @@ -31,14 +31,12 @@ void signal_handler(int signal_value) { namespace boost { namespace endian { -inline boost::uint32_t load_little_u32( unsigned char const * p ) BOOST_NOEXCEPT -{ - return boost::endian::endian_load( p ); +inline boost::uint32_t load_little_u32(unsigned char const* p) BOOST_NOEXCEPT { + return boost::endian::endian_load(p); } -inline boost::int32_t load_little_s32( unsigned char const * p ) BOOST_NOEXCEPT -{ - return boost::endian::endian_load( p ); +inline boost::int32_t load_little_s32(unsigned char const* p) BOOST_NOEXCEPT { + return boost::endian::endian_load(p); } } // namespace endian @@ -52,33 +50,34 @@ namespace transport { * Slight modification from: * https://stackoverflow.com/questions/3381614/c-convert-string-to-hexadecimal-and-vice-versa/16125797#16125797 */ -std::string stringToHex(const std::string &in) { - std::stringstream ss; +std::string stringToHex(const std::string& in) { + std::stringstream ss; - ss << std::hex << std::setfill('0'); - for (char i: in) { - ss << std::setw(2) << static_cast(static_cast(i)); - } + ss << std::hex << std::setfill('0'); + for (char i : in) { + ss << std::setw(2) << static_cast(static_cast(i)); + } - return ss.str(); + return ss.str(); } // stringToHex() // From Little Endian hex string to integer uint32_t bytesToInt(void* data, size_t size) { - assert(size == 4); - uint32_t result; - std::memcpy(&result, data, size); - return result; + assert(size == 4); + uint32_t result; + std::memcpy(&result, data, size); + return result; } -std::optional> decode_itcoinblock_payload(const std::string& bin_buffer) -{ +std::optional> +decode_itcoinblock_payload(const std::string& bin_buffer) { if (bin_buffer.size() != ZComm::ITCOINBLOCK_MSG_SIZE) { - BOOST_LOG_TRIVIAL(error) << "The message payload must be exactly " << ZComm::ITCOINBLOCK_MSG_SIZE << " bytes. This one is " << bin_buffer.size() << " bytes"; + BOOST_LOG_TRIVIAL(error) << "The message payload must be exactly " << ZComm::ITCOINBLOCK_MSG_SIZE + << " bytes. This one is " << bin_buffer.size() << " bytes"; return std::nullopt; } - const std::string hash_bin_buffer{(const char *)bin_buffer.data(), 32}; + const std::string hash_bin_buffer{(const char*)bin_buffer.data(), 32}; // TODO: hash_bin_buffer è in little endian: controllare se lo sto decodificando bene const std::string hash_hex_string = stringToHex(hash_bin_buffer); @@ -89,18 +88,16 @@ std::optional> decode_itcoinblock_pay return {{hash_hex_string, block_height, block_time}}; } // decode_itcoinblock_payload() -ZComm::ZComm(const itcoin::FbftConfig& conf): - NetworkTransport{conf}, - ctx{std::make_unique()}, - my_group{std::string{"replica" + std::to_string(conf.id())}}, - itcoinblock_topic_name{"itcoinblock"} -{ +ZComm::ZComm(const itcoin::FbftConfig& conf) + : NetworkTransport{conf}, ctx{std::make_unique()}, + my_group{std::string{"replica" + std::to_string(conf.id())}}, itcoinblock_topic_name{"itcoinblock"} { // setup dish (rx) this->dish_socket = std::make_unique(*(this->ctx), zmq::socket_type::dish); // build dish_bind_string std::string dish_bind_string = "tcp://*:" + m_conf.replica_set_v()[m_conf.id()].port(); - BOOST_LOG_TRIVIAL(info) << "Binding dish (for receiving broadcast messages from other replicas) to: " << dish_bind_string; + BOOST_LOG_TRIVIAL(info) << "Binding dish (for receiving broadcast messages from other replicas) to: " + << dish_bind_string; this->dish_socket->bind(dish_bind_string); /* @@ -131,19 +128,20 @@ ZComm::ZComm(const itcoin::FbftConfig& conf): if (m_conf.sniffer_dish_connection_string().has_value()) { std::string sniffer_dish_connection_string{m_conf.sniffer_dish_connection_string().value()}; - BOOST_LOG_TRIVIAL(warning) << "Outgoing messages will also be sent to: " << sniffer_dish_connection_string; + BOOST_LOG_TRIVIAL(warning) << "Outgoing messages will also be sent to: " + << sniffer_dish_connection_string; this->radio_socket->connect(sniffer_dish_connection_string.c_str()); } // setup rawblock (block notifications from itcoin-core) this->itcoin_sub_socket = std::make_unique(*(this->ctx), zmq::socket_type::sub); - BOOST_LOG_TRIVIAL(info) << "itcoinblock: subscribing topic " << this->itcoinblock_topic_name << " on " << conf.getItcoinblockConnectionString(); + BOOST_LOG_TRIVIAL(info) << "itcoinblock: subscribing topic " << this->itcoinblock_topic_name << " on " + << conf.getItcoinblockConnectionString(); this->itcoin_sub_socket->connect(conf.getItcoinblockConnectionString()); this->itcoin_sub_socket->set(zmq::sockopt::subscribe, this->itcoinblock_topic_name); } // ZComm::ZComm() -void ZComm::handler_dish(zmq::event_flags e) -{ +void ZComm::handler_dish(zmq::event_flags e) { if ((e & zmq::event_flags::pollin) != zmq::event_flags::none) { // event_flags::pollin bit is set in e zmq::message_t msg; @@ -160,8 +158,7 @@ void ZComm::handler_dish(zmq::event_flags e) } } // ZComm::handler_dish() -void ZComm::handler_itcoin_block(zmq::event_flags e) -{ +void ZComm::handler_itcoin_block(zmq::event_flags e) { if ((e & zmq::event_flags::pollin) != zmq::event_flags::none) { // event_flags::pollin bit is set in e std::vector recv_msgs; @@ -175,18 +172,21 @@ void ZComm::handler_itcoin_block(zmq::event_flags e) return; } if (res.value() != 3) { - BOOST_LOG_TRIVIAL(error) << "Ricevuto messaggio composto di " << res.value() << " parti. Deve essere di 3"; + BOOST_LOG_TRIVIAL(error) << "Ricevuto messaggio composto di " << res.value() + << " parti. Deve essere di 3"; return; } if (res.value() != recv_msgs.size()) { - BOOST_LOG_TRIVIAL(error) << "Res.value vale " << res.value() << ", mentre recv_msgs ha " << recv_msgs.size() << " elementi. Inaccettabile."; + BOOST_LOG_TRIVIAL(error) << "Res.value vale " << res.value() << ", mentre recv_msgs ha " + << recv_msgs.size() << " elementi. Inaccettabile."; return; } // part 1: topic name const std::string topic_name = recv_msgs[0].to_string(); if (topic_name != this->itcoinblock_topic_name) { - BOOST_LOG_TRIVIAL(error) << "Ricevuto nome topic inatteso: " << topic_name << " anziché " << this->itcoinblock_topic_name; + BOOST_LOG_TRIVIAL(error) << "Ricevuto nome topic inatteso: " << topic_name << " anziché " + << this->itcoinblock_topic_name; return; } @@ -201,15 +201,16 @@ void ZComm::handler_itcoin_block(zmq::event_flags e) uint32_t seqNumber = bytesToInt(recv_msgs[2].data(), recv_msgs[2].size()); // emit the rawblock_received() signal - BOOST_LOG_TRIVIAL(trace) << "new block received. Hash: " << hash_hex_string << ", height: " << block_height << ", time: " << block_time << ", seqnum: " << seqNumber; + BOOST_LOG_TRIVIAL(trace) << "new block received. Hash: " << hash_hex_string + << ", height: " << block_height << ", time: " << block_time + << ", seqnum: " << seqNumber; this->itcoinblock_received(hash_hex_string, block_height, block_time, seqNumber); } else if (zmq::event_flags::none != (e & ~zmq::event_flags::pollout)) { throw std::runtime_error("Unexpected event type " + std::to_string(static_cast(e))); } } // ZComm::handler_itcoin_block() -int ZComm::run_forever() -{ +int ZComm::run_forever() { /* * Setup custom signal handlers for SIGINT and SIGTERM. We will restore them * to their previous values if we ever exit this function. @@ -231,12 +232,10 @@ int ZComm::run_forever() zmq::active_poller_t poller; - poller.add(*(this->dish_socket), zmq::event_flags::pollin, [&](zmq::event_flags e) { - this->handler_dish(e); - }); - poller.add(*(this->itcoin_sub_socket), zmq::event_flags::pollin, [&](zmq::event_flags e) { - this->handler_itcoin_block(e); - }); + poller.add(*(this->dish_socket), zmq::event_flags::pollin, + [&](zmq::event_flags e) { this->handler_dish(e); }); + poller.add(*(this->itcoin_sub_socket), zmq::event_flags::pollin, + [&](zmq::event_flags e) { this->handler_itcoin_block(e); }); // TODO: m_conf.target_block_time() should be a std::duration already, not a double std::chrono::milliseconds target_block_time{int(this->m_conf.target_block_time() * 1000)}; @@ -249,22 +248,20 @@ int ZComm::run_forever() std::chrono::milliseconds time_margin = (target_block_time - elapsed); if (time_margin.count() < 1) { - BOOST_LOG_TRIVIAL(warning) << boost::format("ACHTUNG: the system is operating without any time margin. target_block_time: %1% ms, cycle elapsed time: %2% ms") - % target_block_time.count() - % elapsed.count(); + BOOST_LOG_TRIVIAL(warning) << boost::format( + "ACHTUNG: the system is operating without any time margin. " + "target_block_time: %1% ms, cycle elapsed time: %2% ms") % + target_block_time.count() % elapsed.count(); network_timeout = std::chrono::milliseconds{1}; } else { network_timeout = std::chrono::milliseconds{time_margin / 2}; } // TODO REMOVE ME: Added to make experiments deterministic - if (is_first_time) - { + if (is_first_time) { // the first time is better to have bigger timeout in order to trigger view changes network_timeout = std::chrono::milliseconds{10000}; is_first_time = false; - } - else - { + } else { // A determinist and small timeout network_timeout = std::chrono::milliseconds{5}; } @@ -276,7 +273,8 @@ int ZComm::run_forever() elapsed = std::chrono::duration_cast(after_wait - before_wait); - BOOST_LOG_TRIVIAL(trace) << "ELAPSED: " << elapsed.count() << " ms, EVENT COUNT: " << event_count << ", POLLING TIMEOUT WAS: " << network_timeout.count() << " ms"; + BOOST_LOG_TRIVIAL(trace) << "ELAPSED: " << elapsed.count() << " ms, EVENT COUNT: " << event_count + << ", POLLING TIMEOUT WAS: " << network_timeout.count() << " ms"; if (event_count > 0) { // at least an event happened on the network: start the cycle again @@ -287,16 +285,16 @@ int ZComm::run_forever() * Nothing happened on the network: emit the network_timeout_expired() * signal */ - std::chrono::steady_clock::time_point before_idle = std::chrono::steady_clock::now(); - this->network_timeout_expired(); - std::chrono::steady_clock::time_point after_idle = std::chrono::steady_clock::now(); - elapsed = std::chrono::duration_cast(after_idle - before_idle); - } catch (zmq::error_t &e) { - BOOST_LOG_TRIVIAL(info) << "Interrupt received: " << e.what(); + std::chrono::steady_clock::time_point before_idle = std::chrono::steady_clock::now(); + this->network_timeout_expired(); + std::chrono::steady_clock::time_point after_idle = std::chrono::steady_clock::now(); + elapsed = std::chrono::duration_cast(after_idle - before_idle); + } catch (zmq::error_t& e) { + BOOST_LOG_TRIVIAL(info) << "Interrupt received: " << e.what(); } if (s_interrupted) { - BOOST_LOG_TRIVIAL(info) << "interrupt received, exiting run_forever()"; - break; + BOOST_LOG_TRIVIAL(info) << "interrupt received, exiting run_forever()"; + break; } } // while (true) @@ -312,27 +310,23 @@ int ZComm::run_forever() return EXIT_SUCCESS; } // ZComm::run_forever() -void ZComm::BroadcastMessage(std::unique_ptr p_msg) -{ +void ZComm::BroadcastMessage(std::unique_ptr p_msg) { this->broadcast(p_msg->ToBinBuffer()); } // ZComm::BroadcastMessage() -void ZComm::broadcast(const std::string& bin_buffer) -{ +void ZComm::broadcast(const std::string& bin_buffer) { zmq::message_t msg(bin_buffer); msg.set_group(this->my_group.c_str()); BOOST_LOG_TRIVIAL(info) << "broadcasting " << bin_buffer.length() << " bytes on group " << msg.group(); zmq::send_result_t res = this->radio_socket->send(msg, zmq::send_flags::none); if (res.has_value() == false) { - BOOST_LOG_TRIVIAL(error) << "Error while trying to broadcast " << bin_buffer.length() << "bytes on group " << msg.group(); + BOOST_LOG_TRIVIAL(error) << "Error while trying to broadcast " << bin_buffer.length() << "bytes on group " + << msg.group(); } } // ZComm::broadcast() -ZComm::~ZComm() -{ -} // ZComm::~ZComm() - +ZComm::~ZComm() {} // ZComm::~ZComm() } // namespace transport } // namespace itcoin diff --git a/src/transport/zcomm.h b/src/transport/zcomm.h index 7fdd6a5..b742b3e 100644 --- a/src/transport/zcomm.h +++ b/src/transport/zcomm.h @@ -17,9 +17,9 @@ namespace itcoin { namespace fbft { namespace messages { - class Message; -} // namespace fbft; -} // namespace messages; +class Message; +} // namespace messages +} // namespace fbft namespace transport { @@ -41,109 +41,111 @@ using namespace std::chrono_literals; * * In case of decoding errors, prints a log and returns std::nullopt. */ -std::optional> decode_itcoinblock_payload(const std::string& bin_buffer); +std::optional> +decode_itcoinblock_payload(const std::string& bin_buffer); class ZComm : public network::NetworkTransport { - public: - /** - * Configures a ZComm object, binds the dish socket and connects to the - * dishes of the other replicas and to the pub socket of the itcoin-core - * process local to this replica. - * - * The object will automatically take care of reconnections, - * retransmissions and discarding of new messages when the send queue is - * full. - * - * conf: - * A FbftConfig object - */ - ZComm(const itcoin::FbftConfig& conf); - - /** - * Broadcasts a message to all the replicas configured in - * connection_strings_towards_replicas (see constructor). - * - * If some replicas are offline, the messages will be delivered when they - * come back online. - * - * The messages will be sent on a group named "replicaX", where X is my_id. - */ - void broadcast(const std::string& bin_buffer); - - void BroadcastMessage(std::unique_ptr p_msg); - - /** - * Runs forever. Relevant events are published via the following - * boost.signals2 signals: - * - replica_message_received, if a message from a replica was received; - * - itcoinblock_received, if the itcoin-core process local to this miner - * has notified us of the appearance of a new block; - * - network_timeout_expired, if there was no network traffic for more than - * half the target_block_time. - * - * If SIGINT or SIGTERM are caught, returns EXIT_SUCCESS. - * - * If there are problems installing the unix signal handlers, writes an - * error log and immediately returns EXIT_FAILURE. - */ - int run_forever(); - - /** - * typedef for the signal emitted when receiving a message from a miner - * replica: (group_name, bin_buffer) - */ - typedef bs2::signal SigReplicaMessageReceived_t; - - /** - * typedef for the signal emitted when receiving a itcoinblock: (block hash - * as hex string, height, time, sequence_number) - */ - typedef bs2::signal SigItcoinBlockReceived_t; - - /** - * typedef for the signal emitted when no events have happened on the - * network for half the expected cycle time (target_block_time / 2) - */ - typedef bs2::signal SigNetworkTimeoutExpired_t; - - SigReplicaMessageReceived_t replica_message_received; - SigItcoinBlockReceived_t itcoinblock_received; - SigNetworkTimeoutExpired_t network_timeout_expired; - - /** - * Messages on the "itcoinblock" topic must be of a fixed size of 40 bits - * (see https://github.com/bancaditalia/itcoin-core/blob/itcoin/doc/zmq.md). - */ - static constexpr uint16_t ITCOINBLOCK_MSG_SIZE = 40; - - ~ZComm(); - - private: - bool is_first_time = true; // TODO REMOVE: the first time is better to have bigger timeout in order to trigger view changes - - const std::string my_group; - const std::string itcoinblock_topic_name; - - std::unique_ptr ctx; - - /** - * outgoing messages for the other replicas are sent through this zmq socket - */ - std::unique_ptr radio_socket; - - /** - * incoming messages from the other replicas are received here - */ - std::unique_ptr dish_socket; - - /** - * new block notifications from the itcoin-core process local to this - * replica are received on this zmq sub socket - */ - std::unique_ptr itcoin_sub_socket; - - void handler_dish(zmq::event_flags e); - void handler_itcoin_block(zmq::event_flags e); +public: + /** + * Configures a ZComm object, binds the dish socket and connects to the + * dishes of the other replicas and to the pub socket of the itcoin-core + * process local to this replica. + * + * The object will automatically take care of reconnections, + * retransmissions and discarding of new messages when the send queue is + * full. + * + * conf: + * A FbftConfig object + */ + ZComm(const itcoin::FbftConfig& conf); + + /** + * Broadcasts a message to all the replicas configured in + * connection_strings_towards_replicas (see constructor). + * + * If some replicas are offline, the messages will be delivered when they + * come back online. + * + * The messages will be sent on a group named "replicaX", where X is my_id. + */ + void broadcast(const std::string& bin_buffer); + + void BroadcastMessage(std::unique_ptr p_msg); + + /** + * Runs forever. Relevant events are published via the following + * boost.signals2 signals: + * - replica_message_received, if a message from a replica was received; + * - itcoinblock_received, if the itcoin-core process local to this miner + * has notified us of the appearance of a new block; + * - network_timeout_expired, if there was no network traffic for more than + * half the target_block_time. + * + * If SIGINT or SIGTERM are caught, returns EXIT_SUCCESS. + * + * If there are problems installing the unix signal handlers, writes an + * error log and immediately returns EXIT_FAILURE. + */ + int run_forever(); + + /** + * typedef for the signal emitted when receiving a message from a miner + * replica: (group_name, bin_buffer) + */ + typedef bs2::signal SigReplicaMessageReceived_t; + + /** + * typedef for the signal emitted when receiving a itcoinblock: (block hash + * as hex string, height, time, sequence_number) + */ + typedef bs2::signal SigItcoinBlockReceived_t; + + /** + * typedef for the signal emitted when no events have happened on the + * network for half the expected cycle time (target_block_time / 2) + */ + typedef bs2::signal SigNetworkTimeoutExpired_t; + + SigReplicaMessageReceived_t replica_message_received; + SigItcoinBlockReceived_t itcoinblock_received; + SigNetworkTimeoutExpired_t network_timeout_expired; + + /** + * Messages on the "itcoinblock" topic must be of a fixed size of 40 bits + * (see https://github.com/bancaditalia/itcoin-core/blob/itcoin/doc/zmq.md). + */ + static constexpr uint16_t ITCOINBLOCK_MSG_SIZE = 40; + + ~ZComm(); + +private: + bool is_first_time = + true; // TODO REMOVE: the first time is better to have bigger timeout in order to trigger view changes + + const std::string my_group; + const std::string itcoinblock_topic_name; + + std::unique_ptr ctx; + + /** + * outgoing messages for the other replicas are sent through this zmq socket + */ + std::unique_ptr radio_socket; + + /** + * incoming messages from the other replicas are received here + */ + std::unique_ptr dish_socket; + + /** + * new block notifications from the itcoin-core process local to this + * replica are received on this zmq sub socket + */ + std::unique_ptr itcoin_sub_socket; + + void handler_dish(zmq::event_flags e); + void handler_itcoin_block(zmq::event_flags e); }; // class ZComm } // namespace transport diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index 1f7c6b8..813e079 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -7,49 +7,46 @@ #include #include -#include +#include #include #include -#include -#include +#include #include +#include #include namespace itcoin { namespace utils { -void configure_boost_logging() -{ +void configure_boost_logging() { namespace bl = boost::log; bl::add_common_attributes(); - bl::core::get()->set_filter - ( - bl::trivial::severity >= bl::trivial::debug - ); - - bl::add_console_log ( - std::clog, - bl::keywords::format = ( - bl::expressions::stream - << bl::expressions::attr(bl::aux::default_attribute_names::line_id()) - << " [" << bl::expressions::attr(bl::aux::default_attribute_names::timestamp()) << "]" - //<< " [" << bl::expressions::attr(bl::aux::default_attribute_names::process_id()) << "" - //<< " " << bl::expressions::attr(bl::aux::default_attribute_names::thread_id()) << "]" - << " [" << bl::trivial::severity << "]" - << " " << bl::expressions::smessage - ) - ); + bl::core::get()->set_filter(bl::trivial::severity >= bl::trivial::debug); + + bl::add_console_log( + std::clog, + bl::keywords::format = + (bl::expressions::stream + << bl::expressions::attr(bl::aux::default_attribute_names::line_id()) << " [" + << bl::expressions::attr(bl::aux::default_attribute_names::timestamp()) + << "]" + //<< " [" << + // bl::expressions::attr(bl::aux::default_attribute_names::process_id()) << + // "" + //<< " " << + // bl::expressions::attr(bl::aux::default_attribute_names::thread_id()) << "]" + << " [" << bl::trivial::severity << "]" + << " " << bl::expressions::smessage)); } /* * Slight modification from: * https://stackoverflow.com/questions/3381614/c-convert-string-to-hexadecimal-and-vice-versa/16125797#16125797 */ -std::string stringToHex(const std::string in) -{ +std::string stringToHex(const std::string in) { std::stringstream ss; ss << std::hex << std::setfill('0'); @@ -61,42 +58,39 @@ std::string stringToHex(const std::string in) } // stringToHex() std::string hexToString(const std::string in) { - std::string output; + std::string output; - if ((in.length() % 2) != 0) { - throw std::runtime_error("hexToString, input string is not valid length ..."); - } + if ((in.length() % 2) != 0) { + throw std::runtime_error("hexToString, input string is not valid length ..."); + } - size_t cnt = in.length() / 2; + size_t cnt = in.length() / 2; - for (size_t i = 0; cnt > i; ++i) { - uint32_t s = 0; - std::stringstream ss; - ss << std::hex << in.substr(i * 2, 2); - ss >> s; + for (size_t i = 0; cnt > i; ++i) { + uint32_t s = 0; + std::stringstream ss; + ss << std::hex << in.substr(i * 2, 2); + ss >> s; - output.push_back(static_cast(s)); - } + output.push_back(static_cast(s)); + } - return output; -} //hexToString + return output; +} // hexToString -std::vector string2byteVector(const std::string& s) -{ +std::vector string2byteVector(const std::string& s) { return std::vector{s.begin(), s.end()}; } // string2charVector() -std::string byteVector2string(const std::vector& charVector) -{ +std::string byteVector2string(const std::vector& charVector) { return std::string{charVector.begin(), charVector.end()}; } // charVector2string() -std::string join(const std::vector& sequence, const std::string& separator) -{ +std::string join(const std::vector& sequence, const std::string& separator) { std::string result; for (size_t i = 0; i < sequence.size(); i++) { - result += sequence[i] + ((i != sequence.size()-1) ? separator : ""); + result += sequence[i] + ((i != sequence.size() - 1) ? separator : ""); } return result; @@ -110,10 +104,10 @@ unsigned int stoui(const std::string& str, std::size_t* pos, int base) { throw std::out_of_range("stoui"); } - return (unsigned int) result; + return (unsigned int)result; } // stoui() -std::string checkHash(const std::string &hashStr) { +std::string checkHash(const std::string& hashStr) { // a hash string must be a hex string checkHex(hashStr); @@ -125,10 +119,10 @@ std::string checkHash(const std::string &hashStr) { return hashStr; } // checkHash() -std::string checkHex(const std::string &hashStr) { - bool allHexDigits = std::all_of(hashStr.begin(), hashStr.end(), [](char c) { return HexDigit(c) >= 0;}); +std::string checkHex(const std::string& hashStr) { + bool allHexDigits = std::all_of(hashStr.begin(), hashStr.end(), [](char c) { return HexDigit(c) >= 0; }); - if (hashStr.size() > 0 && !allHexDigits){ + if (hashStr.size() > 0 && !allHexDigits) { throw std::invalid_argument("hex string not valid"); } diff --git a/src/utils/utils.h b/src/utils/utils.h index 5696ed8..53934fc 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -55,21 +55,18 @@ std::string byteVector2string(const std::vector& byteVector); * * C++23 will probably make this obsolete thanks to std::to_underlying(). * - * source: https://stackoverflow.com/questions/8357240/how-to-automatically-convert-strongly-typed-enum-into-int#33083231 + * source: + * https://stackoverflow.com/questions/8357240/how-to-automatically-convert-strongly-typed-enum-into-int#33083231 */ -template -constexpr auto enumToUnderlying(E e) noexcept -{ - return static_cast>(e); +template constexpr auto enumToUnderlying(E e) noexcept { + return static_cast>(e); } // enumToUnderlying() /** * Returns a string representation of value e of enum class type E. */ -template -constexpr auto enumValueToString(E e) noexcept -{ - return std::to_string(static_cast>(e)); +template constexpr auto enumValueToString(E e) noexcept { + return std::to_string(static_cast>(e)); } // enumValueToString() /** @@ -81,12 +78,12 @@ std::string join(const std::vector& sequence, const std::string& se unsigned int stoui(const std::string& str, std::size_t* pos = nullptr, int base = 10); -std::string checkHash(const std::string &hashStr); -std::string checkHex(const std::string &hexStr); - +std::string checkHash(const std::string& hashStr); +std::string checkHex(const std::string& hexStr); /** - * source: https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c/56766138#56766138 + * source: + * https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c/56766138#56766138 * * Returns a string_view of the type of the passed expression, computed at * compile time. @@ -110,8 +107,7 @@ std::string checkHex(const std::string &hexStr); * std::cout << type_name() << '\n'; // "const int&" * } */ -template -constexpr auto type_name() { +template constexpr auto type_name() { std::string_view name, prefix, suffix; #ifdef __clang__ name = __PRETTY_FUNCTION__; @@ -134,4 +130,4 @@ constexpr auto type_name() { } // namespace utils } // namespace itcoin -#endif //FBFT_UTILS_H_ +#endif // FBFT_UTILS_H_ diff --git a/src/wallet/BitcoinRpcWallet.cpp b/src/wallet/BitcoinRpcWallet.cpp index 3e2c4c0..913ea8b 100644 --- a/src/wallet/BitcoinRpcWallet.cpp +++ b/src/wallet/BitcoinRpcWallet.cpp @@ -6,10 +6,10 @@ #include #include -#include "config/FbftConfig.h" #include "../blockchain/extract.h" #include "../fbft/messages/messages.h" #include "../transport/btcclient.h" +#include "config/FbftConfig.h" using namespace std; using Message = itcoin::fbft::messages::Message; @@ -17,53 +17,35 @@ using Message = itcoin::fbft::messages::Message; namespace itcoin { namespace wallet { -BitcoinRpcWallet::BitcoinRpcWallet(const itcoin::FbftConfig& conf, transport::BtcClient& bitcoind): -Wallet(conf), m_bitcoind(bitcoind) -{ +BitcoinRpcWallet::BitcoinRpcWallet(const itcoin::FbftConfig& conf, transport::BtcClient& bitcoind) + : Wallet(conf), m_bitcoind(bitcoind) { m_pubkey_address = m_conf.replica_set_v().at(m_conf.id()).p2pkh(); - BOOST_LOG_TRIVIAL(debug) << str( - boost::format("R%1% BitcoinRpcWallet will sign using pubkey address %2%.") - % m_conf.id() - % m_pubkey_address - ); + BOOST_LOG_TRIVIAL(debug) << str(boost::format("R%1% BitcoinRpcWallet will sign using pubkey address %2%.") % + m_conf.id() % m_pubkey_address); } -void BitcoinRpcWallet::AppendSignature(Message& message) const -{ - if(message.sender_id() != m_conf.id()) - { - string error_msg = str( - boost::format("R%1% BitcoinRpcWallet cannot sign message with sender_id = %2%.") - % m_conf.id() - % message.sender_id() - ); +void BitcoinRpcWallet::AppendSignature(Message& message) const { + if (message.sender_id() != m_conf.id()) { + string error_msg = str(boost::format("R%1% BitcoinRpcWallet cannot sign message with sender_id = %2%.") % + m_conf.id() % message.sender_id()); throw runtime_error(error_msg); } string msg_digest = message.digest(); string sig = m_bitcoind.signmessage(m_pubkey_address, msg_digest); - BOOST_LOG_TRIVIAL(trace) << str( - boost::format("R%1% BitcoinRpcWallet signing message with digest = %2%.") - % m_conf.id() - % msg_digest - ); + BOOST_LOG_TRIVIAL(trace) << str(boost::format("R%1% BitcoinRpcWallet signing message with digest = %2%.") % + m_conf.id() % msg_digest); message.set_signature(sig); } -bool BitcoinRpcWallet::VerifySignature(const Message& message) const -{ +bool BitcoinRpcWallet::VerifySignature(const Message& message) const { string msg_digest = message.digest(); string msg_sig = message.signature(); - string msg_pubkey_address = - m_conf.replica_set_v().at(message.sender_id()).p2pkh(); + string msg_pubkey_address = m_conf.replica_set_v().at(message.sender_id()).p2pkh(); - return m_bitcoind.verifymessage( - msg_pubkey_address, - msg_sig, - msg_digest - ); + return m_bitcoind.verifymessage(msg_pubkey_address, msg_sig, msg_digest); } -} -} +} // namespace wallet +} // namespace itcoin diff --git a/src/wallet/RoastWallet.cpp b/src/wallet/RoastWallet.cpp index e0c47b7..bbafc8d 100644 --- a/src/wallet/RoastWallet.cpp +++ b/src/wallet/RoastWallet.cpp @@ -8,10 +8,7 @@ using namespace std; namespace itcoin { namespace wallet { -RoastWallet::RoastWallet(const itcoin::FbftConfig& conf): -Wallet(conf) -{ -} +RoastWallet::RoastWallet(const itcoin::FbftConfig& conf) : Wallet(conf) {} -} -} +} // namespace wallet +} // namespace itcoin diff --git a/src/wallet/RoastWalletImpl.cpp b/src/wallet/RoastWalletImpl.cpp index 141c42d..08231a1 100644 --- a/src/wallet/RoastWalletImpl.cpp +++ b/src/wallet/RoastWalletImpl.cpp @@ -8,14 +8,14 @@ #include #include