提交 0204bcdc 编写于 作者: N Nathan Hourt

Ref #17: Define types, logic, tests

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.
上级 296ef5d1
#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
......@@ -12,9 +12,9 @@ add_library( eos_chain
get_config.cpp
block_log.cpp
BlockchainConfiguration.cpp
${HEADERS}
${PROTOCOL_HEADERS}
)
target_link_libraries( eos_chain fc chainbase eos_types wren )
......
#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), )
......@@ -23,6 +23,7 @@
*/
#pragma once
#include <eos/chain/types.hpp>
#include <eos/chain/BlockchainConfiguration.hpp>
#include "multi_index_includes.hpp"
......@@ -37,6 +38,8 @@ namespace eos { namespace chain {
public_key_type signing_key;
int64_t total_missed = 0;
uint32_t last_confirmed_block_num = 0;
BlockchainConfiguration properties;
};
struct by_key;
......@@ -60,4 +63,5 @@ FC_REFLECT(eos::chain::producer_object,
(signing_key)
(total_missed)
(last_confirmed_block_num)
(properties)
)
......@@ -113,6 +113,7 @@ namespace eos { namespace chain {
using eos::types::AccountName;
using eos::types::PermissionName;
using eos::types::Asset;
using eos::types::ShareType;
using eos::types::Authority;
using eos::types::PermissionName;
using eos::types::TypeName;
......
......@@ -7,6 +7,7 @@ add_library( eos_types
native.cpp
${HEADERS}
"${CMAKE_CURRENT_SOURCE_DIR}/include/eos/types/generated.hpp"
types.eos
)
target_include_directories( eos_types PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
target_link_libraries( eos_types eos_utilities fc )
......
......@@ -40,6 +40,14 @@ struct Authority
keys KeyPermissionWeight[]
accounts AccountPermissionWeight[]
struct BlockchainConfiguration
maxBlockSize UInt32
targetBlockSize UInt32
maxStorageSize UInt64
electedPay ShareType
runnerUpPay ShareType
minAccountBalance ShareType
struct Transfer
from AccountName # may not be the message.sender if message.sender has delegated authority by from
to AccountName
......
#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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册