This repository has been archived by the owner on Aug 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds the BlockchainConfiguration type, which contains the values to be voted on by producers. It also adds the algorithm to create a BlockchainConfiguration containing the median values from a vector of BlockchainConfigurations. Finally, it adds a testcase which verifies that the median calculation is performed correctly.
- Loading branch information
1 parent
296ef5d
commit 0204bcd
Showing
8 changed files
with
142 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#include <eos/chain/BlockchainConfiguration.hpp> | ||
|
||
#include <boost/range/algorithm.hpp> | ||
|
||
#include <fc/io/json.hpp> | ||
|
||
namespace eos { namespace chain { | ||
|
||
template <typename T, typename Range> | ||
struct properties_median_calculator_visitor { | ||
properties_median_calculator_visitor (T& medians, Range votes) | ||
: medians(medians), votes(votes) | ||
{} | ||
|
||
template <typename Member, class Class, Member (Class::*member)> | ||
void operator() (const char*) const { | ||
auto median_itr = boost::begin(votes) + boost::distance(votes)/2; | ||
boost::nth_element(votes, median_itr, [](const T& a, const T& b) { return a.*member < b.*member; }); | ||
medians.*member = (*median_itr).*member; | ||
} | ||
|
||
T& medians; | ||
mutable Range votes; | ||
}; | ||
template <typename T, typename Range> | ||
properties_median_calculator_visitor<T, Range> get_median_properties_calculator(T& medians, Range&& votes) { | ||
return properties_median_calculator_visitor<T, Range>(medians, std::move(votes)); | ||
} | ||
|
||
BlockchainConfiguration BlockchainConfiguration::get_median_values( | ||
std::vector<BlockchainConfiguration> votes) { | ||
BlockchainConfiguration results; | ||
fc::reflector<BlockchainConfiguration>::visit(get_median_properties_calculator(results, std::move(votes))); | ||
return results; | ||
} | ||
|
||
template <typename T> | ||
struct comparison_visitor { | ||
const T& a; | ||
const T& b; | ||
|
||
template <typename Member, class Class, Member (Class::*member)> | ||
void operator() (const char*) const { | ||
if (a.*member != b.*member) | ||
throw false; | ||
} | ||
}; | ||
|
||
bool BlockchainConfiguration::operator==(const BlockchainConfiguration& other) const { | ||
try { | ||
fc::reflector<BlockchainConfiguration>::visit(comparison_visitor<BlockchainConfiguration>{*this, other}); | ||
} catch (bool) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
std::ostream& operator<< (std::ostream& s, const BlockchainConfiguration& p) { | ||
return s << fc::json::to_string(p); | ||
} | ||
|
||
} } // namespace eos::chain |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
libraries/chain/include/eos/chain/BlockchainConfiguration.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#pragma once | ||
|
||
#include <eos/chain/types.hpp> | ||
|
||
#include <eos/types/generated.hpp> | ||
|
||
namespace eos { | ||
namespace chain { | ||
|
||
/** | ||
* @brief Producer-voted blockchain configuration parameters | ||
* | ||
* This object stores the blockchain configuration, which is set by the block producers. Block producers each vote for | ||
* their preference for each of the parameters in this object, and the blockchain runs according to the median of the | ||
* values specified by the producers. | ||
*/ | ||
struct BlockchainConfiguration : public types::BlockchainConfiguration { | ||
using types::BlockchainConfiguration::BlockchainConfiguration; | ||
|
||
static BlockchainConfiguration get_median_values(std::vector<BlockchainConfiguration> votes); | ||
|
||
bool operator==(const BlockchainConfiguration& other) const; | ||
friend std::ostream& operator<< (std::ostream& s, const BlockchainConfiguration& p); | ||
}; | ||
|
||
} | ||
} // namespace eos::chain | ||
|
||
FC_REFLECT_DERIVED(eos::chain::BlockchainConfiguration, (eos::types::BlockchainConfiguration), ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include <eos/chain/BlockchainConfiguration.hpp> | ||
|
||
#include <boost/test/unit_test.hpp> | ||
|
||
namespace eos { | ||
using namespace chain; | ||
|
||
BOOST_AUTO_TEST_SUITE(misc_tests) | ||
|
||
/// Test calculation of median values of blockchain operation properties | ||
BOOST_AUTO_TEST_CASE(median_properties_test) | ||
{ try { | ||
vector<BlockchainConfiguration> votes{ | ||
{1024 , 512 , 4096 , Asset(5000 ).amount, Asset(4000 ).amount, Asset(100 ).amount}, | ||
{10000 , 100 , 4096 , Asset(3333 ).amount, Asset(27109 ).amount, Asset(10 ).amount}, | ||
{2048 , 1500 , 1000 , Asset(5432 ).amount, Asset(2000 ).amount, Asset(50 ).amount}, | ||
{100 , 25 , 1024 , Asset(90000 ).amount, Asset(0 ).amount, Asset(433 ).amount}, | ||
{1024 , 1000 , 100 , Asset(10 ).amount, Asset(50 ).amount, Asset(200 ).amount}, | ||
}; | ||
BlockchainConfiguration medians{ | ||
1024, 512, 1024, Asset(5000).amount, Asset(2000).amount, Asset(100).amount | ||
}; | ||
|
||
BOOST_CHECK_EQUAL(BlockchainConfiguration::get_median_values(votes), medians); | ||
|
||
votes.emplace_back(BlockchainConfiguration{1, 1, 1, 1, 1, 1}); | ||
votes.emplace_back(BlockchainConfiguration{1, 1, 1, 1, 1, 1}); | ||
medians = {1024, 100, 1000, Asset(3333).amount, Asset(50).amount, Asset(50).amount}; | ||
|
||
BOOST_CHECK_EQUAL(BlockchainConfiguration::get_median_values(votes), medians); | ||
BOOST_CHECK_EQUAL(BlockchainConfiguration::get_median_values({medians}), medians); | ||
} FC_LOG_AND_RETHROW() } | ||
|
||
BOOST_AUTO_TEST_SUITE_END() | ||
|
||
} // namespace eos |