Skip to content

Commit 628d7c9

Browse files
committed
Merge branch 'staking' into 'master'
Changed staking and voting mechanisms See merge request snax/blockchain/eos/snax!48
2 parents ff907bb + ee974a4 commit 628d7c9

6 files changed

Lines changed: 256 additions & 177 deletions

File tree

contracts/snax.system/snax.system.hpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,39 @@ namespace snaxsystem {
173173
static constexpr uint32_t seconds_per_day = 24 * 3600;
174174
static constexpr uint64_t system_token_symbol = CORE_SYMBOL;
175175

176+
static double snax_vote_multipliers[] = {
177+
1.00000000000000,
178+
0.90000000000000,
179+
0.80000000000000,
180+
0.70000000000000,
181+
0.55000000000000,
182+
0.40000000000000,
183+
0.25000000000000,
184+
0.10000000000000,
185+
0.05000000000000,
186+
0.02500000000000,
187+
0.01250000000000,
188+
0.00625000000000,
189+
0.00312500000000,
190+
0.00156250000000,
191+
0.00078125000000,
192+
0.00039062500000,
193+
0.00019531250000,
194+
0.00009765625000,
195+
0.00004882812500,
196+
0.00002441406250,
197+
0.00001220703125,
198+
0.00000610351563,
199+
0.00000244140625,
200+
0.00000244140625,
201+
0.00000244140625,
202+
0.00000244140625,
203+
0.00000244140625,
204+
0.00000244140625,
205+
0.00000244140625,
206+
0.00000244140625,
207+
};
208+
176209
class system_contract : public native {
177210
private:
178211
voters_table _voters;
@@ -277,6 +310,9 @@ namespace snaxsystem {
277310
std::tuple<double, double> get_parabola(double x0, double y0) const;
278311
double calculate_parabola(double a, double b, double c, double x) const;
279312
double convert_asset_to_double(asset value) const;
313+
double apply_vote_weight(const account_name voter, const double vote_weight, const uint8_t iter) const {
314+
return voter == N(snax.team) ? vote_weight * snax_vote_multipliers[iter]: vote_weight;
315+
}
280316
asset get_balance(account_name account);
281317

282318
void update_elected_producers( block_timestamp timestamp );

contracts/snax.system/voting.cpp

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,6 @@ namespace snaxsystem {
2626
using snax::singleton;
2727
using snax::transaction;
2828

29-
static double vote_multipliers[] = {
30-
1.00000000000000,
31-
0.90000000000000,
32-
0.80000000000000,
33-
0.70000000000000,
34-
0.55000000000000,
35-
0.40000000000000,
36-
0.25000000000000,
37-
0.10000000000000,
38-
0.05000000000000,
39-
0.02500000000000,
40-
0.01250000000000,
41-
0.00625000000000,
42-
0.00312500000000,
43-
0.00156250000000,
44-
0.00078125000000,
45-
0.00039062500000,
46-
0.00019531250000,
47-
0.00009765625000,
48-
0.00004882812500,
49-
0.00002441406250,
50-
0.00001220703125,
51-
0.00000610351563,
52-
0.00000244140625,
53-
0.00000244140625,
54-
0.00000244140625,
55-
0.00000244140625,
56-
0.00000244140625,
57-
0.00000244140625,
58-
0.00000244140625,
59-
0.00000244140625,
60-
};
61-
6229
/**
6330
* This method will create a producer_config and producer_info object for 'producer'
6431
*
@@ -115,6 +82,9 @@ namespace snaxsystem {
11582
if (it->active()) top_producers.emplace_back( std::pair<snax::producer_key,uint16_t>({{it->owner, it->producer_key}, it->location}) );
11683
}
11784

85+
if (top_producers.size() == 0)
86+
return;
87+
11888
/// sort by producer name
11989
std::sort( top_producers.begin(), top_producers.end() );
12090

@@ -134,8 +104,9 @@ namespace snaxsystem {
134104
double stake2vote( int64_t staked ) {
135105
/// TODO subtract 2080 brings the large numbers closer to this decade
136106
double weight = int64_t( (now() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 );
137-
return double(staked) / 10000 * std::pow( 2, weight );
107+
return double(staked) / 100 * std::pow( 2, weight );
138108
}
109+
139110
/**
140111
* @pre producers must be sorted from lowest to highest and must be registered and active
141112
* @pre if proxy is set then no producers can be voted for
@@ -201,12 +172,14 @@ namespace snaxsystem {
201172
});
202173
propagate_weight_change( *old_proxy );
203174
} else {
175+
uint8_t iter = 0;
204176
for( const auto& p : voter->producers ) {
205177
if (p != 0) {
206178
auto& d = producer_deltas[p];
207-
d.first -= voter->last_vote_weight;
179+
d.first -= system_contract::apply_vote_weight(voter_name, voter->last_vote_weight, iter);
208180
d.second = false;
209181
}
182+
iter++;
210183
}
211184
}
212185
}
@@ -223,10 +196,10 @@ namespace snaxsystem {
223196
}
224197
} else {
225198
if( new_vote_weight >= 0 ) {
226-
int8_t iter = 0;
199+
uint8_t iter = 0;
227200
for( const auto& p : producers ) {
228201
if (p != 0) {
229-
const double vote_weight = voter_name == N(snax.team) ? new_vote_weight * vote_multipliers[iter]: new_vote_weight;
202+
auto vote_weight = system_contract::apply_vote_weight(voter_name, new_vote_weight, iter);
230203
auto& d = producer_deltas[p];
231204
d.first += vote_weight;
232205
d.second = true;
@@ -306,12 +279,17 @@ namespace snaxsystem {
306279
propagate_weight_change( proxy );
307280
} else {
308281
auto delta = new_weight - voter.last_vote_weight;
282+
uint8_t iter = 0;
309283
for ( auto acnt : voter.producers ) {
310-
auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption
311-
_producers.modify( pitr, 0, [&]( auto& p ) {
312-
p.total_votes += delta;
313-
_gstate.total_producer_vote_weight += delta;
314-
});
284+
if (acnt) {
285+
auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption
286+
_producers.modify( pitr, 0, [&]( auto& p ) {
287+
auto votes = system_contract::apply_vote_weight(voter.owner, delta, iter);
288+
p.total_votes += votes;
289+
_gstate.total_producer_vote_weight += votes;
290+
});
291+
}
292+
iter++;
315293
}
316294
}
317295
}

contracts/test_snax.system/test_snax.system.hpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,39 @@ namespace snaxsystem {
173173
static constexpr uint32_t seconds_per_day = 24 * 3600;
174174
static constexpr uint64_t system_token_symbol = CORE_SYMBOL;
175175

176+
static double snax_vote_multipliers[] = {
177+
1.00000000000000,
178+
0.90000000000000,
179+
0.80000000000000,
180+
0.70000000000000,
181+
0.55000000000000,
182+
0.40000000000000,
183+
0.25000000000000,
184+
0.10000000000000,
185+
0.05000000000000,
186+
0.02500000000000,
187+
0.01250000000000,
188+
0.00625000000000,
189+
0.00312500000000,
190+
0.00156250000000,
191+
0.00078125000000,
192+
0.00039062500000,
193+
0.00019531250000,
194+
0.00009765625000,
195+
0.00004882812500,
196+
0.00002441406250,
197+
0.00001220703125,
198+
0.00000610351563,
199+
0.00000244140625,
200+
0.00000244140625,
201+
0.00000244140625,
202+
0.00000244140625,
203+
0.00000244140625,
204+
0.00000244140625,
205+
0.00000244140625,
206+
0.00000244140625,
207+
};
208+
176209
class system_contract : public native {
177210
private:
178211
voters_table _voters;
@@ -279,6 +312,9 @@ namespace snaxsystem {
279312
std::tuple<double, double> get_parabola(double x0, double y0) const;
280313
double calculate_parabola(double a, double b, double c, double x) const;
281314
double convert_asset_to_double(asset value) const;
315+
double apply_vote_weight(const account_name voter, const double vote_weight, const uint8_t iter) const {
316+
return voter == N(snax.team) ? vote_weight * snax_vote_multipliers[iter]: vote_weight;
317+
}
282318
asset get_balance(account_name account);
283319

284320
void update_elected_producers( block_timestamp timestamp );

contracts/test_snax.system/voting.cpp

Lines changed: 24 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,6 @@ namespace snaxsystem {
2626
using snax::singleton;
2727
using snax::transaction;
2828

29-
static double vote_multipliers[] = {
30-
1.00000000000000,
31-
0.90000000000000,
32-
0.80000000000000,
33-
0.70000000000000,
34-
0.55000000000000,
35-
0.40000000000000,
36-
0.25000000000000,
37-
0.10000000000000,
38-
0.05000000000000,
39-
0.02500000000000,
40-
0.01250000000000,
41-
0.00625000000000,
42-
0.00312500000000,
43-
0.00156250000000,
44-
0.00078125000000,
45-
0.00039062500000,
46-
0.00019531250000,
47-
0.00009765625000,
48-
0.00004882812500,
49-
0.00002441406250,
50-
0.00001220703125,
51-
0.00000610351563,
52-
0.00000244140625,
53-
0.00000244140625,
54-
0.00000244140625,
55-
0.00000244140625,
56-
0.00000244140625,
57-
0.00000244140625,
58-
0.00000244140625,
59-
0.00000244140625,
60-
};
61-
6229
/**
6330
* This method will create a producer_config and producer_info object for 'producer'
6431
*
@@ -115,6 +82,9 @@ namespace snaxsystem {
11582
if (it->active()) top_producers.emplace_back( std::pair<snax::producer_key,uint16_t>({{it->owner, it->producer_key}, it->location}) );
11683
}
11784

85+
if (top_producers.size() == 0)
86+
return;
87+
11888
/// sort by producer name
11989
std::sort( top_producers.begin(), top_producers.end() );
12090

@@ -134,8 +104,9 @@ namespace snaxsystem {
134104
double stake2vote( int64_t staked ) {
135105
/// TODO subtract 2080 brings the large numbers closer to this decade
136106
double weight = int64_t( (now() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 );
137-
return double(staked) / 10000 * std::pow( 2, weight );
107+
return double(staked) / 100 * std::pow( 2, weight );
138108
}
109+
139110
/**
140111
* @pre producers must be sorted from lowest to highest and must be registered and active
141112
* @pre if proxy is set then no producers can be voted for
@@ -201,12 +172,14 @@ namespace snaxsystem {
201172
});
202173
propagate_weight_change( *old_proxy );
203174
} else {
175+
uint8_t iter = 0;
204176
for( const auto& p : voter->producers ) {
205-
if (p != 0) {
206-
auto& d = producer_deltas[p];
207-
d.first -= voter->last_vote_weight;
208-
d.second = false;
209-
}
177+
if (p != 0) {
178+
auto& d = producer_deltas[p];
179+
d.first -= system_contract::apply_vote_weight(voter_name, voter->last_vote_weight, iter);
180+
d.second = false;
181+
}
182+
iter++;
210183
}
211184
}
212185
}
@@ -223,10 +196,10 @@ namespace snaxsystem {
223196
}
224197
} else {
225198
if( new_vote_weight >= 0 ) {
226-
int8_t iter = 0;
199+
uint8_t iter = 0;
227200
for( const auto& p : producers ) {
228201
if (p != 0) {
229-
const double vote_weight = voter_name == N(snax.team) ? new_vote_weight * vote_multipliers[iter]: new_vote_weight;
202+
auto vote_weight = system_contract::apply_vote_weight(voter_name, new_vote_weight, iter);
230203
auto& d = producer_deltas[p];
231204
d.first += vote_weight;
232205
d.second = true;
@@ -306,12 +279,17 @@ namespace snaxsystem {
306279
propagate_weight_change( proxy );
307280
} else {
308281
auto delta = new_weight - voter.last_vote_weight;
282+
uint8_t iter = 0;
309283
for ( auto acnt : voter.producers ) {
310-
auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption
311-
_producers.modify( pitr, 0, [&]( auto& p ) {
312-
p.total_votes += delta;
313-
_gstate.total_producer_vote_weight += delta;
314-
});
284+
if (acnt) {
285+
auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption
286+
_producers.modify( pitr, 0, [&]( auto& p ) {
287+
auto votes = system_contract::apply_vote_weight(voter.owner, delta, iter);
288+
p.total_votes += votes;
289+
_gstate.total_producer_vote_weight += votes;
290+
});
291+
}
292+
iter++;
315293
}
316294
}
317295
}

0 commit comments

Comments
 (0)