forked from EOSIO/eos
-
Notifications
You must be signed in to change notification settings - Fork 70
/
eosio.system.cpp
195 lines (164 loc) · 7.34 KB
/
eosio.system.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include "eosio.system.hpp"
#include <eosiolib/dispatcher.hpp>
#include "producer_pay.cpp"
#include "delegate_bandwidth.cpp"
#include "voting.cpp"
#include "exchange_state.cpp"
namespace eosiosystem {
system_contract::system_contract( account_name s )
:native(s),
_voters(_self,_self),
_producers(_self,_self),
_global(_self,_self),
_rammarket(_self,_self)
{
//print( "construct system\n" );
_gstate = _global.exists() ? _global.get() : get_default_parameters();
auto itr = _rammarket.find(S(4,RAMCORE));
if( itr == _rammarket.end() ) {
auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount;
if( system_token_supply > 0 ) {
itr = _rammarket.emplace( _self, [&]( auto& m ) {
m.supply.amount = 100000000000000ll;
m.supply.symbol = S(4,RAMCORE);
m.base.balance.amount = int64_t(_gstate.free_ram());
m.base.balance.symbol = S(0,RAM);
m.quote.balance.amount = system_token_supply / 1000;
m.quote.balance.symbol = CORE_SYMBOL;
});
}
} else {
//print( "ram market already created" );
}
}
eosio_global_state system_contract::get_default_parameters() {
eosio_global_state dp;
get_blockchain_parameters(dp);
return dp;
}
system_contract::~system_contract() {
//print( "destruct system\n" );
_global.set( _gstate, _self );
//eosio_exit(0);
}
void system_contract::setram( uint64_t max_ram_size ) {
require_auth( _self );
eosio_assert( _gstate.max_ram_size < max_ram_size, "ram may only be increased" ); /// decreasing ram might result market maker issues
eosio_assert( max_ram_size < 1024ll*1024*1024*1024*1024, "ram size is unrealistic" );
eosio_assert( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" );
auto delta = int64_t(max_ram_size) - int64_t(_gstate.max_ram_size);
auto itr = _rammarket.find(S(4,RAMCORE));
/**
* Increase or decrease the amount of ram for sale based upon the change in max
* ram size.
*/
_rammarket.modify( itr, 0, [&]( auto& m ) {
m.base.balance.amount += delta;
});
_gstate.max_ram_size = max_ram_size;
_global.set( _gstate, _self );
}
void system_contract::setparams( const eosio::blockchain_parameters& params ) {
require_auth( N(eosio) );
(eosio::blockchain_parameters&)(_gstate) = params;
eosio_assert( 3 <= _gstate.max_authority_depth, "max_authority_depth should be at least 3" );
set_blockchain_parameters( params );
}
void system_contract::setpriv( account_name account, uint8_t ispriv ) {
require_auth( _self );
set_privileged( account, ispriv );
}
void system_contract::rmvproducer( account_name producer ) {
require_auth( _self );
auto prod = _producers.find( producer );
eosio_assert( prod != _producers.end(), "producer not found" );
_producers.modify( prod, 0, [&](auto& p) {
p.deactivate();
});
}
void system_contract::bidname( account_name bidder, account_name newname, asset bid ) {
require_auth( bidder );
eosio_assert( eosio::name_suffix(newname) == newname, "you can only bid on top-level suffix" );
eosio_assert( !is_account( newname ), "account already exists" );
eosio_assert( bid.symbol == asset().symbol, "asset must be system token" );
eosio_assert( bid.amount > 0, "insufficient bid" );
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {bidder,N(active)},
{ bidder, N(eosio.names), bid, std::string("bid name ")+(name{newname}).to_string() } );
name_bid_table bids(_self,_self);
print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" );
auto current = bids.find( newname );
if( current == bids.end() ) {
bids.emplace( bidder, [&]( auto& b ) {
b.newname = newname;
b.high_bidder = bidder;
b.high_bid = bid.amount;
b.last_bid_time = current_time();
});
} else {
eosio_assert( current->high_bid > 0, "this auction has already closed" );
eosio_assert( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" );
eosio_assert( current->high_bidder != bidder, "account is already highest bidder" );
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.names),N(active)},
{ N(eosio.names), current->high_bidder, asset(current->high_bid),
std::string("refund bid on name ")+(name{newname}).to_string() } );
bids.modify( current, bidder, [&]( auto& b ) {
b.high_bidder = bidder;
b.high_bid = bid.amount;
b.last_bid_time = current_time();
});
}
}
/**
* Called after a new account is created. This code enforces resource-limits rules
* for new accounts as well as new account naming conventions.
*
* Account names containing '.' symbols must have a suffix equal to the name of the creator.
* This allows users who buy a premium name (shorter than 12 characters with no dots) to be the only ones
* who can create accounts with the creator's name as a suffix.
*
*/
void native::newaccount( account_name creator,
account_name newact
/* no need to parse authorites
const authority& owner,
const authority& active*/ ) {
if( creator != _self ) {
auto tmp = newact >> 4;
bool has_dot = false;
for( uint32_t i = 0; i < 12; ++i ) {
has_dot |= !(tmp & 0x1f);
tmp >>= 5;
}
if( has_dot ) { // or is less than 12 characters
auto suffix = eosio::name_suffix(newact);
if( suffix == newact ) {
name_bid_table bids(_self,_self);
auto current = bids.find( newact );
eosio_assert( current != bids.end(), "no active bid for name" );
eosio_assert( current->high_bidder == creator, "only highest bidder can claim" );
eosio_assert( current->high_bid < 0, "auction for name is not closed yet" );
bids.erase( current );
} else {
eosio_assert( creator == suffix, "only suffix may create this account" );
}
}
}
user_resources_table userres( _self, newact);
userres.emplace( newact, [&]( auto& res ) {
res.owner = newact;
});
set_resource_limits( newact, 0, 0, 0 );
}
} /// eosio.system
EOSIO_ABI( eosiosystem::system_contract,
// native.hpp (newaccount definition is actually in eosio.system.cpp)
(newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)
// eosio.system.cpp
(setram)(setparams)(setpriv)(rmvproducer)(bidname)
// delegate_bandwidth.cpp
(buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund)
// voting.cpp
(regproducer)(unregprod)(voteproducer)(regproxy)
// producer_pay.cpp
(onblock)(claimrewards)
)