提交 49ea3373 编写于 作者: D Daniel Larimer

remove broken producer proxy voting

上级 303f2bb9
......@@ -34,8 +34,6 @@ void chain_initializer::register_types(chain_controller& chain, chainbase::datab
// Install the native contract's indexes; we can't do anything until our objects are recognized
db.add_index<staked_balance_multi_index>();
db.add_index<producer_votes_multi_index>();
db.add_index<proxy_vote_multi_index>();
db.add_index<producer_schedule_multi_index>();
#define SET_APP_HANDLER( contract, scope, action, nspace ) \
chain._set_apply_handler( #contract, #scope, #action, &BOOST_PP_CAT(contracts::apply_, BOOST_PP_CAT(contract, BOOST_PP_CAT(_,action) ) ) )
......@@ -270,9 +268,6 @@ std::vector<action> chain_initializer::prepare_database( chain_controller& chain
chainbase::database& db) {
std::vector<action> messages_to_process;
// Create the singleton object, producer_schedule_object
db.create<producer_schedule_object>([](const auto&){});
/// Create the native contract accounts manually; sadly, we can't run their contracts to make them create themselves
auto create_native_account = [this, &db](account_name name, auto liquid_balance) {
db.create<account_object>([this, &name](account_object& a) {
......
......@@ -358,10 +358,6 @@ void apply_eosio_okproducer(apply_context& context) {
auto total_voting_stake = voter.staked_balance;
// Check if voter is proxied to; if so, we need to add in the proxied stake
if (auto proxy = db.find<proxy_vote_object, by_target_name>(voter.owner_name))
total_voting_stake += proxy->proxied_stake;
// Add/remove votes from producer
db.modify(producer, [approve = approve.approve, total_voting_stake](producer_votes_object& pvo) {
if (approve)
......
......@@ -14,114 +14,5 @@
namespace eosio { namespace chain { namespace contracts {
void proxy_vote_object::add_proxy_source(const account_name& source, share_type source_stake, chainbase::database& db) const {
db.modify(*this, [&source, source_stake](proxy_vote_object& pvo) {
pvo.proxy_sources.insert(source);
pvo.proxied_stake += source_stake;
});
db.get<staked_balance_object, by_owner_name>(proxy_target).propagate_votes(source_stake, db);
}
void proxy_vote_object::remove_proxy_source(const account_name& source, share_type source_stake,
chainbase::database& db) const {
db.modify(*this, [&source, source_stake](proxy_vote_object& pvo) {
pvo.proxy_sources.erase(source);
pvo.proxied_stake -= source_stake;
});
db.get<staked_balance_object, by_owner_name>(proxy_target).propagate_votes(source_stake, db);
}
void proxy_vote_object::update_proxied_state(share_type staked_delta, chainbase::database& db) const {
db.modify(*this, [staked_delta](proxy_vote_object& pvo) {
pvo.proxied_stake += staked_delta;
});
db.get<staked_balance_object, by_owner_name>(proxy_target).propagate_votes(staked_delta, db);
}
void proxy_vote_object::cancel_proxies(chainbase::database& db) const {
boost::for_each(proxy_sources, [&db](const account_name& source) {
const auto& balance = db.get<staked_balance_object, by_owner_name>(source);
db.modify(balance, [](staked_balance_object& sbo) {
sbo.producer_votes = producer_slate{};
});
});
}
/*
producer_round producer_schedule_object::calculate_next_round(chainbase::database& db) const {
// Create storage and machinery with nice names, for choosing the top-voted producers
producer_round round;
auto filter_retired_producers = boost::adaptors::filtered([&db](const producer_votes_object& pvo) {
return db.get<producer_object, by_owner>(pvo.owner_name).signing_key != public_key();
});
auto produer_object_to_name = boost::adaptors::transformed([](const producer_votes_object& p) { return p.owner_name; });
const auto& all_producers_by_votes = db.get_index<producer_votes_multi_index, by_votes>();
auto active_producers_by_votes = all_producers_by_votes | filter_retired_producers;
FC_ASSERT(boost::distance(active_producers_by_votes) >= config::blocks_per_round,
"Not enough active producers registered to schedule a round!",
("active_producers", (int64_t)boost::distance(active_producers_by_votes))
("all_producers", (int64_t)all_producers_by_votes.size()));
// Copy the top voted active producer's names into the round
auto runner_up_storage =
boost::copy_n(active_producers_by_votes | produer_object_to_name, config::voted_producers_per_round, round.begin());
// More machinery with nice names, this time for choosing runner-up producers
auto voted_producer_range = boost::make_iterator_range(round.begin(), runner_up_storage);
// Sort the voted producer names; we'll need to do it anyways, and it makes searching faster if we do it now
boost::sort(voted_producer_range);
auto FilterVotedProducers = boost::adaptors::filtered([&voted_producer_range](const producer_votes_object& pvo) {
return !boost::binary_search(voted_producer_range, pvo.owner_name);
});
const auto& all_producers_by_finish_time = db.get_index<producer_votes_multi_index, by_projected_race_finish_time>();
auto eligible_producers_by_finish_time = all_producers_by_finish_time | filter_retired_producers | FilterVotedProducers;
auto runnerUpProducerCount = config::blocks_per_round - config::voted_producers_per_round;
// Copy the front producers in the race into the round
auto round_end =
boost::copy_n(eligible_producers_by_finish_time | produer_object_to_name, runnerUpProducerCount, runner_up_storage);
FC_ASSERT(round_end == round.end(),
"Round scheduling yielded an unexpected number of producers: got ${actual}, but expected ${expected}",
("actual", (int64_t)std::distance(round.begin(), round_end))("expected", (int64_t)round.size()));
auto lastRunnerUpName = *(round_end - 1);
// Sort the runner-up producers into the voted ones
boost::inplace_merge(round, runner_up_storage);
// Machinery to update the virtual race tracking for the producers that completed their lap
auto lastRunnerUp = all_producers_by_finish_time.iterator_to(db.get<producer_votes_object,by_owner_name>(lastRunnerUpName));
auto new_race_time = lastRunnerUp->projected_race_finish_time();
auto start_new_lap = [&db, new_race_time](const producer_votes_object& pvo) {
db.modify(pvo, [new_race_time](producer_votes_object& pvo) {
pvo.start_new_race_lap(new_race_time);
});
};
auto lap_completers = boost::make_iterator_range(all_producers_by_finish_time.begin(), ++lastRunnerUp);
// Start each producer that finished his lap on the next one, and update the global race time.
try {
if (boost::distance(lap_completers) < all_producers_by_finish_time.size()
&& new_race_time < std::numeric_limits<uint128_t>::max()) {
//ilog("Processed producer race. ${count} producers completed a lap at virtual time ${time}",
// ("count", (int64_t)boost::distance(lap_completers))("time", new_race_time));
boost::for_each(lap_completers, start_new_lap);
db.modify(*this, [new_race_time](producer_schedule_object& pso) {
pso.current_race_time = new_race_time;
});
} else {
//wlog("Producer race finished; restarting race.");
reset_producer_race(db);
}
} catch (producer_race_overflow_exception&) {
// Virtual race time has overflown. Reset race for everyone.
// wlog("Producer race virtual time overflow detected! Resetting race.");
reset_producer_race(db);
}
return round;
}
*/
} } } // namespace eosio::chain::contracts
......@@ -56,9 +56,6 @@ void staked_balance_object::propagate_votes(share_type staked_delta, chainbase::
});
});
else {
// This account has proxied its votes to another account; update the proxy_vote_object
const auto& proxy = db.get<proxy_vote_object, by_target_name>(producer_votes.get<account_name>());
proxy.update_proxied_state(staked_delta, db);
}
}
......
......@@ -42,81 +42,6 @@ class producer_votes_object : public chainbase::object<producer_votes_object_typ
}
};
/**
* @brief The proxy_vote_object tracks proxied votes
*
* This object is created when an account indicates that it wishes to allow other accounts to proxy their votes to it,
* so that the proxying accounts add their stake to the proxy target's votes.
*
* When an account S proxies its votes to an account P, we look up the @ref proxy_vote_object with @ref proxy_target P,
* and add S to the @ref proxy_sources, and add S's stake to @proxied_stake. We then update @ref proxy_target's votes, to
* account for the change in its voting weight. Any time S's stake changes, we update the @ref proxied_stake accordingly.
* If S terminates its vote delegation to P, we remove S and its stake from @ref proxy_sources and @ref proxied_stake,
* then update @ref proxy_target's votes. If P stops accepting proxied votes, then its @ref proxy_vote_object is removed
* and all accounts listed in @ref proxy_sources revert back to an unproxied voting state.
*
* Whenever any account A changes its votes, we check if there is some @ref proxy_vote_object for which A is the target,
* and if so, we add the @ref proxied_stake to its voting weight.
*
* An account A may only proxy to one account at a time, and if A has proxied its votes to some other account, A may
* not cast any other votes until it unproxies its voting power.
*/
class proxy_vote_object : public chainbase::object<proxy_vote_object_type, proxy_vote_object> {
OBJECT_CTOR(proxy_vote_object, (proxy_sources))
id_type id;
/// The account receiving the proxied voting power
account_name proxy_target;
/// The list of accounts proxying their voting power to @ref proxy_target
shared_set<account_name> proxy_sources;
/// The total stake proxied to @ref proxy_target. At all times, this should be equal to the sum of stake over all
/// accounts in @ref proxy_sources
share_type proxied_stake = 0;
void add_proxy_source(const account_name& source, share_type source_stake, chainbase::database& db) const;
void remove_proxy_source(const account_name& source, share_type source_stake,
chainbase::database& db) const;
void update_proxied_state(share_type staked_delta, chainbase::database& db) const;
/// Cancel proxying votes to @ref proxy_target for all @ref proxy_sources
void cancel_proxies(chainbase::database& db) const;
};
/**
* @brief The producer_schedule_object class schedules producers into rounds
*
* This class stores the state of the virtual race to select runner-up producers, and provides the logic for selecting
* a round of producers.
*
* This is a singleton object within the database; there will only be one stored.
*/
class producer_schedule_object : public chainbase::object<producer_schedule_object_type, producer_schedule_object> {
OBJECT_CTOR(producer_schedule_object)
id_type id;
uint128_t current_race_time = 0;
/// Retrieve a reference to the producer_schedule_object stored in the provided database
static const producer_schedule_object& get(const chainbase::database& db) { return db.get(id_type()); }
/**
* @brief Calculate the next round of block producers
* @param db The blockchain database
* @return The next round of block producers, sorted by owner name
*
* This method calculates the next round of block producers according to votes and the virtual race for runner-up
* producers. Although it is a const method, it will use its non-const db parameter to update its own records, as
* well as the race records stored in the @ref producer_votes_objects
*/
//TODO: did the concept of producer rounds get destroyed?
//producer_round calculate_next_round(chainbase::database& db) const;
/**
* @brief Reset all producers in the virtual race to the starting line, and reset virtual time to zero
*/
void reset_producer_race(chainbase::database& db) const;
};
using boost::multi_index::const_mem_fun;
/// Index producers by their owner's name
struct by_owner_name;
......@@ -147,25 +72,6 @@ using producer_votes_multi_index = chainbase::shared_multi_index_container<
/// Index proxies by the proxy target account name
struct by_target_name;
using proxy_vote_multi_index = chainbase::shared_multi_index_container<
proxy_vote_object,
indexed_by<
ordered_unique<tag<by_id>, member<proxy_vote_object, proxy_vote_object::id_type, &proxy_vote_object::id>>,
ordered_unique<tag<by_target_name>, member<proxy_vote_object, account_name, &proxy_vote_object::proxy_target>>
>
>;
using producer_schedule_multi_index = chainbase::shared_multi_index_container<
producer_schedule_object,
indexed_by<
ordered_unique<tag<by_id>,
member<producer_schedule_object, producer_schedule_object::id_type, &producer_schedule_object::id>
>
>
>;
} } } // namespace eosio::chain::contracts
CHAINBASE_SET_INDEX_TYPE(eosio::chain::contracts::producer_votes_object, eosio::chain::contracts::producer_votes_multi_index)
CHAINBASE_SET_INDEX_TYPE(eosio::chain::contracts::proxy_vote_object, eosio::chain::contracts::proxy_vote_multi_index)
CHAINBASE_SET_INDEX_TYPE(eosio::chain::contracts::producer_schedule_object, eosio::chain::contracts::producer_schedule_multi_index)
......@@ -62,7 +62,6 @@ namespace eosio { namespace chain {
block_id_type head_block_id;
time_point time;
account_name current_producer;
uint32_t accounts_registered_this_interval = 0;
share_type total_staked_tokens;
......@@ -165,7 +164,6 @@ FC_REFLECT(eosio::chain::dynamic_global_property_object,
(head_block_id)
(time)
(current_producer)
(accounts_registered_this_interval)
(current_absolute_slot)
(recent_slots_filled)
(last_irreversible_block_num)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册