Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
58243806
Y
YTBP
项目概览
YottaChain
/
YTBP
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
YTBP
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
58243806
编写于
7月 23, 2019
作者:
W
Wang Zhi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
backup for eosio.system
上级
8741ff39
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
3374 addition
and
0 deletion
+3374
-0
contracts/eosio.system_bak/CMakeLists.txt
contracts/eosio.system_bak/CMakeLists.txt
+8
-0
contracts/eosio.system_bak/README.md
contracts/eosio.system_bak/README.md
+84
-0
contracts/eosio.system_bak/delegate_bandwidth.cpp
contracts/eosio.system_bak/delegate_bandwidth.cpp
+426
-0
contracts/eosio.system_bak/eosio.system.abi
contracts/eosio.system_bak/eosio.system.abi
+697
-0
contracts/eosio.system_bak/eosio.system.cpp
contracts/eosio.system_bak/eosio.system.cpp
+215
-0
contracts/eosio.system_bak/eosio.system.hpp
contracts/eosio.system_bak/eosio.system.hpp
+360
-0
contracts/eosio.system_bak/exchange_state.cpp
contracts/eosio.system_bak/exchange_state.cpp
+85
-0
contracts/eosio.system_bak/exchange_state.hpp
contracts/eosio.system_bak/exchange_state.hpp
+40
-0
contracts/eosio.system_bak/native.hpp
contracts/eosio.system_bak/native.hpp
+112
-0
contracts/eosio.system_bak/producer_pay.cpp
contracts/eosio.system_bak/producer_pay.cpp
+348
-0
contracts/eosio.system_bak/voting.cpp
contracts/eosio.system_bak/voting.cpp
+999
-0
未找到文件。
contracts/eosio.system_bak/CMakeLists.txt
0 → 100644
浏览文件 @
58243806
file
(
GLOB ABI_FILES
"*.abi"
)
configure_file
(
"
${
ABI_FILES
}
"
"
${
CMAKE_CURRENT_BINARY_DIR
}
"
COPYONLY
)
add_wast_executable
(
TARGET eosio.system
INCLUDE_FOLDERS
${
STANDARD_INCLUDE_FOLDERS
}
LIBRARIES libc++ libc eosiolib eosio.token
DESTINATION_FOLDER
${
CMAKE_CURRENT_BINARY_DIR
}
)
contracts/eosio.system_bak/README.md
0 → 100644
浏览文件 @
58243806
eosio.system
----------
This contract enables users to stake tokens, and then configure and vote on producers and worker proposals.
Users can also proxy their voting influence to other users.
The state of this contract is read to determine the 21 active block producers.
Actions:
The naming convention is codeaccount::actionname followed by a list of paramters.
Indicates that a particular account wishes to become a producer
## eosio.system::cfgproducer account config
-
**account**
the producer account to update
-
updates the configuration settings for a particular producer, these
Storage changes are billed to 'account'
## eosio.system::okproducer account producer vote
-
**account**
the account which is doing the voting
-
**producer**
the producer which is being voted for (or unvoted for)
-
**vote**
true if the producer should be voted for, false if not
Each account has a maximum number of votes it can maintain. Storage changes will be billed to 'account'
## eosio.system::setproxy account proxy
-
**account**
the account which is updating it's proxy
-
**proxy**
the account which will have the power to vote account's stake
All current votes are removed and a new proxy link is created. The votes for every producer the proxy
has voted for are updated immediately.
Storage changes will be billed to 'account'
## eosio.system::unstake account quantity
-
**account**
- the account which is requesting their balance be unstaked
-
**quantity**
- the quantity which will be unstaked, unstaked tokens lose voting influence immediately
-
in order to unstake tokens, an account must request them. The user will receive them over
time via weekly withdraws. The length of time will be configured by the median time as set by
the active producers.
-
If this is called while in the process of unstaking, the currently pending unstake is canceled as if
quantity were 0, then it is applied as if a new unstake request was made.
-
all producers this 'from' has voted for will have their votes updated immediately.
-
bandwidth and storage for the deferred transaction will be billed to 'from'
## eosio.system::withdraw account
-
this action can only be triggered by eosio.system via a deferred transaction generated by unstake
-
this will generate an inline eosio.token::transfer call from=eosio.system to=account and amount equal to the next withdraw increment
-
this will generate another deferred withdraw to continue the process if there are still withdraws to be made
## eosio.system::transfer from to amount memo
-
decrements balance of from if amount <= balance
-
increments balance of to by amount
-
memo is ignored
## eosio.system::stakevote account amount
-
the primary currency of eosio is controlled by the token contract which enables users to transfer
balances from one user to another. The receiver is notified on incoming balances and the vote contract
will stake the tokens on receipt.
-
all producers this 'from' has voted for will have their votes updated immediately.
## eosio.system::onblock account blocktime blocknum
-
this special action is triggered when a block is applied by the given producer and cannot be generated from
any other source. It is used to pay producers and calculate missed blocks of other producers.
-
producer pay is deposited into the producer's stake balance and can be withdrawn over time.
-
if blocknum is the start of a new round this may update the active producer config from the producer votes.
## eosio.system::freeze producer accounts true|false
-
requires permission of the @producers account
-
if an account is frozen, all authorizations of that account are rejected and the code for that account will not be run
## eosio.system::paystandby producer
-
every block some amount of tokens is paid
-
at most once per day a producer may claim a percentage of the standby pay equal to their totalvotes / allvotes
contracts/eosio.system_bak/delegate_bandwidth.cpp
0 → 100644
浏览文件 @
58243806
/**
* @file
* @copyright defined in eos/LICENSE
*/
#include "eosio.system.hpp"
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/datastream.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/multi_index.hpp>
#include <eosiolib/privileged.h>
#include <eosiolib/transaction.hpp>
#include <eosio.token/eosio.token.hpp>
#include <cmath>
#include <map>
namespace
eosiosystem
{
using
eosio
::
asset
;
using
eosio
::
indexed_by
;
using
eosio
::
const_mem_fun
;
using
eosio
::
bytes
;
using
eosio
::
print
;
using
eosio
::
permission_level
;
using
std
::
map
;
using
std
::
pair
;
static
constexpr
time
refund_delay
=
3
*
24
*
3600
;
static
constexpr
time
refund_expiration_time
=
3600
;
struct
user_resources
{
account_name
owner
;
asset
net_weight
;
asset
cpu_weight
;
int64_t
ram_bytes
=
0
;
uint64_t
primary_key
()
const
{
return
owner
;
}
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE
(
user_resources
,
(
owner
)(
net_weight
)(
cpu_weight
)(
ram_bytes
)
)
};
/**
* Every user 'from' has a scope/table that uses every receipient 'to' as the primary key.
*/
struct
delegated_bandwidth
{
account_name
from
;
account_name
to
;
asset
net_weight
;
asset
cpu_weight
;
uint64_t
primary_key
()
const
{
return
to
;
}
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE
(
delegated_bandwidth
,
(
from
)(
to
)(
net_weight
)(
cpu_weight
)
)
};
struct
refund_request
{
account_name
owner
;
time
request_time
;
eosio
::
asset
net_amount
;
eosio
::
asset
cpu_amount
;
uint64_t
primary_key
()
const
{
return
owner
;
}
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE
(
refund_request
,
(
owner
)(
request_time
)(
net_amount
)(
cpu_amount
)
)
};
/**
* These tables are designed to be constructed in the scope of the relevant user, this
* facilitates simpler API for per-user queries
*/
typedef
eosio
::
multi_index
<
N
(
userres
),
user_resources
>
user_resources_table
;
typedef
eosio
::
multi_index
<
N
(
delband
),
delegated_bandwidth
>
del_bandwidth_table
;
typedef
eosio
::
multi_index
<
N
(
refunds
),
refund_request
>
refunds_table
;
/**
* This action will buy an exact amount of ram and bill the payer the current market price.
*/
void
system_contract
::
buyrambytes
(
account_name
payer
,
account_name
receiver
,
uint32_t
bytes
)
{
auto
itr
=
_rammarket
.
find
(
S
(
4
,
RAMCORE
));
auto
tmp
=
*
itr
;
auto
eosout
=
tmp
.
convert
(
asset
(
bytes
,
S
(
0
,
RAM
)),
CORE_SYMBOL
);
buyram
(
payer
,
receiver
,
eosout
);
}
/**
* When buying ram the payer irreversiblly transfers quant to system contract and only
* the receiver may reclaim the tokens via the sellram action. The receiver pays for the
* storage of all database records associated with this action.
*
* RAM is a scarce resource whose supply is defined by global properties max_ram_size. RAM is
* priced using the bancor algorithm such that price-per-byte with a constant reserve ratio of 100:1.
*/
void
system_contract
::
buyram
(
account_name
payer
,
account_name
receiver
,
asset
quant
)
{
require_auth
(
payer
);
eosio_assert
(
quant
.
amount
>
0
,
"must purchase a positive amount"
);
auto
fee
=
quant
;
fee
.
amount
=
(
fee
.
amount
+
199
)
/
200
;
/// .5% fee (round up)
// fee.amount cannot be 0 since that is only possible if quant.amount is 0 which is not allowed by the assert above.
// If quant.amount == 1, then fee.amount == 1,
// otherwise if quant.amount > 1, then 0 < fee.amount < quant.amount.
auto
quant_after_fee
=
quant
;
quant_after_fee
.
amount
-=
fee
.
amount
;
// quant_after_fee.amount should be > 0 if quant.amount > 1.
// If quant.amount == 1, then quant_after_fee.amount == 0 and the next inline transfer will fail causing the buyram action to fail.
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
payer
,
N
(
active
)},
{
payer
,
N
(
eosio
.
ram
),
quant_after_fee
,
std
::
string
(
"buy ram"
)
}
);
if
(
fee
.
amount
>
0
)
{
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
payer
,
N
(
active
)},
{
payer
,
N
(
eosio
.
ramfee
),
fee
,
std
::
string
(
"ram fee"
)
}
);
}
int64_t
bytes_out
;
const
auto
&
market
=
_rammarket
.
get
(
S
(
4
,
RAMCORE
),
"ram market does not exist"
);
_rammarket
.
modify
(
market
,
0
,
[
&
](
auto
&
es
)
{
bytes_out
=
es
.
convert
(
quant_after_fee
,
S
(
0
,
RAM
)
).
amount
;
});
eosio_assert
(
bytes_out
>
0
,
"must reserve a positive amount"
);
_gstate
.
total_ram_bytes_reserved
+=
uint64_t
(
bytes_out
);
_gstate
.
total_ram_stake
+=
quant_after_fee
.
amount
;
user_resources_table
userres
(
_self
,
receiver
);
auto
res_itr
=
userres
.
find
(
receiver
);
if
(
res_itr
==
userres
.
end
()
)
{
res_itr
=
userres
.
emplace
(
receiver
,
[
&
](
auto
&
res
)
{
res
.
owner
=
receiver
;
res
.
ram_bytes
=
bytes_out
;
});
}
else
{
userres
.
modify
(
res_itr
,
receiver
,
[
&
](
auto
&
res
)
{
res
.
ram_bytes
+=
bytes_out
;
});
}
set_resource_limits
(
res_itr
->
owner
,
res_itr
->
ram_bytes
,
res_itr
->
net_weight
.
amount
,
res_itr
->
cpu_weight
.
amount
);
}
/**
* The system contract now buys and sells RAM allocations at prevailing market prices.
* This may result in traders buying RAM today in anticipation of potential shortages
* tomorrow. Overall this will result in the market balancing the supply and demand
* for RAM over time.
*/
void
system_contract
::
sellram
(
account_name
account
,
int64_t
bytes
)
{
require_auth
(
account
);
eosio_assert
(
bytes
>
0
,
"cannot sell negative byte"
);
user_resources_table
userres
(
_self
,
account
);
auto
res_itr
=
userres
.
find
(
account
);
eosio_assert
(
res_itr
!=
userres
.
end
(),
"no resource row"
);
eosio_assert
(
res_itr
->
ram_bytes
>=
bytes
,
"insufficient quota"
);
asset
tokens_out
;
auto
itr
=
_rammarket
.
find
(
S
(
4
,
RAMCORE
));
_rammarket
.
modify
(
itr
,
0
,
[
&
](
auto
&
es
)
{
/// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases
tokens_out
=
es
.
convert
(
asset
(
bytes
,
S
(
0
,
RAM
)),
CORE_SYMBOL
);
});
eosio_assert
(
tokens_out
.
amount
>
1
,
"token amount received from selling ram is too low"
);
_gstate
.
total_ram_bytes_reserved
-=
static_cast
<
decltype
(
_gstate
.
total_ram_bytes_reserved
)
>
(
bytes
);
// bytes > 0 is asserted above
_gstate
.
total_ram_stake
-=
tokens_out
.
amount
;
//// this shouldn't happen, but just in case it does we should prevent it
eosio_assert
(
_gstate
.
total_ram_stake
>=
0
,
"error, attempt to unstake more tokens than previously staked"
);
userres
.
modify
(
res_itr
,
account
,
[
&
](
auto
&
res
)
{
res
.
ram_bytes
-=
bytes
;
});
set_resource_limits
(
res_itr
->
owner
,
res_itr
->
ram_bytes
,
res_itr
->
net_weight
.
amount
,
res_itr
->
cpu_weight
.
amount
);
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
.
ram
),
N
(
active
)},
{
N
(
eosio
.
ram
),
account
,
asset
(
tokens_out
),
std
::
string
(
"sell ram"
)
}
);
auto
fee
=
(
tokens_out
.
amount
+
199
)
/
200
;
/// .5% fee (round up)
// since tokens_out.amount was asserted to be at least 2 earlier, fee.amount < tokens_out.amount
if
(
fee
>
0
)
{
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
account
,
N
(
active
)},
{
account
,
N
(
eosio
.
ramfee
),
asset
(
fee
),
std
::
string
(
"sell ram fee"
)
}
);
}
}
void
validate_b1_vesting
(
int64_t
stake
)
{
const
int64_t
base_time
=
1527811200
;
/// 2018-06-01
const
int64_t
max_claimable
=
100'000'000'0000ll
;
const
int64_t
claimable
=
int64_t
(
max_claimable
*
double
(
now
()
-
base_time
)
/
(
10
*
seconds_per_year
)
);
eosio_assert
(
max_claimable
-
claimable
<=
stake
,
"b1 can only claim their tokens over 10 years"
);
}
void
system_contract
::
changebw
(
account_name
from
,
account_name
receiver
,
const
asset
stake_net_delta
,
const
asset
stake_cpu_delta
,
bool
transfer
)
{
require_auth
(
from
);
eosio_assert
(
stake_net_delta
!=
asset
(
0
)
||
stake_cpu_delta
!=
asset
(
0
),
"should stake non-zero amount"
);
eosio_assert
(
std
::
abs
(
(
stake_net_delta
+
stake_cpu_delta
).
amount
)
>=
std
::
max
(
std
::
abs
(
stake_net_delta
.
amount
),
std
::
abs
(
stake_cpu_delta
.
amount
)
),
"net and cpu deltas cannot be opposite signs"
);
account_name
source_stake_from
=
from
;
if
(
transfer
)
{
from
=
receiver
;
}
// update stake delegated from "from" to "receiver"
{
del_bandwidth_table
del_tbl
(
_self
,
from
);
auto
itr
=
del_tbl
.
find
(
receiver
);
if
(
itr
==
del_tbl
.
end
()
)
{
itr
=
del_tbl
.
emplace
(
from
,
[
&
](
auto
&
dbo
){
dbo
.
from
=
from
;
dbo
.
to
=
receiver
;
dbo
.
net_weight
=
stake_net_delta
;
dbo
.
cpu_weight
=
stake_cpu_delta
;
});
}
else
{
del_tbl
.
modify
(
itr
,
0
,
[
&
](
auto
&
dbo
){
dbo
.
net_weight
+=
stake_net_delta
;
dbo
.
cpu_weight
+=
stake_cpu_delta
;
});
}
eosio_assert
(
asset
(
0
)
<=
itr
->
net_weight
,
"insufficient staked net bandwidth"
);
eosio_assert
(
asset
(
0
)
<=
itr
->
cpu_weight
,
"insufficient staked cpu bandwidth"
);
if
(
itr
->
net_weight
==
asset
(
0
)
&&
itr
->
cpu_weight
==
asset
(
0
)
)
{
del_tbl
.
erase
(
itr
);
}
}
// itr can be invalid, should go out of scope
// update totals of "receiver"
{
user_resources_table
totals_tbl
(
_self
,
receiver
);
auto
tot_itr
=
totals_tbl
.
find
(
receiver
);
if
(
tot_itr
==
totals_tbl
.
end
()
)
{
tot_itr
=
totals_tbl
.
emplace
(
from
,
[
&
](
auto
&
tot
)
{
tot
.
owner
=
receiver
;
tot
.
net_weight
=
stake_net_delta
;
tot
.
cpu_weight
=
stake_cpu_delta
;
});
}
else
{
totals_tbl
.
modify
(
tot_itr
,
from
==
receiver
?
from
:
0
,
[
&
](
auto
&
tot
)
{
tot
.
net_weight
+=
stake_net_delta
;
tot
.
cpu_weight
+=
stake_cpu_delta
;
});
}
eosio_assert
(
asset
(
0
)
<=
tot_itr
->
net_weight
,
"insufficient staked total net bandwidth"
);
eosio_assert
(
asset
(
0
)
<=
tot_itr
->
cpu_weight
,
"insufficient staked total cpu bandwidth"
);
set_resource_limits
(
receiver
,
tot_itr
->
ram_bytes
,
tot_itr
->
net_weight
.
amount
,
tot_itr
->
cpu_weight
.
amount
);
if
(
tot_itr
->
net_weight
==
asset
(
0
)
&&
tot_itr
->
cpu_weight
==
asset
(
0
)
&&
tot_itr
->
ram_bytes
==
0
)
{
totals_tbl
.
erase
(
tot_itr
);
}
}
// tot_itr can be invalid, should go out of scope
// create refund or update from existing refund
if
(
N
(
eosio
.
stake
)
!=
source_stake_from
)
{
//for eosio both transfer and refund make no sense
refunds_table
refunds_tbl
(
_self
,
from
);
auto
req
=
refunds_tbl
.
find
(
from
);
//create/update/delete refund
auto
net_balance
=
stake_net_delta
;
auto
cpu_balance
=
stake_cpu_delta
;
bool
need_deferred_trx
=
false
;
// net and cpu are same sign by assertions in delegatebw and undelegatebw
// redundant assertion also at start of changebw to protect against misuse of changebw
bool
is_undelegating
=
(
net_balance
.
amount
+
cpu_balance
.
amount
)
<
0
;
bool
is_delegating_to_self
=
(
!
transfer
&&
from
==
receiver
);
if
(
is_delegating_to_self
||
is_undelegating
)
{
if
(
req
!=
refunds_tbl
.
end
()
)
{
//need to update refund
refunds_tbl
.
modify
(
req
,
0
,
[
&
](
refund_request
&
r
)
{
if
(
net_balance
<
asset
(
0
)
||
cpu_balance
<
asset
(
0
)
)
{
r
.
request_time
=
now
();
}
r
.
net_amount
-=
net_balance
;
if
(
r
.
net_amount
<
asset
(
0
)
)
{
net_balance
=
-
r
.
net_amount
;
r
.
net_amount
=
asset
(
0
);
}
else
{
net_balance
=
asset
(
0
);
}
r
.
cpu_amount
-=
cpu_balance
;
if
(
r
.
cpu_amount
<
asset
(
0
)
){
cpu_balance
=
-
r
.
cpu_amount
;
r
.
cpu_amount
=
asset
(
0
);
}
else
{
cpu_balance
=
asset
(
0
);
}
});
eosio_assert
(
asset
(
0
)
<=
req
->
net_amount
,
"negative net refund amount"
);
//should never happen
eosio_assert
(
asset
(
0
)
<=
req
->
cpu_amount
,
"negative cpu refund amount"
);
//should never happen
if
(
req
->
net_amount
==
asset
(
0
)
&&
req
->
cpu_amount
==
asset
(
0
)
)
{
refunds_tbl
.
erase
(
req
);
need_deferred_trx
=
false
;
}
else
{
need_deferred_trx
=
true
;
}
}
else
if
(
net_balance
<
asset
(
0
)
||
cpu_balance
<
asset
(
0
)
)
{
//need to create refund
refunds_tbl
.
emplace
(
from
,
[
&
](
refund_request
&
r
)
{
r
.
owner
=
from
;
if
(
net_balance
<
asset
(
0
)
)
{
r
.
net_amount
=
-
net_balance
;
net_balance
=
asset
(
0
);
}
// else r.net_amount = 0 by default constructor
if
(
cpu_balance
<
asset
(
0
)
)
{
r
.
cpu_amount
=
-
cpu_balance
;
cpu_balance
=
asset
(
0
);
}
// else r.cpu_amount = 0 by default constructor
r
.
request_time
=
now
();
});
need_deferred_trx
=
true
;
}
// else stake increase requested with no existing row in refunds_tbl -> nothing to do with refunds_tbl
}
/// end if is_delegating_to_self || is_undelegating
if
(
need_deferred_trx
)
{
eosio
::
transaction
out
;
out
.
actions
.
emplace_back
(
permission_level
{
from
,
N
(
active
)
},
_self
,
N
(
refund
),
from
);
out
.
delay_sec
=
refund_delay
;
cancel_deferred
(
from
);
// TODO: Remove this line when replacing deferred trxs is fixed
out
.
send
(
from
,
from
,
true
);
}
else
{
cancel_deferred
(
from
);
}
auto
transfer_amount
=
net_balance
+
cpu_balance
;
if
(
asset
(
0
)
<
transfer_amount
)
{
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
source_stake_from
,
N
(
active
)},
{
source_stake_from
,
N
(
eosio
.
stake
),
asset
(
transfer_amount
),
std
::
string
(
"stake bandwidth"
)
}
);
}
}
// update voting power
{
asset
total_update
=
stake_net_delta
+
stake_cpu_delta
;
auto
from_voter
=
_voters
.
find
(
from
);
if
(
from_voter
==
_voters
.
end
()
)
{
from_voter
=
_voters
.
emplace
(
from
,
[
&
](
auto
&
v
)
{
v
.
owner
=
from
;
v
.
staked
=
total_update
.
amount
;
});
}
else
{
_voters
.
modify
(
from_voter
,
0
,
[
&
](
auto
&
v
)
{
v
.
staked
+=
total_update
.
amount
;
});
}
eosio_assert
(
0
<=
from_voter
->
staked
,
"stake for voting cannot be negative"
);
if
(
from
==
N
(
b1
)
)
{
validate_b1_vesting
(
from_voter
->
staked
);
}
if
(
from_voter
->
producers
.
size
()
||
from_voter
->
proxy
)
{
update_votes
(
from
,
from_voter
->
proxy
,
from_voter
->
producers
,
false
);
}
}
}
void
system_contract
::
delegatebw
(
account_name
from
,
account_name
receiver
,
asset
stake_net_quantity
,
asset
stake_cpu_quantity
,
bool
transfer
)
{
eosio_assert
(
stake_cpu_quantity
>=
asset
(
0
),
"must stake a positive amount"
);
eosio_assert
(
stake_net_quantity
>=
asset
(
0
),
"must stake a positive amount"
);
eosio_assert
(
stake_net_quantity
+
stake_cpu_quantity
>
asset
(
0
),
"must stake a positive amount"
);
eosio_assert
(
!
transfer
||
from
!=
receiver
,
"cannot use transfer flag if delegating to self"
);
changebw
(
from
,
receiver
,
stake_net_quantity
,
stake_cpu_quantity
,
transfer
);
}
// delegatebw
void
system_contract
::
undelegatebw
(
account_name
from
,
account_name
receiver
,
asset
unstake_net_quantity
,
asset
unstake_cpu_quantity
)
{
eosio_assert
(
asset
()
<=
unstake_cpu_quantity
,
"must unstake a positive amount"
);
eosio_assert
(
asset
()
<=
unstake_net_quantity
,
"must unstake a positive amount"
);
eosio_assert
(
asset
()
<
unstake_cpu_quantity
+
unstake_net_quantity
,
"must unstake a positive amount"
);
eosio_assert
(
_gstate
.
total_activated_stake
>=
min_activated_stake
,
"cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)"
);
changebw
(
from
,
receiver
,
-
unstake_net_quantity
,
-
unstake_cpu_quantity
,
false
);
}
// undelegatebw
void
system_contract
::
refund
(
const
account_name
owner
)
{
require_auth
(
owner
);
refunds_table
refunds_tbl
(
_self
,
owner
);
auto
req
=
refunds_tbl
.
find
(
owner
);
eosio_assert
(
req
!=
refunds_tbl
.
end
(),
"refund request not found"
);
eosio_assert
(
req
->
request_time
+
refund_delay
<=
now
(),
"refund is not available yet"
);
// Until now() becomes NOW, the fact that now() is the timestamp of the previous block could in theory
// allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many
// consecutive missed blocks.
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
.
stake
),
N
(
active
)},
{
N
(
eosio
.
stake
),
req
->
owner
,
req
->
net_amount
+
req
->
cpu_amount
,
std
::
string
(
"unstake"
)
}
);
refunds_tbl
.
erase
(
req
);
}
}
//namespace eosiosystem
contracts/eosio.system_bak/eosio.system.abi
0 → 100644
浏览文件 @
58243806
{
"version": "eosio::abi/1.0",
"types": [{
"new_type_name": "account_name",
"type": "name"
},{
"new_type_name": "permission_name",
"type": "name"
},{
"new_type_name": "action_name",
"type": "name"
},{
"new_type_name": "transaction_id_type",
"type": "checksum256"
},{
"new_type_name": "weight_type",
"type": "uint16"
}],
"____comment": "eosio.bios structs: set_account_limits, setpriv, set_global_limits, producer_key, set_producers, require_auth are provided so abi available for deserialization in future.",
"structs": [{
"name": "permission_level",
"base": "",
"fields": [
{"name":"actor", "type":"account_name"},
{"name":"permission", "type":"permission_name"}
]
},{
"name": "key_weight",
"base": "",
"fields": [
{"name":"key", "type":"public_key"},
{"name":"weight", "type":"weight_type"}
]
},{
"name": "prod_meta",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"total_votes", "type":"float64"},
{"name":"producer_key", "type":"public_key"},
{"name":"all_stake", "type":"int64"},
{"name":"is_active", "type":"bool"},
{"name":"url", "type":"string"},
{"name":"location", "type":"uint16"}
]
},{
"name": "bidname",
"base": "",
"fields": [
{"name":"bidder", "type":"account_name"},
{"name":"newname", "type":"account_name"},
{"name":"bid", "type":"asset"}
]
},{
"name": "permission_level_weight",
"base": "",
"fields": [
{"name":"permission", "type":"permission_level"},
{"name":"weight", "type":"weight_type"}
]
},{
"name": "wait_weight",
"base": "",
"fields": [
{"name":"wait_sec", "type":"uint32"},
{"name":"weight", "type":"weight_type"}
]
},{
"name": "authority",
"base": "",
"fields": [
{"name":"threshold", "type":"uint32"},
{"name":"keys", "type":"key_weight[]"},
{"name":"accounts", "type":"permission_level_weight[]"},
{"name":"waits", "type":"wait_weight[]"}
]
},{
"name": "newaccount",
"base": "",
"fields": [
{"name":"creator", "type":"account_name"},
{"name":"name", "type":"account_name"},
{"name":"owner", "type":"authority"},
{"name":"active", "type":"authority"}
]
},{
"name": "setcode",
"base": "",
"fields": [
{"name":"account", "type":"account_name"},
{"name":"vmtype", "type":"uint8"},
{"name":"vmversion", "type":"uint8"},
{"name":"code", "type":"bytes"}
]
},{
"name": "setabi",
"base": "",
"fields": [
{"name":"account", "type":"account_name"},
{"name":"abi", "type":"bytes"}
]
},{
"name": "updateauth",
"base": "",
"fields": [
{"name":"account", "type":"account_name"},
{"name":"permission", "type":"permission_name"},
{"name":"parent", "type":"permission_name"},
{"name":"auth", "type":"authority"}
]
},{
"name": "deleteauth",
"base": "",
"fields": [
{"name":"account", "type":"account_name"},
{"name":"permission", "type":"permission_name"}
]
},{
"name": "linkauth",
"base": "",
"fields": [
{"name":"account", "type":"account_name"},
{"name":"code", "type":"account_name"},
{"name":"type", "type":"action_name"},
{"name":"requirement", "type":"permission_name"}
]
},{
"name": "unlinkauth",
"base": "",
"fields": [
{"name":"account", "type":"account_name"},
{"name":"code", "type":"account_name"},
{"name":"type", "type":"action_name"}
]
},{
"name": "canceldelay",
"base": "",
"fields": [
{"name":"canceling_auth", "type":"permission_level"},
{"name":"trx_id", "type":"transaction_id_type"}
]
},{
"name": "onerror",
"base": "",
"fields": [
{"name":"sender_id", "type":"uint128"},
{"name":"sent_trx", "type":"bytes"}
]
},{
"name": "buyrambytes",
"base": "",
"fields": [
{"name":"payer", "type":"account_name"},
{"name":"receiver", "type":"account_name"},
{"name":"bytes", "type":"uint32"}
]
},{
"name": "sellram",
"base": "",
"fields": [
{"name":"account", "type":"account_name"},
{"name":"bytes", "type":"uint64"}
]
},{
"name": "buyram",
"base": "",
"fields": [
{"name":"payer", "type":"account_name"},
{"name":"receiver", "type":"account_name"},
{"name":"quant", "type":"asset"}
]
},{
"name": "delegatebw",
"base": "",
"fields": [
{"name":"from", "type":"account_name"},
{"name":"receiver", "type":"account_name"},
{"name":"stake_net_quantity", "type":"asset"},
{"name":"stake_cpu_quantity", "type":"asset"},
{"name":"transfer", "type":"bool"}
]
},{
"name": "undelegatebw",
"base": "",
"fields": [
{"name":"from", "type":"account_name"},
{"name":"receiver", "type":"account_name"},
{"name":"unstake_net_quantity", "type":"asset"},
{"name":"unstake_cpu_quantity", "type":"asset"}
]
},{
"name": "refund",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"}
]
},{
"name": "delegated_bandwidth",
"base": "",
"fields": [
{"name":"from", "type":"account_name"},
{"name":"to", "type":"account_name"},
{"name":"net_weight", "type":"asset"},
{"name":"cpu_weight", "type":"asset"}
]
},{
"name": "user_resources",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"net_weight", "type":"asset"},
{"name":"cpu_weight", "type":"asset"},
{"name":"ram_bytes", "type":"uint64"}
]
},{
"name": "total_resources",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"net_weight", "type":"asset"},
{"name":"cpu_weight", "type":"asset"},
{"name":"ram_bytes", "type":"uint64"}
]
},{
"name": "refund_request",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"request_time", "type":"time_point_sec"},
{"name":"net_amount", "type":"asset"},
{"name":"cpu_amount", "type":"asset"}
]
},{
"name": "blockchain_parameters",
"base": "",
"fields": [
{"name":"max_block_net_usage", "type":"uint64"},
{"name":"target_block_net_usage_pct", "type":"uint32"},
{"name":"max_transaction_net_usage", "type":"uint32"},
{"name":"base_per_transaction_net_usage", "type":"uint32"},
{"name":"net_usage_leeway", "type":"uint32"},
{"name":"context_free_discount_net_usage_num", "type":"uint32"},
{"name":"context_free_discount_net_usage_den", "type":"uint32"},
{"name":"max_block_cpu_usage", "type":"uint32"},
{"name":"target_block_cpu_usage_pct", "type":"uint32"},
{"name":"max_transaction_cpu_usage", "type":"uint32"},
{"name":"min_transaction_cpu_usage", "type":"uint32"},
{"name":"max_transaction_lifetime", "type":"uint32"},
{"name":"deferred_trx_expiration_window", "type":"uint32"},
{"name":"max_transaction_delay", "type":"uint32"},
{"name":"max_inline_action_size", "type":"uint32"},
{"name":"max_inline_action_depth", "type":"uint16"},
{"name":"max_authority_depth", "type":"uint16"}
]
},{
"name": "eosio_global_state",
"base": "blockchain_parameters",
"fields": [
{"name":"max_ram_size", "type":"uint64"},
{"name":"total_ram_bytes_reserved", "type":"uint64"},
{"name":"total_ram_stake", "type":"int64"},
{"name":"last_producer_schedule_update", "type":"block_timestamp_type"},
{"name":"last_pervote_bucket_fill", "type":"uint64"},
{"name":"pervote_bucket", "type":"int64"},
{"name":"perblock_bucket", "type":"int64"},
{"name":"total_unpaid_blocks", "type":"uint32"},
{"name":"total_activated_stake", "type":"int64"},
{"name":"thresh_activated_stake_time", "type":"uint64"},
{"name":"last_producer_schedule_size", "type":"uint16"},
{"name":"total_producer_vote_weight", "type":"float64"},
{"name":"last_name_close", "type":"block_timestamp_type"}
]
},{
"name": "eosio_global_state2",
"base": "",
"fields": [
{"name":"perbase_bucket", "type":"int64"},
{"name":"total_unpaid_base_cnt", "type":"uint32"},
{"name":"last_claim_time", "type":"uint64"}
]
},{
"name": "eosio_global_count",
"base": "",
"fields": [
{"name":"total_accounts", "type":"uint64"}
]
},{
"name": "producer_info",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"total_votes", "type":"float64"},
{"name":"producer_key", "type":"public_key"},
{"name":"is_active", "type":"bool"},
{"name":"url", "type":"string"},
{"name":"unpaid_blocks", "type":"uint32"},
{"name":"last_claim_time", "type":"uint64"},
{"name":"location", "type":"uint16"}
]
},{
"name": "producer_info_ext",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"seq_num", "type":"uint16"},
{"name":"out_votes", "type":"int64"},
{"name":"unpaid_base_cnt", "type":"uint32"}
]
},{
"name": "producers_seq",
"base": "",
"fields": [
{"name":"seq_num", "type":"uint16"},
{"name":"is_org", "type":"bool"},
{"name":"prods_l1", "type":"prod_meta"},
{"name":"prods_l2", "type":"prod_meta[]"},
{"name":"prods_l3", "type":"prod_meta[]"},
{"name":"prods_all", "type":"prod_meta[]"},
]
},{
"name": "regproducer",
"base": "",
"fields": [
{"name":"producer", "type":"account_name"},
{"name":"producer_key", "type":"public_key"},
{"name":"url", "type":"string"},
{"name":"location", "type":"uint16"}
]
},{
"name": "unregprod",
"base": "",
"fields": [
{"name":"producer", "type":"account_name"}
]
},{
"name": "clsprods2",
"base": "",
"fields": []
},{
"name": "seqproducer",
"base": "",
"fields": [
{"name":"producer", "type":"account_name"},
{"name":"seq", "type":"uint16"},
{"name":"level", "type":"uint8"}
]
},{
"name": "testnewelec",
"base": "",
"fields": []
},{
"name": "tmpvotennn",
"base": "",
"fields": [
{"name":"producer", "type":"account_name"},
{"name":"tickets", "type":"int64"}
]
},{
"name": "setram",
"base": "",
"fields": [
{"name":"max_ram_size", "type":"uint64"}
]
},{
"name": "regproxy",
"base": "",
"fields": [
{"name":"proxy", "type":"account_name"},
{"name":"isproxy", "type":"bool"}
]
},{
"name": "voteproducer",
"base": "",
"fields": [
{"name":"voter", "type":"account_name"},
{"name":"proxy", "type":"account_name"},
{"name":"producers", "type":"account_name[]"}
]
},{
"name": "voter_info",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"proxy", "type":"account_name"},
{"name":"producers", "type":"account_name[]"},
{"name":"staked", "type":"int64"},
{"name":"last_vote_weight", "type":"float64"},
{"name":"proxied_vote_weight", "type":"float64"},
{"name":"is_proxy", "type":"bool"}
]
},{
"name": "claimrewards",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"}
]
},{
"name": "rewardprods",
"base": "",
"fields": []
},{
"name": "setpriv",
"base": "",
"fields": [
{"name":"account", "type":"account_name"},
{"name":"is_priv", "type":"int8"}
]
},{
"name": "rmvproducer",
"base": "",
"fields": [
{"name":"producer", "type":"account_name"}
]
},{
"name": "set_account_limits",
"base": "",
"fields": [
{"name":"account", "type":"account_name"},
{"name":"ram_bytes", "type":"int64"},
{"name":"net_weight", "type":"int64"},
{"name":"cpu_weight", "type":"int64"}
]
},{
"name": "set_global_limits",
"base": "",
"fields": [
{"name":"cpu_usec_per_period", "type":"int64"}
]
},{
"name": "producer_key",
"base": "",
"fields": [
{"name":"producer_name", "type":"account_name"},
{"name":"block_signing_key", "type":"public_key"}
]
},{
"name": "set_producers",
"base": "",
"fields": [
{"name":"schedule", "type":"producer_key[]"}
]
},{
"name": "require_auth",
"base": "",
"fields": [
{"name":"from", "type":"account_name"}
]
},{
"name": "setparams",
"base": "",
"fields": [
{"name":"params", "type":"blockchain_parameters"}
]
},{
"name": "connector",
"base": "",
"fields": [
{"name":"balance", "type":"asset"},
{"name":"weight", "type":"float64"}
]
},{
"name": "exchange_state",
"base": "",
"fields": [
{"name":"supply", "type":"asset"},
{"name":"base", "type":"connector"},
{"name":"quote", "type":"connector"}
]
}, {
"name": "namebid_info",
"base": "",
"fields": [
{"name":"newname", "type":"account_name"},
{"name":"high_bidder", "type":"account_name"},
{"name":"high_bid", "type":"int64"},
{"name":"last_bid_time", "type":"uint64"}
]
}
],
"actions": [{
"name": "newaccount",
"type": "newaccount",
"ricardian_contract": ""
},{
"name": "setcode",
"type": "setcode",
"ricardian_contract": ""
},{
"name": "setabi",
"type": "setabi",
"ricardian_contract": ""
},{
"name": "updateauth",
"type": "updateauth",
"ricardian_contract": ""
},{
"name": "deleteauth",
"type": "deleteauth",
"ricardian_contract": ""
},{
"name": "linkauth",
"type": "linkauth",
"ricardian_contract": ""
},{
"name": "unlinkauth",
"type": "unlinkauth",
"ricardian_contract": ""
},{
"name": "canceldelay",
"type": "canceldelay",
"ricardian_contract": ""
},{
"name": "onerror",
"type": "onerror",
"ricardian_contract": ""
},{
"name": "buyrambytes",
"type": "buyrambytes",
"ricardian_contract": ""
},{
"name": "buyram",
"type": "buyram",
"ricardian_contract": ""
},{
"name": "sellram",
"type": "sellram",
"ricardian_contract": ""
},{
"name": "delegatebw",
"type": "delegatebw",
"ricardian_contract": ""
},{
"name": "undelegatebw",
"type": "undelegatebw",
"ricardian_contract": ""
},{
"name": "refund",
"type": "refund",
"ricardian_contract": ""
},{
"name": "regproducer",
"type": "regproducer",
"ricardian_contract": ""
},{
"name": "setram",
"type": "setram",
"ricardian_contract": ""
},{
"name": "bidname",
"type": "bidname",
"ricardian_contract": ""
},{
"name": "unregprod",
"type": "unregprod",
"ricardian_contract": ""
},{
"name": "clsprods2",
"type": "clsprods2",
"ricardian_contract": ""
},{
"name": "seqproducer",
"type": "seqproducer",
"ricardian_contract": ""
},{
"name": "testnewelec",
"type": "testnewelec",
"ricardian_contract": ""
},{
"name": "tmpvotennn",
"type": "tmpvotennn",
"ricardian_contract": ""
},{
"name": "regproxy",
"type": "regproxy",
"ricardian_contract": ""
},{
"name": "voteproducer",
"type": "voteproducer",
"ricardian_contract": ""
},{
"name": "claimrewards",
"type": "claimrewards",
"ricardian_contract": ""
},{
"name": "rewardprods",
"type": "rewardprods",
"ricardian_contract": ""
},{
"name": "setpriv",
"type": "setpriv",
"ricardian_contract": ""
},{
"name": "rmvproducer",
"type": "rmvproducer",
"ricardian_contract": ""
},{
"name": "setalimits",
"type": "set_account_limits",
"ricardian_contract": ""
},{
"name": "setglimits",
"type": "set_global_limits",
"ricardian_contract": ""
},{
"name": "setprods",
"type": "set_producers",
"ricardian_contract": ""
},{
"name": "reqauth",
"type": "require_auth",
"ricardian_contract": ""
},{
"name": "setparams",
"type": "setparams",
"ricardian_contract": ""
}],
"tables": [{
"name": "producers",
"type": "producer_info",
"index_type": "i64",
"key_names" : ["owner"],
"key_types" : ["uint64"]
},{
"name": "producersext",
"type": "producer_info_ext",
"index_type": "i64",
"key_names" : ["owner"],
"key_types" : ["uint64"]
},{
"name": "producerseq",
"type": "producers_seq",
"index_type": "i64",
"key_names" : ["seq_num"],
"key_types" : ["uint64"]
},{
"name": "global",
"type": "eosio_global_state",
"index_type": "i64",
"key_names" : [],
"key_types" : []
},{
"name": "globalext",
"type": "eosio_global_state2",
"index_type": "i64",
"key_names" : [],
"key_types" : []
},{
"name": "gcount",
"type": "eosio_global_count",
"index_type": "i64",
"key_names" : [],
"key_types" : []
},{
"name": "voters",
"type": "voter_info",
"index_type": "i64",
"key_names" : ["owner"],
"key_types" : ["account_name"]
},{
"name": "userres",
"type": "user_resources",
"index_type": "i64",
"key_names" : ["owner"],
"key_types" : ["uint64"]
},{
"name": "delband",
"type": "delegated_bandwidth",
"index_type": "i64",
"key_names" : ["to"],
"key_types" : ["uint64"]
},{
"name": "rammarket",
"type": "exchange_state",
"index_type": "i64",
"key_names" : ["supply"],
"key_types" : ["uint64"]
},{
"name": "refunds",
"type": "refund_request",
"index_type": "i64",
"key_names" : ["owner"],
"key_types" : ["uint64"]
},{
"name": "namebids",
"type": "namebid_info",
"index_type": "i64",
"key_names" : ["newname"],
"key_types" : ["account_name"]
}
],
"ricardian_clauses": [],
"abi_extensions": []
}
contracts/eosio.system_bak/eosio.system.cpp
0 → 100644
浏览文件 @
58243806
#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
),
_producersext
(
_self
,
_self
),
_globalex
(
_self
,
_self
)
{
//print( "construct system\n" );
_gstate
=
_global
.
exists
()
?
_global
.
get
()
:
get_default_parameters
();
_gstateex
=
_globalex
.
exists
()
?
_globalex
.
get
()
:
eosio_global_state2
{};
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
);
_globalex
.
set
(
_gstateex
,
_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
();
});
change_producer_seq_info
(
producer
,
public_key
(),
false
,
false
,
""
);
}
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
(
newname
!=
0
,
"the empty name is not a valid account name to bid on"
);
eosio_assert
(
(
newname
&
0xFull
)
==
0
,
"13 character names are not valid account names to bid on"
);
eosio_assert
(
(
newname
&
0x1F0ull
)
==
0
,
"accounts with 12 character names and no dots can be created without bidding required"
);
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 authorities
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
);
//##YTA-Change start:
global_count_singleton
global
(
_self
,
_self
);
eosio_global_count
gstate
;
if
(
global
.
exists
())
{
gstate
=
global
.
get
();
}
gstate
.
total_accounts
+=
1
;
global
.
set
(
gstate
,
_self
);
//##YTA-Change end:
}
}
/// 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
)(
clsprods2
)(
seqproducer
)(
testnewelec
)
// producer_pay.cpp
(
onblock
)(
claimrewards
)(
rewardprods
)
)
contracts/eosio.system_bak/eosio.system.hpp
0 → 100644
浏览文件 @
58243806
/**
* @file
* @copyright defined in eos/LICENSE
*/
#pragma once
#include <eosio.system/native.hpp>
#include <eosiolib/asset.hpp>
#include <eosiolib/time.hpp>
#include <eosiolib/privileged.hpp>
#include <eosiolib/singleton.hpp>
#include <eosio.system/exchange_state.hpp>
#include <string>
namespace
eosiosystem
{
using
eosio
::
asset
;
using
eosio
::
indexed_by
;
using
eosio
::
const_mem_fun
;
using
eosio
::
block_timestamp
;
struct
name_bid
{
account_name
newname
;
account_name
high_bidder
;
int64_t
high_bid
=
0
;
///< negative high_bid == closed auction waiting to be claimed
uint64_t
last_bid_time
=
0
;
auto
primary_key
()
const
{
return
newname
;
}
uint64_t
by_high_bid
()
const
{
return
static_cast
<
uint64_t
>
(
-
high_bid
);
}
};
typedef
eosio
::
multi_index
<
N
(
namebids
),
name_bid
,
indexed_by
<
N
(
highbid
),
const_mem_fun
<
name_bid
,
uint64_t
,
&
name_bid
::
by_high_bid
>
>
>
name_bid_table
;
struct
eosio_global_state
:
eosio
::
blockchain_parameters
{
uint64_t
free_ram
()
const
{
return
max_ram_size
-
total_ram_bytes_reserved
;
}
uint64_t
max_ram_size
=
64ll
*
1024
*
1024
*
1024
;
uint64_t
total_ram_bytes_reserved
=
0
;
int64_t
total_ram_stake
=
0
;
block_timestamp
last_producer_schedule_update
;
uint64_t
last_pervote_bucket_fill
=
0
;
int64_t
pervote_bucket
=
0
;
int64_t
perblock_bucket
=
0
;
uint32_t
total_unpaid_blocks
=
0
;
/// all blocks which have been produced but not paid
int64_t
total_activated_stake
=
0
;
uint64_t
thresh_activated_stake_time
=
0
;
uint16_t
last_producer_schedule_size
=
0
;
double
total_producer_vote_weight
=
0
;
/// the sum of all producer votes
block_timestamp
last_name_close
;
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE_DERIVED
(
eosio_global_state
,
eosio
::
blockchain_parameters
,
(
max_ram_size
)(
total_ram_bytes_reserved
)(
total_ram_stake
)
(
last_producer_schedule_update
)(
last_pervote_bucket_fill
)
(
pervote_bucket
)(
perblock_bucket
)(
total_unpaid_blocks
)(
total_activated_stake
)(
thresh_activated_stake_time
)
(
last_producer_schedule_size
)(
total_producer_vote_weight
)(
last_name_close
)
)
};
//##YTA-Change start:
struct
eosio_global_state2
{
int64_t
perbase_bucket
=
0
;
uint32_t
total_unpaid_base_cnt
=
0
;
uint64_t
last_claim_time
=
0
;
EOSLIB_SERIALIZE
(
eosio_global_state2
,
(
perbase_bucket
)(
total_unpaid_base_cnt
)(
last_claim_time
))
};
struct
eosio_global_count
{
uint64_t
total_accounts
=
1
;
EOSLIB_SERIALIZE
(
eosio_global_count
,
(
total_accounts
)
)
};
//##YTA-Change end:
struct
producer_info
{
account_name
owner
;
double
total_votes
=
0
;
eosio
::
public_key
producer_key
;
/// a packed public key object
bool
is_active
=
true
;
std
::
string
url
;
uint32_t
unpaid_blocks
=
0
;
uint64_t
last_claim_time
=
0
;
uint16_t
location
=
0
;
uint64_t
primary_key
()
const
{
return
owner
;
}
double
by_votes
()
const
{
return
is_active
?
-
total_votes
:
total_votes
;
}
bool
active
()
const
{
return
is_active
;
}
void
deactivate
()
{
producer_key
=
public_key
();
is_active
=
false
;
}
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE
(
producer_info
,
(
owner
)(
total_votes
)(
producer_key
)(
is_active
)(
url
)
(
unpaid_blocks
)(
last_claim_time
)(
location
)
)
};
//##YTA-Change start:
struct
producer_info_ext
{
account_name
owner
;
uint16_t
seq_num
=
1
;
// from 1 to 21
int64_t
out_votes
=
0
;
uint32_t
unpaid_base_cnt
=
0
;
uint64_t
primary_key
()
const
{
return
owner
;
}
EOSLIB_SERIALIZE
(
producer_info_ext
,
(
owner
)(
seq_num
)(
out_votes
)(
unpaid_base_cnt
))
};
struct
prod_meta
{
account_name
owner
;
double
total_votes
=
0
;
// total votes
eosio
::
public_key
producer_key
;
/// a packed public key object
int64_t
all_stake
=
0
;
// total original votes (buy yta amount)
bool
is_active
=
true
;
std
::
string
url
;
uint16_t
location
=
0
;
EOSLIB_SERIALIZE
(
prod_meta
,
(
owner
)(
total_votes
)(
producer_key
)(
all_stake
)(
is_active
)(
url
)(
location
)
)
};
struct
producers_seq
{
uint16_t
seq_num
=
1
;
// from 1 to 21
bool
is_org
=
false
;
prod_meta
prods_l1
;
// only one
std
::
vector
<
prod_meta
>
prods_l2
;
//max 5
std
::
vector
<
prod_meta
>
prods_l3
;
std
::
vector
<
prod_meta
>
prods_all
;
uint64_t
primary_key
()
const
{
return
seq_num
;
}
EOSLIB_SERIALIZE
(
producers_seq
,
(
seq_num
)(
is_org
)(
prods_l1
)(
prods_l2
)(
prods_l3
)(
prods_all
)
)
};
//##YTA-Change end:
//##YTA-Change start:
struct
yta_prod_info
{
account_name
owner
;
double
total_votes
=
0
;
// total votes
eosio
::
public_key
producer_key
;
/// a packed public key object
int64_t
all_stake
=
0
;
// total original votes (buy yta amount)
bool
is_active
=
true
;
std
::
string
url
;
uint16_t
location
=
0
;
bool
is_in_grace
;
//是否处在补齐投票的宽限期
uint64_t
grace_start_time
=
0
;
//宽限期的开始时间
EOSLIB_SERIALIZE
(
yta_prod_info
,
(
owner
)(
total_votes
)(
producer_key
)(
all_stake
)(
is_active
)(
url
)(
location
)(
is_in_grace
)(
grace_start_time
)
)
};
struct
all_prods_level
{
std
::
vector
<
yta_prod_info
>
prods_l1
;
//max 21
std
::
vector
<
yta_prod_info
>
prods_l2
;
//max 105
std
::
vector
<
yta_prod_info
>
prods_l3
;
EOSLIB_SERIALIZE
(
all_prods_level
,
(
prods_l1
)(
prods_l2
)(
prods_l3
)
)
};
typedef
eosio
::
singleton
<
N
(
all_prods
),
all_prods_level
>
all_prods_singleton
;
//##YTA-Change end:
struct
voter_info
{
account_name
owner
=
0
;
/// the voter
account_name
proxy
=
0
;
/// the proxy set by the voter, if any
std
::
vector
<
account_name
>
producers
;
/// the producers approved by this voter if no proxy set
int64_t
staked
=
0
;
/**
* Every time a vote is cast we must first "undo" the last vote weight, before casting the
* new vote weight. Vote weight is calculated as:
*
* stated.amount * 2 ^ ( weeks_since_launch/weeks_per_year)
*/
double
last_vote_weight
=
0
;
/// the vote weight cast the last time the vote was updated
/**
* Total vote weight delegated to this voter.
*/
double
proxied_vote_weight
=
0
;
/// the total vote weight delegated to this voter as a proxy
bool
is_proxy
=
0
;
/// whether the voter is a proxy for others
uint32_t
reserved1
=
0
;
time
reserved2
=
0
;
eosio
::
asset
reserved3
;
uint64_t
primary_key
()
const
{
return
owner
;
}
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE
(
voter_info
,
(
owner
)(
proxy
)(
producers
)(
staked
)(
last_vote_weight
)(
proxied_vote_weight
)(
is_proxy
)(
reserved1
)(
reserved2
)(
reserved3
)
)
};
typedef
eosio
::
multi_index
<
N
(
voters
),
voter_info
>
voters_table
;
typedef
eosio
::
multi_index
<
N
(
producers
),
producer_info
,
indexed_by
<
N
(
prototalvote
),
const_mem_fun
<
producer_info
,
double
,
&
producer_info
::
by_votes
>
>
>
producers_table
;
//##YTA-Change start:
typedef
eosio
::
multi_index
<
N
(
producersext
),
producer_info_ext
>
producers_ext_table
;
typedef
eosio
::
multi_index
<
N
(
producerseq
),
producers_seq
>
producers_seq_table
;
//##YTA-Change end:
typedef
eosio
::
singleton
<
N
(
global
),
eosio_global_state
>
global_state_singleton
;
//##YTA-Change start:
typedef
eosio
::
singleton
<
N
(
globalext
),
eosio_global_state2
>
global_state2_singleton
;
typedef
eosio
::
singleton
<
N
(
gcount
),
eosio_global_count
>
global_count_singleton
;
//##YTA-Change end:
// static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation
static
constexpr
uint32_t
seconds_per_day
=
24
*
3600
;
static
constexpr
uint64_t
system_token_symbol
=
CORE_SYMBOL
;
class
system_contract
:
public
native
{
private:
voters_table
_voters
;
producers_table
_producers
;
global_state_singleton
_global
;
eosio_global_state
_gstate
;
rammarket
_rammarket
;
//##YTA-Change start:
producers_ext_table
_producersext
;
eosio_global_state2
_gstateex
;
global_state2_singleton
_globalex
;
//##YTA-Change end:
public:
system_contract
(
account_name
s
);
~
system_contract
();
// Actions:
void
onblock
(
block_timestamp
timestamp
,
account_name
producer
);
// const block_header& header ); /// only parse first 3 fields of block header
// functions defined in delegate_bandwidth.cpp
/**
* Stakes SYS from the balance of 'from' for the benfit of 'receiver'.
* If transfer == true, then 'receiver' can unstake to their account
* Else 'from' can unstake at any time.
*/
void
delegatebw
(
account_name
from
,
account_name
receiver
,
asset
stake_net_quantity
,
asset
stake_cpu_quantity
,
bool
transfer
);
/**
* Decreases the total tokens delegated by from to receiver and/or
* frees the memory associated with the delegation if there is nothing
* left to delegate.
*
* This will cause an immediate reduction in net/cpu bandwidth of the
* receiver.
*
* A transaction is scheduled to send the tokens back to 'from' after
* the staking period has passed. If existing transaction is scheduled, it
* will be canceled and a new transaction issued that has the combined
* undelegated amount.
*
* The 'from' account loses voting power as a result of this call and
* all producer tallies are updated.
*/
void
undelegatebw
(
account_name
from
,
account_name
receiver
,
asset
unstake_net_quantity
,
asset
unstake_cpu_quantity
);
/**
* Increases receiver's ram quota based upon current price and quantity of
* tokens provided. An inline transfer from receiver to system contract of
* tokens will be executed.
*/
void
buyram
(
account_name
buyer
,
account_name
receiver
,
asset
tokens
);
void
buyrambytes
(
account_name
buyer
,
account_name
receiver
,
uint32_t
bytes
);
/**
* Reduces quota my bytes and then performs an inline transfer of tokens
* to receiver based upon the average purchase price of the original quota.
*/
void
sellram
(
account_name
receiver
,
int64_t
bytes
);
/**
* This action is called after the delegation-period to claim all pending
* unstaked tokens belonging to owner
*/
void
refund
(
account_name
owner
);
// functions defined in voting.cpp
void
regproducer
(
const
account_name
producer
,
const
public_key
&
producer_key
,
const
std
::
string
&
url
,
uint16_t
location
);
void
unregprod
(
const
account_name
producer
);
//##YTA-Change start:
void
clsprods2
();
void
seqproducer
(
const
account_name
producer
,
uint16_t
seq
,
uint8_t
level
);
void
tmpvotennn
(
const
account_name
producer
,
int64_t
tickets
);
void
testnewelec
();
//##YTA-Change end:
void
setram
(
uint64_t
max_ram_size
);
void
voteproducer
(
const
account_name
voter
,
const
account_name
proxy
,
const
std
::
vector
<
account_name
>&
producers
);
void
regproxy
(
const
account_name
proxy
,
bool
isproxy
);
void
setparams
(
const
eosio
::
blockchain_parameters
&
params
);
// functions defined in producer_pay.cpp
void
claimrewards
(
const
account_name
&
owner
);
void
rewardprods
();
void
setpriv
(
account_name
account
,
uint8_t
ispriv
);
void
rmvproducer
(
account_name
producer
);
void
bidname
(
account_name
bidder
,
account_name
newname
,
asset
bid
);
private:
void
update_elected_producers
(
block_timestamp
timestamp
);
//##YTA-Change start:
void
update_elected_producers_yta2
(
block_timestamp
timestamp
);
void
update_elected_producers_yta
(
block_timestamp
timestamp
);
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
getProducerForSeq
(
uint64_t
seq_num
);
void
rm_producer_seq
(
const
account_name
producer
,
uint16_t
seq
);
void
add_producer_seq
(
const
account_name
producer
,
uint16_t
seq
,
uint8_t
level
);
void
change_producer_seq_info
(
const
account_name
producer
,
const
eosio
::
public_key
&
producer_key
,
bool
isactive
,
bool
seturl
,
const
std
::
string
&
url
);
void
update_producers_seq_totalvotes
(
uint16_t
seq_num
,
account_name
owner
,
double
total_votes
);
//##YTA-Change end:
// Implementation details:
//defind in delegate_bandwidth.cpp
void
changebw
(
account_name
from
,
account_name
receiver
,
asset
stake_net_quantity
,
asset
stake_cpu_quantity
,
bool
transfer
);
//defined in voting.hpp
static
eosio_global_state
get_default_parameters
();
void
update_votes
(
const
account_name
voter
,
const
account_name
proxy
,
const
std
::
vector
<
account_name
>&
producers
,
bool
voting
);
// defined in voting.cpp
void
propagate_weight_change
(
const
voter_info
&
voter
);
};
}
/// eosiosystem
contracts/eosio.system_bak/exchange_state.cpp
0 → 100644
浏览文件 @
58243806
#include <eosio.system/exchange_state.hpp>
namespace
eosiosystem
{
asset
exchange_state
::
convert_to_exchange
(
connector
&
c
,
asset
in
)
{
real_type
R
(
supply
.
amount
);
real_type
C
(
c
.
balance
.
amount
+
in
.
amount
);
real_type
F
(
c
.
weight
/
1000.0
);
real_type
T
(
in
.
amount
);
real_type
ONE
(
1.0
);
real_type
E
=
-
R
*
(
ONE
-
std
::
pow
(
ONE
+
T
/
C
,
F
)
);
//print( "E: ", E, "\n");
int64_t
issued
=
int64_t
(
E
);
supply
.
amount
+=
issued
;
c
.
balance
.
amount
+=
in
.
amount
;
return
asset
(
issued
,
supply
.
symbol
);
}
asset
exchange_state
::
convert_from_exchange
(
connector
&
c
,
asset
in
)
{
eosio_assert
(
in
.
symbol
==
supply
.
symbol
,
"unexpected asset symbol input"
);
real_type
R
(
supply
.
amount
-
in
.
amount
);
real_type
C
(
c
.
balance
.
amount
);
real_type
F
(
1000.0
/
c
.
weight
);
real_type
E
(
in
.
amount
);
real_type
ONE
(
1.0
);
// potentially more accurate:
// The functions std::expm1 and std::log1p are useful for financial calculations, for example,
// when calculating small daily interest rates: (1+x)n
// -1 can be expressed as std::expm1(n * std::log1p(x)).
// real_type T = C * std::expm1( F * std::log1p(E/R) );
real_type
T
=
C
*
(
std
::
pow
(
ONE
+
E
/
R
,
F
)
-
ONE
);
//print( "T: ", T, "\n");
int64_t
out
=
int64_t
(
T
);
supply
.
amount
-=
in
.
amount
;
c
.
balance
.
amount
-=
out
;
return
asset
(
out
,
c
.
balance
.
symbol
);
}
asset
exchange_state
::
convert
(
asset
from
,
symbol_type
to
)
{
auto
sell_symbol
=
from
.
symbol
;
auto
ex_symbol
=
supply
.
symbol
;
auto
base_symbol
=
base
.
balance
.
symbol
;
auto
quote_symbol
=
quote
.
balance
.
symbol
;
//print( "From: ", from, " TO ", asset( 0,to), "\n" );
//print( "base: ", base_symbol, "\n" );
//print( "quote: ", quote_symbol, "\n" );
//print( "ex: ", supply.symbol, "\n" );
if
(
sell_symbol
!=
ex_symbol
)
{
if
(
sell_symbol
==
base_symbol
)
{
from
=
convert_to_exchange
(
base
,
from
);
}
else
if
(
sell_symbol
==
quote_symbol
)
{
from
=
convert_to_exchange
(
quote
,
from
);
}
else
{
eosio_assert
(
false
,
"invalid sell"
);
}
}
else
{
if
(
to
==
base_symbol
)
{
from
=
convert_from_exchange
(
base
,
from
);
}
else
if
(
to
==
quote_symbol
)
{
from
=
convert_from_exchange
(
quote
,
from
);
}
else
{
eosio_assert
(
false
,
"invalid conversion"
);
}
}
if
(
to
!=
from
.
symbol
)
return
convert
(
from
,
to
);
return
from
;
}
}
/// namespace eosiosystem
contracts/eosio.system_bak/exchange_state.hpp
0 → 100644
浏览文件 @
58243806
#pragma once
#include <eosiolib/asset.hpp>
namespace
eosiosystem
{
using
eosio
::
asset
;
using
eosio
::
symbol_type
;
typedef
double
real_type
;
/**
* Uses Bancor math to create a 50/50 relay between two asset types. The state of the
* bancor exchange is entirely contained within this struct. There are no external
* side effects associated with using this API.
*/
struct
exchange_state
{
asset
supply
;
struct
connector
{
asset
balance
;
double
weight
=
.5
;
EOSLIB_SERIALIZE
(
connector
,
(
balance
)(
weight
)
)
};
connector
base
;
connector
quote
;
uint64_t
primary_key
()
const
{
return
supply
.
symbol
;
}
asset
convert_to_exchange
(
connector
&
c
,
asset
in
);
asset
convert_from_exchange
(
connector
&
c
,
asset
in
);
asset
convert
(
asset
from
,
symbol_type
to
);
EOSLIB_SERIALIZE
(
exchange_state
,
(
supply
)(
base
)(
quote
)
)
};
typedef
eosio
::
multi_index
<
N
(
rammarket
),
exchange_state
>
rammarket
;
}
/// namespace eosiosystem
contracts/eosio.system_bak/native.hpp
0 → 100644
浏览文件 @
58243806
/**
* @file
* @copyright defined in eos/LICENSE
*/
#pragma once
#include <eosiolib/action.hpp>
#include <eosiolib/public_key.hpp>
#include <eosiolib/types.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/privileged.h>
#include <eosiolib/optional.hpp>
#include <eosiolib/producer_schedule.hpp>
#include <eosiolib/contract.hpp>
namespace
eosiosystem
{
using
eosio
::
permission_level
;
using
eosio
::
public_key
;
typedef
std
::
vector
<
char
>
bytes
;
struct
permission_level_weight
{
permission_level
permission
;
weight_type
weight
;
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE
(
permission_level_weight
,
(
permission
)(
weight
)
)
};
struct
key_weight
{
public_key
key
;
weight_type
weight
;
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE
(
key_weight
,
(
key
)(
weight
)
)
};
struct
authority
{
uint32_t
threshold
;
uint32_t
delay_sec
;
std
::
vector
<
key_weight
>
keys
;
std
::
vector
<
permission_level_weight
>
accounts
;
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE
(
authority
,
(
threshold
)(
delay_sec
)(
keys
)(
accounts
)
)
};
struct
block_header
{
uint32_t
timestamp
;
account_name
producer
;
uint16_t
confirmed
=
0
;
block_id_type
previous
;
checksum256
transaction_mroot
;
checksum256
action_mroot
;
uint32_t
schedule_version
=
0
;
eosio
::
optional
<
eosio
::
producer_schedule
>
new_producers
;
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE
(
block_header
,
(
timestamp
)(
producer
)(
confirmed
)(
previous
)(
transaction_mroot
)(
action_mroot
)
(
schedule_version
)(
new_producers
))
};
/*
* Method parameters commented out to prevent generation of code that parses input data.
*/
class
native
:
public
eosio
::
contract
{
public:
using
eosio
::
contract
::
contract
;
/**
* Called after a new account is created. This code enforces resource-limits rules
* for new accounts as well as new account naming conventions.
*
* 1. accounts cannot contain '.' symbols which forces all acccounts to be 12
* characters long without '.' until a future account auction process is implemented
* which prevents name squatting.
*
* 2. new accounts must stake a minimal number of tokens (as set in system parameters)
* therefore, this method will execute an inline buyram from receiver for newacnt in
* an amount equal to the current new account creation fee.
*/
void
newaccount
(
account_name
creator
,
account_name
newact
/* no need to parse authorites
const authority& owner,
const authority& active*/
);
void
updateauth
(
/*account_name account,
permission_name permission,
permission_name parent,
const authority& data*/
)
{}
void
deleteauth
(
/*account_name account, permission_name permission*/
)
{}
void
linkauth
(
/*account_name account,
account_name code,
action_name type,
permission_name requirement*/
)
{}
void
unlinkauth
(
/*account_name account,
account_name code,
action_name type*/
)
{}
void
canceldelay
(
/*permission_level canceling_auth, transaction_id_type trx_id*/
)
{}
void
onerror
(
/*const bytes&*/
)
{}
};
}
contracts/eosio.system_bak/producer_pay.cpp
0 → 100644
浏览文件 @
58243806
#include "eosio.system.hpp"
#include <eosiolib/print.hpp>
#include <eosio.token/eosio.token.hpp>
namespace
eosiosystem
{
const
int64_t
min_pervote_daily_pay
=
100'0000
;
//##YTA-Change start:
//Change total vote rate from 15% to 1% for test network
//const int64_t min_activated_stake = 150'000'000'0000;
const
int64_t
min_activated_stake
=
5'000'0000
;
//##YTA-Change end:
const
uint32_t
blocks_per_year
=
52
*
7
*
24
*
2
*
3600
;
// half seconds per year
const
uint32_t
seconds_per_year
=
52
*
7
*
24
*
3600
;
const
uint32_t
blocks_per_day
=
2
*
24
*
3600
;
const
uint32_t
blocks_per_hour
=
2
*
3600
;
const
uint64_t
useconds_per_day
=
24
*
3600
*
uint64_t
(
1000000
);
const
uint64_t
useconds_per_year
=
seconds_per_year
*
1000000ll
;
const
int64_t
block_initial_timestamp
=
1551369600ll
;
// epoch year 2019.03.01 unix timestamp 1551369600s
//yta seo total= yta_seo_year[i] * YTA_SEO_BASE
const
uint32_t
YTA_SEO_BASE
=
10'0000
;
const
double
YTA_PRECISION
=
10000.0000
;
const
uint32_t
yta_seo_year
[
62
]
=
{
1000
,
900
,
800
,
700
,
600
,
600
,
500
,
500
,
400
,
400
,
300
,
300
,
200
,
200
,
200
,
100
,
100
,
100
,
90
,
90
,
90
,
80
,
80
,
80
,
70
,
70
,
70
,
70
,
60
,
60
,
60
,
60
,
50
,
50
,
50
,
50
,
50
,
40
,
40
,
40
,
40
,
40
,
30
,
30
,
30
,
30
,
30
,
20
,
20
,
20
,
20
,
20
,
10
,
10
,
10
,
10
,
10
,
9
,
9
,
9
,
9
,
9
};
void
system_contract
::
onblock
(
block_timestamp
timestamp
,
account_name
producer
)
{
using
namespace
eosio
;
require_auth
(
N
(
eosio
));
/** until activated stake crosses this threshold no new rewards are paid */
if
(
_gstate
.
total_activated_stake
<
min_activated_stake
)
return
;
if
(
_gstate
.
last_pervote_bucket_fill
==
0
)
/// start the presses
_gstate
.
last_pervote_bucket_fill
=
current_time
();
/**
* At startup the initial producer may not be one that is registered / elected
* and therefore there may be no producer object for them.
*/
auto
prod
=
_producers
.
find
(
producer
);
if
(
prod
!=
_producers
.
end
()
)
{
_gstate
.
total_unpaid_blocks
++
;
_producers
.
modify
(
prod
,
0
,
[
&
](
auto
&
p
)
{
p
.
unpaid_blocks
++
;
});
}
//##YTA-Change start:
if
(
timestamp
.
slot
-
_gstate
.
last_producer_schedule_update
.
slot
>
120
)
{
for
(
auto
it
=
_producersext
.
begin
();
it
!=
_producersext
.
end
();
it
++
)
{
_producersext
.
modify
(
it
,
0
,
[
&
](
auto
&
p
)
{
p
.
unpaid_base_cnt
++
;
});
_gstateex
.
total_unpaid_base_cnt
++
;
}
}
//##YTA-Change end:
//##YTA-Change start:
/// only update block producers once every minute, block_timestamp is in half seconds
//if( timestamp.slot - _gstate.last_producer_schedule_update.slot > 120 ) {
/// update block producers once every two minute due to election strategy is more complex than before
if
(
timestamp
.
slot
-
_gstate
.
last_producer_schedule_update
.
slot
>
120
)
{
//##YTA-Change end:
update_elected_producers
(
timestamp
);
//update_elected_producers_yta( timestamp );
if
(
(
timestamp
.
slot
-
_gstate
.
last_name_close
.
slot
)
>
blocks_per_day
)
{
name_bid_table
bids
(
_self
,
_self
);
auto
idx
=
bids
.
get_index
<
N
(
highbid
)
>
();
auto
highest
=
idx
.
begin
();
if
(
highest
!=
idx
.
end
()
&&
highest
->
high_bid
>
0
&&
highest
->
last_bid_time
<
(
current_time
()
-
useconds_per_day
)
&&
_gstate
.
thresh_activated_stake_time
>
0
&&
(
current_time
()
-
_gstate
.
thresh_activated_stake_time
)
>
14
*
useconds_per_day
)
{
_gstate
.
last_name_close
=
timestamp
;
idx
.
modify
(
highest
,
0
,
[
&
](
auto
&
b
){
b
.
high_bid
=
-
b
.
high_bid
;
});
}
}
}
}
using
namespace
eosio
;
void
system_contract
::
claimrewards
(
const
account_name
&
owner
)
{
require_auth
(
_self
);
//require_auth(owner);
//@@@@@@@@@@@@@@@@@@@@
const
auto
&
prod
=
_producers
.
get
(
owner
);
eosio_assert
(
prod
.
active
(),
"producer does not have an active key"
);
eosio_assert
(
_gstate
.
total_activated_stake
>=
min_activated_stake
,
"cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)"
);
auto
ct
=
current_time
();
eosio_assert
(
ct
-
prod
.
last_claim_time
>
useconds_per_day
,
"already claimed rewards within past day"
);
const
asset
token_supply
=
token
(
N
(
eosio
.
token
)).
get_supply
(
symbol_type
(
system_token_symbol
).
name
()
);
const
auto
usecs_since_last_fill
=
ct
-
_gstate
.
last_pervote_bucket_fill
;
print
(
"usecs_since_last_fill: "
,
usecs_since_last_fill
,
"
\n
"
);
print
(
"_gstate.last_pervote_bucket_fill: "
,
_gstate
.
last_pervote_bucket_fill
,
"
\n
"
);
print
(
"now(): "
,
now
(),
"
\n
"
);
int
idx_year
=
(
int
)((
now
()
-
block_initial_timestamp
)
/
seconds_per_year
);
auto
seo_token
=
yta_seo_year
[
idx_year
]
*
YTA_SEO_BASE
;
print
(
"idx_year: "
,
idx_year
,
"
\n
"
);
print
(
"yta_seo_year[idx_year]: "
,
yta_seo_year
[
idx_year
],
"
\n
"
);
print
(
"token_supply: "
,
token_supply
,
"
\n
"
);
print
(
"seo_token: "
,
seo_token
,
"
\n
"
);
if
(
usecs_since_last_fill
>
0
&&
_gstate
.
last_pervote_bucket_fill
>
0
)
{
auto
new_tokens
=
static_cast
<
int64_t
>
(
seo_token
*
YTA_PRECISION
*
double
(
usecs_since_last_fill
)
/
double
(
useconds_per_year
));
print
(
"new_token: "
,
new_tokens
,
"
\n
"
);
auto
to_per_base_pay
=
static_cast
<
int64_t
>
((
new_tokens
*
3
)
/
5
);
auto
to_producers
=
new_tokens
-
to_per_base_pay
;
auto
to_per_block_pay
=
to_producers
/
2
;
auto
to_per_vote_pay
=
to_producers
-
to_per_block_pay
;
INLINE_ACTION_SENDER
(
eosio
::
token
,
issue
)(
N
(
eosio
.
token
),
{{
N
(
eosio
),
N
(
active
)}},
{
N
(
eosio
),
asset
(
new_tokens
),
std
::
string
(
"issue tokens for producer pay"
)}
);
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
),
N
(
active
)},
{
N
(
eosio
),
N
(
hddbasefound
),
asset
(
to_per_base_pay
),
"fund per-base bucket"
}
);
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
),
N
(
active
)},
{
N
(
eosio
),
N
(
eosio
.
bpay
),
asset
(
to_per_block_pay
),
"fund per-block bucket"
}
);
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
),
N
(
active
)},
{
N
(
eosio
),
N
(
eosio
.
vpay
),
asset
(
to_per_vote_pay
),
"fund per-vote bucket"
}
);
_gstateex
.
perbase_bucket
+=
to_per_base_pay
;
_gstate
.
pervote_bucket
+=
to_per_vote_pay
;
_gstate
.
perblock_bucket
+=
to_per_block_pay
;
_gstate
.
last_pervote_bucket_fill
=
ct
;
}
const
auto
&
prodext
=
_producersext
.
get
(
owner
);
int64_t
producer_per_base_pay
=
0
;
if
(
_gstateex
.
total_unpaid_base_cnt
>
0
)
{
producer_per_base_pay
=
(
_gstateex
.
perbase_bucket
*
prodext
.
unpaid_base_cnt
)
/
_gstateex
.
total_unpaid_base_cnt
;
}
int64_t
producer_per_block_pay
=
0
;
if
(
_gstate
.
total_unpaid_blocks
>
0
)
{
producer_per_block_pay
=
(
_gstate
.
perblock_bucket
*
prod
.
unpaid_blocks
)
/
_gstate
.
total_unpaid_blocks
;
}
int64_t
producer_per_vote_pay
=
0
;
if
(
_gstate
.
total_producer_vote_weight
>
0
)
{
producer_per_vote_pay
=
int64_t
((
_gstate
.
pervote_bucket
*
prod
.
total_votes
)
/
_gstate
.
total_producer_vote_weight
);
}
if
(
producer_per_vote_pay
<
min_pervote_daily_pay
)
{
producer_per_vote_pay
=
0
;
}
_gstateex
.
perbase_bucket
-=
producer_per_base_pay
;
_gstate
.
pervote_bucket
-=
producer_per_vote_pay
;
_gstate
.
perblock_bucket
-=
producer_per_block_pay
;
_gstate
.
total_unpaid_blocks
-=
prod
.
unpaid_blocks
;
_gstateex
.
total_unpaid_base_cnt
-=
prodext
.
unpaid_base_cnt
;
_producers
.
modify
(
prod
,
0
,
[
&
](
auto
&
p
)
{
p
.
last_claim_time
=
ct
;
p
.
unpaid_blocks
=
0
;
});
_producersext
.
modify
(
prodext
,
0
,
[
&
](
auto
&
p
)
{
p
.
unpaid_base_cnt
=
0
;
});
if
(
producer_per_base_pay
>
0
)
{
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
hddbasefound
),
N
(
active
)},
{
N
(
hddbasefound
),
owner
,
asset
(
producer_per_base_pay
),
std
::
string
(
"producer base pay"
)
}
);
}
if
(
producer_per_block_pay
>
0
)
{
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
.
bpay
),
N
(
active
)},
{
N
(
eosio
.
bpay
),
owner
,
asset
(
producer_per_block_pay
),
std
::
string
(
"producer block pay"
)
}
);
}
if
(
producer_per_vote_pay
>
0
)
{
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
.
vpay
),
N
(
active
)},
{
N
(
eosio
.
vpay
),
owner
,
asset
(
producer_per_vote_pay
),
std
::
string
(
"producer vote pay"
)
}
);
}
}
void
system_contract
::
rewardprods
(
)
{
//require_auth(_self);
require_auth
(
N
(
ytarewardusr
));
auto
ct
=
current_time
();
//eosio_assert( ct - _gstateex.last_claim_time > useconds_per_day, "already claimed rewards within past day" );
_gstateex
.
last_claim_time
=
ct
;
const
auto
usecs_since_last_fill
=
ct
-
_gstate
.
last_pervote_bucket_fill
;
int
idx_year
=
(
int
)((
now
()
-
block_initial_timestamp
)
/
seconds_per_year
);
auto
seo_token
=
yta_seo_year
[
idx_year
]
*
YTA_SEO_BASE
;
if
(
usecs_since_last_fill
>
0
&&
_gstate
.
last_pervote_bucket_fill
>
0
)
{
auto
new_tokens
=
static_cast
<
int64_t
>
(
seo_token
*
YTA_PRECISION
*
double
(
usecs_since_last_fill
)
/
double
(
useconds_per_year
));
print
(
"new_token: "
,
new_tokens
,
"
\n
"
);
auto
to_per_base_pay
=
static_cast
<
int64_t
>
((
new_tokens
*
3
)
/
5
);
auto
to_producers
=
new_tokens
-
to_per_base_pay
;
auto
to_per_block_pay
=
to_producers
/
2
;
auto
to_per_vote_pay
=
to_producers
-
to_per_block_pay
;
INLINE_ACTION_SENDER
(
eosio
::
token
,
issue
)(
N
(
eosio
.
token
),
{{
N
(
eosio
),
N
(
active
)}},
{
N
(
eosio
),
asset
(
new_tokens
),
std
::
string
(
"issue tokens for producer pay"
)}
);
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
),
N
(
active
)},
{
N
(
eosio
),
N
(
hddbasefound
),
asset
(
to_per_base_pay
),
"fund per-base bucket"
}
);
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
),
N
(
active
)},
{
N
(
eosio
),
N
(
eosio
.
bpay
),
asset
(
to_per_block_pay
),
"fund per-block bucket"
}
);
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
),
N
(
active
)},
{
N
(
eosio
),
N
(
eosio
.
vpay
),
asset
(
to_per_vote_pay
),
"fund per-vote bucket"
}
);
_gstateex
.
perbase_bucket
+=
to_per_base_pay
;
_gstate
.
pervote_bucket
+=
to_per_vote_pay
;
_gstate
.
perblock_bucket
+=
to_per_block_pay
;
_gstate
.
last_pervote_bucket_fill
=
ct
;
}
int64_t
producer_total_base_pay
=
_gstateex
.
perbase_bucket
;
int64_t
producer_total_block_pay
=
_gstate
.
perblock_bucket
;
int64_t
producer_total_vote_pay
=
_gstate
.
pervote_bucket
;
print
(
"producer_total_base_pay -- "
,
producer_total_base_pay
,
"
\n
"
);
print
(
"producer_total_block_pay -- "
,
producer_total_block_pay
,
"
\n
"
);
print
(
"producer_total_vote_pay -- "
,
producer_total_vote_pay
,
"
\n
"
);
int64_t
producer_already_base_pay
=
0
;
int64_t
producer_already_block_pay
=
0
;
int64_t
producer_already_vote_pay
=
0
;
uint32_t
total_unpaid_blocks
=
_gstate
.
total_unpaid_blocks
;
uint32_t
total_unpaid_base_cnt
=
_gstateex
.
total_unpaid_base_cnt
;
for
(
auto
it
=
_producers
.
begin
();
it
!=
_producers
.
end
();
it
++
)
{
if
(
!
(
it
->
active
()))
continue
;
auto
&
prodex
=
_producersext
.
get
(
it
->
owner
);
int64_t
producer_per_base_pay
=
0
;
if
(
_gstateex
.
total_unpaid_base_cnt
>
0
)
{
producer_per_base_pay
=
(
_gstateex
.
perbase_bucket
*
prodex
.
unpaid_base_cnt
)
/
total_unpaid_base_cnt
;
}
int64_t
producer_per_block_pay
=
0
;
if
(
_gstate
.
total_unpaid_blocks
>
0
)
{
producer_per_block_pay
=
(
_gstate
.
perblock_bucket
*
it
->
unpaid_blocks
)
/
total_unpaid_blocks
;
}
int64_t
producer_per_vote_pay
=
0
;
if
(
_gstate
.
total_producer_vote_weight
>
0
)
{
producer_per_vote_pay
=
int64_t
((
_gstate
.
pervote_bucket
*
it
->
total_votes
)
/
_gstate
.
total_producer_vote_weight
);
}
print
(
"producer_per_base_pay -- "
,
producer_per_base_pay
,
"
\n
"
);
print
(
"producer_per_block_pay -- "
,
producer_per_block_pay
,
"
\n
"
);
print
(
"producer_per_vote_pay -- "
,
producer_per_vote_pay
,
"
\n
"
);
_gstate
.
total_unpaid_blocks
-=
it
->
unpaid_blocks
;
_gstateex
.
total_unpaid_base_cnt
-=
prodex
.
unpaid_base_cnt
;
_producers
.
modify
(
it
,
0
,
[
&
](
auto
&
p
)
{
p
.
last_claim_time
=
ct
;
p
.
unpaid_blocks
=
0
;
});
_producersext
.
modify
(
prodex
,
0
,
[
&
](
auto
&
p
)
{
p
.
unpaid_base_cnt
=
0
;
});
if
(
producer_per_base_pay
>
0
&&
((
producer_per_base_pay
+
producer_already_base_pay
)
<=
producer_total_base_pay
)
)
{
producer_already_base_pay
+=
producer_per_base_pay
;
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
hddbasefound
),
N
(
active
)},
{
N
(
hddbasefound
),
it
->
owner
,
asset
(
producer_per_base_pay
),
std
::
string
(
"producer base pay"
)
}
);
}
if
(
producer_per_block_pay
>
0
&&
((
producer_per_block_pay
+
producer_already_block_pay
)
<=
producer_total_block_pay
)
)
{
producer_already_block_pay
+=
producer_per_block_pay
;
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
.
bpay
),
N
(
active
)},
{
N
(
eosio
.
bpay
),
it
->
owner
,
asset
(
producer_per_block_pay
),
std
::
string
(
"producer block pay"
)
}
);
}
if
(
producer_per_vote_pay
>
0
&&
((
producer_per_vote_pay
+
producer_already_vote_pay
)
<=
producer_total_vote_pay
)
)
{
producer_already_vote_pay
+=
producer_per_vote_pay
;
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
.
vpay
),
N
(
active
)},
{
N
(
eosio
.
vpay
),
it
->
owner
,
asset
(
producer_per_vote_pay
),
std
::
string
(
"producer vote pay"
)
}
);
}
}
_gstateex
.
perbase_bucket
-=
producer_already_base_pay
;
_gstate
.
pervote_bucket
-=
producer_already_vote_pay
;
_gstate
.
perblock_bucket
-=
producer_already_block_pay
;
if
(
_gstateex
.
perbase_bucket
<
0
)
_gstateex
.
perbase_bucket
=
0
;
if
(
_gstate
.
pervote_bucket
<
0
)
_gstate
.
pervote_bucket
=
0
;
if
(
_gstate
.
perblock_bucket
<
0
)
_gstate
.
perblock_bucket
=
0
;
}
}
//namespace eosiosystem
contracts/eosio.system_bak/voting.cpp
0 → 100644
浏览文件 @
58243806
/**
* @file
* @copyright defined in eos/LICENSE
*/
#include "eosio.system.hpp"
#include <eosiolib/eosio.hpp>
#include <eosiolib/crypto.h>
#include <eosiolib/print.hpp>
#include <eosiolib/datastream.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/multi_index.hpp>
#include <eosiolib/privileged.hpp>
#include <eosiolib/singleton.hpp>
#include <eosiolib/transaction.hpp>
#include <eosio.token/eosio.token.hpp>
#include <algorithm>
#include <cmath>
namespace
eosiosystem
{
using
eosio
::
indexed_by
;
using
eosio
::
const_mem_fun
;
using
eosio
::
bytes
;
using
eosio
::
print
;
using
eosio
::
singleton
;
using
eosio
::
transaction
;
/**
* This method will create a producer_config and producer_info object for 'producer'
*
* @pre producer is not already registered
* @pre producer to register is an account
* @pre authority of producer to register
*
*/
void
system_contract
::
regproducer
(
const
account_name
producer
,
const
eosio
::
public_key
&
producer_key
,
const
std
::
string
&
url
,
uint16_t
location
)
{
eosio_assert
(
url
.
size
()
<
512
,
"url too long"
);
eosio_assert
(
producer_key
!=
eosio
::
public_key
(),
"public key should not be the default value"
);
/*
require_auth( producer );
auto prod = _producers.find( producer );
if ( prod != _producers.end() ) {
_producers.modify( prod, producer, [&]( producer_info& info ){
info.producer_key = producer_key;
info.is_active = true;
info.url = url;
info.location = location;
});
change_producer_seq_info(producer, producer_key, true, true, url);
} else {
_producers.emplace( producer, [&]( producer_info& info ){
info.owner = producer;
info.total_votes = 0;
info.producer_key = producer_key;
info.is_active = true;
info.url = url;
info.location = location;
});
}
*/
require_auth
(
_self
);
auto
prod
=
_producers
.
find
(
producer
);
if
(
prod
!=
_producers
.
end
()
)
{
_producers
.
modify
(
prod
,
_self
,
[
&
](
producer_info
&
info
){
info
.
producer_key
=
producer_key
;
info
.
is_active
=
true
;
info
.
url
=
url
;
info
.
location
=
location
;
});
change_producer_seq_info
(
producer
,
producer_key
,
true
,
true
,
url
);
}
else
{
_producers
.
emplace
(
_self
,
[
&
](
producer_info
&
info
){
info
.
owner
=
producer
;
info
.
total_votes
=
0
;
info
.
producer_key
=
producer_key
;
info
.
is_active
=
true
;
info
.
url
=
url
;
info
.
location
=
location
;
});
}
}
void
system_contract
::
unregprod
(
const
account_name
producer
)
{
require_auth
(
producer
);
///@@@@@@@@@@@@@@@@@@@@@
return
;
const
auto
&
prod
=
_producers
.
get
(
producer
,
"producer not found"
);
_producers
.
modify
(
prod
,
0
,
[
&
](
producer_info
&
info
){
info
.
deactivate
();
});
change_producer_seq_info
(
producer
,
public_key
(),
false
,
false
,
""
);
}
//##YTA-Change start:
void
system_contract
::
clsprods2
()
{
require_auth
(
_self
);
while
(
_producersext
.
begin
()
!=
_producersext
.
end
())
{
auto
it
=
_producersext
.
begin
();
//it->out_votes
const
auto
&
prod
=
_producers
.
get
(
it
->
owner
,
"producer not found"
);
_producers
.
modify
(
prod
,
0
,
[
&
](
producer_info
&
info
){
info
.
total_votes
-=
it
->
out_votes
;
});
_gstate
.
total_producer_vote_weight
-=
it
->
out_votes
;
_producersext
.
erase
(
_producersext
.
begin
());
}
for
(
uint16_t
seq
=
1
;
seq
<=
21
;
seq
++
)
{
producers_seq_table
_prod_seq
(
_self
,
seq
);
if
(
_prod_seq
.
begin
()
!=
_prod_seq
.
end
()
)
_prod_seq
.
erase
(
_prod_seq
.
begin
());
}
_gstateex
.
total_unpaid_base_cnt
=
0
;
}
void
system_contract
::
seqproducer
(
const
account_name
producer
,
uint16_t
seq
,
uint8_t
level
)
{
require_auth
(
_self
);
//const auto& prod = _producers.get( producer, "producer not found" );
auto
itp
=
_producers
.
find
(
producer
);
eosio_assert
(
itp
!=
_producers
.
end
()
,
"producer not found"
);
eosio_assert
(
seq
>=
1
&&
seq
<=
21
,
"invalidate seq number"
);
eosio_assert
(
level
>=
1
&&
level
<=
3
,
"invalidate level number"
);
//const auto& prod = _producers.get( producer, "producer not found" );
auto
it
=
_producersext
.
find
(
producer
);
if
(
it
==
_producersext
.
end
())
{
_producersext
.
emplace
(
_self
,
[
&
](
auto
&
row
)
{
row
.
owner
=
producer
;
row
.
seq_num
=
seq
;
});
add_producer_seq
(
producer
,
seq
,
level
);
}
else
{
uint16_t
old_seq
=
it
->
seq_num
;
_producersext
.
modify
(
it
,
_self
,
[
&
](
auto
&
row
)
{
row
.
seq_num
=
seq
;
});
rm_producer_seq
(
producer
,
old_seq
);
add_producer_seq
(
producer
,
seq
,
level
);
}
}
void
system_contract
::
rm_producer_seq
(
const
account_name
producer
,
uint16_t
seq
)
{
producers_seq_table
_prodseq
(
_self
,
seq
);
auto
ps_itr
=
_prodseq
.
find
(
seq
);
if
(
ps_itr
==
_prodseq
.
end
()
)
return
;
_prodseq
.
modify
(
ps_itr
,
_self
,
[
&
](
producers_seq
&
info
){
if
(
info
.
prods_l1
.
owner
==
producer
)
{
info
.
prods_l1
.
owner
=
0
;
info
.
prods_l1
.
producer_key
=
public_key
();
info
.
prods_l1
.
all_stake
=
0
;
info
.
prods_l1
.
total_votes
=
0
;
info
.
prods_l1
.
is_active
=
false
;
info
.
prods_l1
.
url
=
""
;
info
.
is_org
=
false
;
}
for
(
auto
it2
=
info
.
prods_l2
.
begin
();
it2
!=
info
.
prods_l2
.
end
();
it2
++
)
{
if
(
it2
->
owner
==
producer
)
{
info
.
prods_l2
.
erase
(
it2
);
break
;
}
}
for
(
auto
it3
=
info
.
prods_l3
.
begin
();
it3
!=
info
.
prods_l3
.
end
();
it3
++
)
{
if
(
it3
->
owner
==
producer
)
{
info
.
prods_l3
.
erase
(
it3
);
break
;
}
}
for
(
auto
itall
=
info
.
prods_all
.
begin
();
itall
!=
info
.
prods_all
.
end
();
itall
++
)
{
if
(
itall
->
owner
==
producer
)
{
info
.
prods_all
.
erase
(
itall
);
break
;
}
}
});
}
void
system_contract
::
add_producer_seq
(
const
account_name
producer
,
uint16_t
seq
,
uint8_t
level
)
{
producers_seq_table
_prodseq
(
_self
,
seq
);
prod_meta
prodm
;
//need retrive from system producers table
const
auto
&
prod
=
_producers
.
get
(
producer
,
"producer not found"
);
prodm
.
owner
=
producer
;
prodm
.
producer_key
=
prod
.
producer_key
;
prodm
.
all_stake
=
(
int64_t
)
prod
.
total_votes
;
prodm
.
total_votes
=
prod
.
total_votes
;
prodm
.
is_active
=
prod
.
is_active
;
prodm
.
url
=
prod
.
url
;
auto
ps_itr
=
_prodseq
.
find
(
seq
);
if
(
ps_itr
==
_prodseq
.
end
()
)
{
_prodseq
.
emplace
(
_self
,
[
&
](
auto
&
row
)
{
row
.
seq_num
=
seq
;
if
(
level
==
1
)
row
.
is_org
=
true
;
row
.
prods_all
.
push_back
(
prodm
);
if
(
level
==
1
)
{
row
.
prods_l1
=
prodm
;
}
else
if
(
level
==
2
)
{
row
.
prods_l2
.
push_back
(
prodm
);
}
else
if
(
level
==
3
)
{
row
.
prods_l3
.
push_back
(
prodm
);
}
});
}
else
{
_prodseq
.
modify
(
ps_itr
,
_self
,
[
&
](
auto
&
row
)
{
if
(
level
==
1
)
row
.
is_org
=
true
;
row
.
prods_all
.
push_back
(
prodm
);
if
(
level
==
1
)
{
row
.
prods_l1
=
prodm
;
}
else
if
(
level
==
2
)
{
row
.
prods_l2
.
push_back
(
prodm
);
}
else
if
(
level
==
3
)
{
row
.
prods_l3
.
push_back
(
prodm
);
}
});
}
}
void
system_contract
::
change_producer_seq_info
(
const
account_name
producer
,
const
eosio
::
public_key
&
producer_key
,
bool
isactive
,
bool
seturl
,
const
std
::
string
&
url
)
{
auto
it
=
_producersext
.
find
(
producer
);
if
(
it
==
_producersext
.
end
())
return
;
uint16_t
seq
=
it
->
seq_num
;
producers_seq_table
_prodseq
(
_self
,
seq
);
auto
ps_itr
=
_prodseq
.
find
(
seq
);
if
(
ps_itr
==
_prodseq
.
end
()
)
return
;
_prodseq
.
modify
(
ps_itr
,
_self
,
[
&
](
producers_seq
&
info
){
if
(
info
.
prods_l1
.
owner
==
producer
)
{
info
.
prods_l1
.
is_active
=
isactive
;
info
.
prods_l1
.
producer_key
=
producer_key
;
if
(
seturl
)
info
.
prods_l1
.
url
=
url
;
}
for
(
auto
it2
=
info
.
prods_l2
.
begin
();
it2
!=
info
.
prods_l2
.
end
();
it2
++
)
{
if
(
it2
->
owner
==
producer
)
{
it2
->
is_active
=
isactive
;
it2
->
producer_key
=
producer_key
;
if
(
seturl
)
it2
->
url
=
url
;
break
;
}
}
for
(
auto
it3
=
info
.
prods_l3
.
begin
();
it3
!=
info
.
prods_l3
.
end
();
it3
++
)
{
if
(
it3
->
owner
==
producer
)
{
it3
->
is_active
=
isactive
;
it3
->
producer_key
=
producer_key
;
if
(
seturl
)
it3
->
url
=
url
;
break
;
}
}
for
(
auto
itall
=
info
.
prods_all
.
begin
();
itall
!=
info
.
prods_all
.
end
();
itall
++
)
{
if
(
itall
->
owner
==
producer
)
{
itall
->
is_active
=
isactive
;
itall
->
producer_key
=
producer_key
;
if
(
seturl
)
itall
->
url
=
url
;
break
;
}
}
});
}
void
system_contract
::
update_producers_seq_totalvotes
(
uint16_t
seq_num
,
account_name
owner
,
double
total_votes
)
{
producers_seq_table
_prodseq
(
_self
,
seq_num
);
auto
ps_itr
=
_prodseq
.
find
(
seq_num
);
if
(
ps_itr
==
_prodseq
.
end
()
)
return
;
_prodseq
.
modify
(
ps_itr
,
_self
,
[
&
](
producers_seq
&
info
){
if
(
info
.
prods_l1
.
owner
==
owner
)
{
info
.
prods_l1
.
total_votes
=
total_votes
;
info
.
prods_l1
.
all_stake
=
(
int64_t
)
total_votes
;
//return;
}
for
(
auto
it
=
info
.
prods_l2
.
begin
();
it
!=
info
.
prods_l2
.
end
();
it
++
)
{
if
(
it
->
owner
==
owner
)
{
it
->
total_votes
=
total_votes
;
it
->
all_stake
=
(
int64_t
)
total_votes
;
break
;
}
}
for
(
auto
it
=
info
.
prods_l3
.
begin
();
it
!=
info
.
prods_l3
.
end
();
it
++
)
{
if
(
it
->
owner
==
owner
)
{
it
->
total_votes
=
total_votes
;
it
->
all_stake
=
(
int64_t
)
total_votes
;
break
;
}
}
for
(
auto
it
=
info
.
prods_all
.
begin
();
it
!=
info
.
prods_all
.
end
();
it
++
)
{
if
(
it
->
owner
==
owner
)
{
it
->
total_votes
=
total_votes
;
it
->
all_stake
=
(
int64_t
)
total_votes
;
break
;
}
}
});
}
void
system_contract
::
testnewelec
()
{
require_auth
(
_self
);
block_timestamp
block_time
;
update_elected_producers_yta2
(
block_time
);
/*
std::vector< std::pair<eosio::producer_key,uint16_t> > top_producers;
top_producers.reserve(21);
for( uint16_t seq_num = 1; seq_num <= 21 ; seq_num++ ) {
std::pair<eosio::producer_key,uint16_t> ppinfo = getProducerForSeq( seq_num );
if( ppinfo.first.producer_name != 0 ) {
top_producers.emplace_back( ppinfo );
}
}
if ( top_producers.size() < _gstate.last_producer_schedule_size ) {
return;
}
/// sort by producer name
std::sort( top_producers.begin(), top_producers.end() );
std::vector<eosio::producer_key> producers;
producers.reserve(top_producers.size());
for( const auto& item : top_producers )
producers.push_back(item.first);
print("producers start------------------------------\n");
for( const auto& item : producers ) {
print("producer -", (name{item.producer_name}), "--");
//std::string str(std::begin(item.block_signing_key.data), std::end(item.block_signing_key.data));
//for(size_t i=0; i<33; i++) {
// char c = item.block_signing_key.data[i];
// printf("%c",c);
//}
//print(str);
print("\n");
}
print("producers end------------------------------\n");
*/
}
void
system_contract
::
tmpvotennn
(
const
account_name
producer
,
int64_t
tickets
)
{
require_auth
(
_self
);
const
auto
&
prod
=
_producers
.
get
(
producer
,
"producer not found"
);
//auto it = _producers.find(producer);
//eosio_assert( it != _producers.end() , "producer not found");
int64_t
vote_delta
=
0
;
_producers
.
modify
(
prod
,
0
,
[
&
](
producer_info
&
info
){
auto
pitr2
=
_producersext
.
find
(
producer
);
if
(
pitr2
!=
_producersext
.
end
()
)
{
vote_delta
=
tickets
-
pitr2
->
out_votes
;
info
.
total_votes
+=
vote_delta
;
_producersext
.
modify
(
pitr2
,
0
,
[
&
](
producer_info_ext
&
info2
){
info2
.
out_votes
=
tickets
;
});
update_producers_seq_totalvotes
(
pitr2
->
seq_num
,
producer
,
info
.
total_votes
);
}
});
_gstate
.
total_producer_vote_weight
+=
vote_delta
;
}
const
uint64_t
useconds_per_day_v
=
24
*
3600
*
uint64_t
(
1000000
);
void
system_contract
::
update_elected_producers_yta2
(
block_timestamp
block_time
)
{
all_prods_singleton
_all_prods
(
_self
,
_self
);
all_prods_level
_all_prods_state
;
if
(
!
_all_prods
.
exists
())
return
;
_all_prods_state
=
_all_prods
.
get
();
/*
for(int i = 0 ; i < 3 ; i++) {
yta_prod_info info;
info.total_votes = 50000000000;
info.all_stake = 50000000000;
info.is_active = true;
info.is_in_grace = false;
_all_prods_state.prods_l1.push_back(info);
}
_all_prods_state.prods_l1[0].owner = N(producer1);
_all_prods_state.prods_l1[0].is_active = false;
_all_prods_state.prods_l1[1].owner = N(producer2);
_all_prods_state.prods_l1[1].is_in_grace = true;
_all_prods_state.prods_l1[1].total_votes = 10000000000;
_all_prods_state.prods_l1[2].owner = N(producer3);
for(int i = 0 ; i < 6 ; i++) {
yta_prod_info info;
info.total_votes = 20000000000;
info.all_stake = 20000000000;
info.is_active = true;
info.is_in_grace = false;
_all_prods_state.prods_l2.push_back(info);
}
_all_prods_state.prods_l2[0].owner = N(producer11);
_all_prods_state.prods_l2[1].owner = N(producer12);
_all_prods_state.prods_l2[2].owner = N(producer13);
_all_prods_state.prods_l2[3].owner = N(producer14);
_all_prods_state.prods_l2[3].is_in_grace = true;
_all_prods_state.prods_l2[3].total_votes = 15000000000;
_all_prods_state.prods_l2[4].owner = N(producer15);
_all_prods_state.prods_l2[5].owner = N(producer1a);
for(int i = 0 ; i < 2 ; i++) {
yta_prod_info info;
info.total_votes = 10000000000;
info.all_stake = 10000000000;
info.is_active = true;
info.is_in_grace = false;
_all_prods_state.prods_l3.push_back(info);
}
_all_prods_state.prods_l3[0].owner = N(producer21);
_all_prods_state.prods_l3[0].total_votes = 21000000000;
_all_prods_state.prods_l3[1].owner = N(producer22);
print("before-----------------------------------\n");
print("level 1-----------------------------------\n");
for( auto it =_all_prods_state.prods_l1.begin(); it != _all_prods_state.prods_l1.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 2-----------------------------------\n");
for( auto it =_all_prods_state.prods_l2.begin(); it != _all_prods_state.prods_l2.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 3-----------------------------------\n");
for( auto it =_all_prods_state.prods_l3.begin(); it != _all_prods_state.prods_l3.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 1 again-----------------------------------\n");
for( auto it =_all_prods_state.prods_l1.begin(); it != _all_prods_state.prods_l1.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
*/
for
(
auto
it
=
_all_prods_state
.
prods_l1
.
begin
();
it
!=
_all_prods_state
.
prods_l1
.
end
();)
{
bool
is_remove
=
false
;
if
(
!
it
->
is_active
)
is_remove
=
true
;
//print("-----level1 down--", (name{it->owner}), "---",(int64_t)it->total_votes ,"\n");
if
((
int64_t
)
it
->
total_votes
<
50000000000
)
{
//print("-----level1 down--", (name{it->owner}), "votes not enough\n");
if
(
it
->
is_in_grace
)
{
if
(
current_time
()
-
it
->
grace_start_time
>
useconds_per_day_v
)
{
is_remove
=
true
;
it
->
is_in_grace
=
false
;
}
}
else
{
it
->
is_in_grace
=
true
;
auto
ct
=
current_time
();
it
->
grace_start_time
=
ct
;
}
}
else
{
it
->
is_in_grace
=
false
;
}
if
(
is_remove
)
{
_all_prods_state
.
prods_l3
.
push_back
(
*
it
);
it
=
_all_prods_state
.
prods_l1
.
erase
(
it
);
}
else
{
++
it
;
}
}
/*
print("step 1-----------------------------------\n");
print("level 1-----------------------------------\n");
for( auto it =_all_prods_state.prods_l1.begin(); it != _all_prods_state.prods_l1.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 2-----------------------------------\n");
for( auto it =_all_prods_state.prods_l2.begin(); it != _all_prods_state.prods_l2.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 3-----------------------------------\n");
for( auto it =_all_prods_state.prods_l3.begin(); it != _all_prods_state.prods_l3.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
*/
for
(
auto
it
=
_all_prods_state
.
prods_l2
.
begin
();
it
!=
_all_prods_state
.
prods_l2
.
end
();)
{
bool
is_remove
=
false
;
if
(
!
it
->
is_active
)
is_remove
=
true
;
//print("-----level2 down--", (name{it->owner}), "---",(int64_t)it->total_votes ,"\n");
if
((
int64_t
)
it
->
total_votes
<
20000000000
)
{
//print("-----level2 down--", (name{it->owner}), "votes not enough\n");
if
(
it
->
is_in_grace
)
{
if
(
current_time
()
-
it
->
grace_start_time
>
useconds_per_day_v
)
{
is_remove
=
true
;
it
->
is_in_grace
=
false
;
}
}
else
{
it
->
is_in_grace
=
true
;
auto
ct
=
current_time
();
it
->
grace_start_time
=
ct
;
}
}
else
{
it
->
is_in_grace
=
false
;
}
if
(
is_remove
)
{
_all_prods_state
.
prods_l3
.
push_back
(
*
it
);
it
=
_all_prods_state
.
prods_l2
.
erase
(
it
);
}
else
{
++
it
;
}
}
/*
print("step 2-----------------------------------\n");
for( auto it =_all_prods_state.prods_l1.begin(); it != _all_prods_state.prods_l1.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 2-----------------------------------\n");
for( auto it =_all_prods_state.prods_l2.begin(); it != _all_prods_state.prods_l2.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 3-----------------------------------\n");
for( auto it =_all_prods_state.prods_l3.begin(); it != _all_prods_state.prods_l3.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
*/
std
::
sort
(
_all_prods_state
.
prods_l2
.
begin
(),
_all_prods_state
.
prods_l2
.
end
(),
[
&
](
yta_prod_info
lhs
,
yta_prod_info
rhs
){
return
lhs
.
total_votes
>
rhs
.
total_votes
;});
for
(
auto
it
=
_all_prods_state
.
prods_l2
.
begin
();
it
!=
_all_prods_state
.
prods_l2
.
end
();)
{
//print("-----level2 up--", (name{it->owner}), "---",(int64_t)it->total_votes ,"\n");
if
((
int64_t
)
it
->
total_votes
>=
50000000000
)
{
//print("-----level2 up--", (name{it->owner}), "votes execeed\n");
if
(
_all_prods_state
.
prods_l1
.
size
()
<
21
)
{
_all_prods_state
.
prods_l1
.
push_back
(
*
it
);
it
=
_all_prods_state
.
prods_l2
.
erase
(
it
);
}
else
{
break
;
}
}
else
{
++
it
;
}
}
/*
print("step 3-----------------------------------\n");
for( auto it =_all_prods_state.prods_l1.begin(); it != _all_prods_state.prods_l1.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 2-----------------------------------\n");
for( auto it =_all_prods_state.prods_l2.begin(); it != _all_prods_state.prods_l2.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 3-----------------------------------\n");
for( auto it =_all_prods_state.prods_l3.begin(); it != _all_prods_state.prods_l3.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
*/
std
::
sort
(
_all_prods_state
.
prods_l3
.
begin
(),
_all_prods_state
.
prods_l3
.
end
(),
[
&
](
yta_prod_info
lhs
,
yta_prod_info
rhs
){
return
lhs
.
total_votes
>
rhs
.
total_votes
;});
for
(
auto
it
=
_all_prods_state
.
prods_l3
.
begin
();
it
!=
_all_prods_state
.
prods_l3
.
end
();)
{
//print("-----level3 up--", (name{it->owner}), "---",(int64_t)it->total_votes ,"\n");
if
((
int64_t
)
it
->
total_votes
>=
20000000000
&&
it
->
is_active
)
{
//print("-----level3 up--", (name{it->owner}), "votes execeed\n");
if
(
_all_prods_state
.
prods_l2
.
size
()
<
105
)
{
_all_prods_state
.
prods_l2
.
push_back
(
*
it
);
it
=
_all_prods_state
.
prods_l3
.
erase
(
it
);
}
else
{
break
;
}
}
else
{
++
it
;
}
}
_all_prods
.
set
(
_all_prods_state
,
_self
);
/*
print("after-----------------------------------\n");
for( auto it =_all_prods_state.prods_l1.begin(); it != _all_prods_state.prods_l1.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 2-----------------------------------\n");
for( auto it =_all_prods_state.prods_l2.begin(); it != _all_prods_state.prods_l2.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
print("level 3-----------------------------------\n");
for( auto it =_all_prods_state.prods_l3.begin(); it != _all_prods_state.prods_l3.end(); it++ ) {
print("producer - ", (name{it->owner}), "--", (int64_t)it->total_votes, " --\n");
}
return;
*/
///---------------------------------------------------
_gstate
.
last_producer_schedule_update
=
block_time
;
std
::
vector
<
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
>
top_producers
;
top_producers
.
reserve
(
21
);
for
(
auto
it
=
_all_prods_state
.
prods_l1
.
begin
();
it
!=
_all_prods_state
.
prods_l1
.
end
();
it
++
)
{
top_producers
.
emplace_back
(
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
({{
it
->
owner
,
it
->
producer_key
},
it
->
location
})
);
}
if
(
top_producers
.
size
()
<
_gstate
.
last_producer_schedule_size
)
{
if
(
top_producers
.
size
()
<
7
)
return
;
}
/// sort by producer name
std
::
sort
(
top_producers
.
begin
(),
top_producers
.
end
()
);
std
::
vector
<
eosio
::
producer_key
>
producers
;
producers
.
reserve
(
top_producers
.
size
());
for
(
const
auto
&
item
:
top_producers
)
producers
.
push_back
(
item
.
first
);
bytes
packed_schedule
=
pack
(
producers
);
if
(
set_proposed_producers
(
packed_schedule
.
data
(),
packed_schedule
.
size
()
)
>=
0
)
{
_gstate
.
last_producer_schedule_size
=
static_cast
<
decltype
(
_gstate
.
last_producer_schedule_size
)
>
(
top_producers
.
size
()
);
}
}
void
system_contract
::
update_elected_producers_yta
(
block_timestamp
block_time
)
{
_gstate
.
last_producer_schedule_update
=
block_time
;
std
::
vector
<
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
>
top_producers
;
top_producers
.
reserve
(
21
);
for
(
uint16_t
seq_num
=
1
;
seq_num
<=
21
;
seq_num
++
)
{
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
ppinfo
=
getProducerForSeq
(
seq_num
);
if
(
ppinfo
.
first
.
producer_name
!=
0
)
{
top_producers
.
emplace_back
(
ppinfo
);
}
}
if
(
top_producers
.
size
()
<
_gstate
.
last_producer_schedule_size
)
{
return
;
}
/// sort by producer name
std
::
sort
(
top_producers
.
begin
(),
top_producers
.
end
()
);
std
::
vector
<
eosio
::
producer_key
>
producers
;
producers
.
reserve
(
top_producers
.
size
());
for
(
const
auto
&
item
:
top_producers
)
producers
.
push_back
(
item
.
first
);
bytes
packed_schedule
=
pack
(
producers
);
if
(
set_proposed_producers
(
packed_schedule
.
data
(),
packed_schedule
.
size
()
)
>=
0
)
{
_gstate
.
last_producer_schedule_size
=
static_cast
<
decltype
(
_gstate
.
last_producer_schedule_size
)
>
(
top_producers
.
size
()
);
}
}
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
system_contract
::
getProducerForSeq
(
uint64_t
seq_num
)
{
producers_seq_table
_prodseq
(
_self
,
seq_num
);
auto
ps_itr
=
_prodseq
.
find
(
seq_num
);
if
(
ps_itr
==
_prodseq
.
end
()
)
return
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
({{
0
,
eosio
::
public_key
{}},
0
});
if
(
ps_itr
->
prods_all
.
begin
()
==
ps_itr
->
prods_all
.
end
()
)
return
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
({{
0
,
eosio
::
public_key
{}},
0
});
if
(
ps_itr
->
is_org
)
{
//if(ps_itr->prods_l1.is_active && ps_itr->prods_l1.total_votes > 50000000000) {
if
(
ps_itr
->
prods_l1
.
is_active
&&
ps_itr
->
prods_l1
.
total_votes
>
0
)
{
return
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
({{
ps_itr
->
prods_l1
.
owner
,
ps_itr
->
prods_l1
.
producer_key
},
ps_itr
->
prods_l1
.
location
});
}
else
{
_prodseq
.
modify
(
ps_itr
,
_self
,
[
&
](
auto
&
row
)
{
row
.
is_org
=
false
;
});
}
}
double
total_votes
=
0
;
bool
is_find
=
false
;
auto
max
=
ps_itr
->
prods_all
.
begin
();
for
(
auto
it
=
ps_itr
->
prods_all
.
begin
();
it
!=
ps_itr
->
prods_all
.
end
();
it
++
)
{
if
(
it
->
is_active
&&
it
->
total_votes
>
total_votes
)
{
max
=
it
;
total_votes
=
it
->
total_votes
;
is_find
=
true
;
}
}
if
(
is_find
)
return
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
({{
max
->
owner
,
max
->
producer_key
},
max
->
location
});
return
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
({{
0
,
eosio
::
public_key
{}},
0
});
}
//##YTA-Change end:
void
system_contract
::
update_elected_producers
(
block_timestamp
block_time
)
{
_gstate
.
last_producer_schedule_update
=
block_time
;
auto
idx
=
_producers
.
get_index
<
N
(
prototalvote
)
>
();
std
::
vector
<
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
>
top_producers
;
top_producers
.
reserve
(
21
);
for
(
auto
it
=
idx
.
cbegin
();
it
!=
idx
.
cend
()
&&
top_producers
.
size
()
<
21
&&
0
<
it
->
total_votes
&&
it
->
active
();
++
it
)
{
top_producers
.
emplace_back
(
std
::
pair
<
eosio
::
producer_key
,
uint16_t
>
({{
it
->
owner
,
it
->
producer_key
},
it
->
location
})
);
}
if
(
top_producers
.
size
()
<
_gstate
.
last_producer_schedule_size
)
{
return
;
}
/// sort by producer name
std
::
sort
(
top_producers
.
begin
(),
top_producers
.
end
()
);
std
::
vector
<
eosio
::
producer_key
>
producers
;
producers
.
reserve
(
top_producers
.
size
());
for
(
const
auto
&
item
:
top_producers
)
producers
.
push_back
(
item
.
first
);
bytes
packed_schedule
=
pack
(
producers
);
if
(
set_proposed_producers
(
packed_schedule
.
data
(),
packed_schedule
.
size
()
)
>=
0
)
{
_gstate
.
last_producer_schedule_size
=
static_cast
<
decltype
(
_gstate
.
last_producer_schedule_size
)
>
(
top_producers
.
size
()
);
}
}
double
stake2vote
(
int64_t
staked
)
{
/// TODO subtract 2080 brings the large numbers closer to this decade
//double weight = int64_t( (now() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 );
//return double(staked) * std::pow( 2, weight );
return
double
(
staked
);
}
/**
* @pre producers must be sorted from lowest to highest and must be registered and active
* @pre if proxy is set then no producers can be voted for
* @pre if proxy is set then proxy account must exist and be registered as a proxy
* @pre every listed producer or proxy must have been previously registered
* @pre voter must authorize this action
* @pre voter must have previously staked some EOS for voting
* @pre voter->staked must be up to date
*
* @post every producer previously voted for will have vote reduced by previous vote weight
* @post every producer newly voted for will have vote increased by new vote amount
* @post prior proxy will proxied_vote_weight decremented by previous vote weight
* @post new proxy will proxied_vote_weight incremented by new vote weight
*
* If voting for a proxy, the producer votes will not change until the proxy updates their own vote.
*/
void
system_contract
::
voteproducer
(
const
account_name
voter_name
,
const
account_name
proxy
,
const
std
::
vector
<
account_name
>&
producers
)
{
require_auth
(
voter_name
);
///@@@@@@@@@@@@@@@@@@@@@
eosio_assert
(
1
==
2
,
"can not vote now."
);
return
;
///@@@@@@@@@@@@@@@@@@@@
update_votes
(
voter_name
,
proxy
,
producers
,
true
);
}
void
system_contract
::
update_votes
(
const
account_name
voter_name
,
const
account_name
proxy
,
const
std
::
vector
<
account_name
>&
producers
,
bool
voting
)
{
//validate input
if
(
proxy
)
{
eosio_assert
(
producers
.
size
()
==
0
,
"cannot vote for producers and proxy at same time"
);
eosio_assert
(
voter_name
!=
proxy
,
"cannot proxy to self"
);
require_recipient
(
proxy
);
}
else
{
//##YTA-Change start:
//eosio_assert( producers.size() <= 30, "attempt to vote for too many producers" );
// One voter can only vote for one producer
eosio_assert
(
producers
.
size
()
<=
1
,
"attempt to vote for too many producers"
);
//##YTA-Change end:
for
(
size_t
i
=
1
;
i
<
producers
.
size
();
++
i
)
{
eosio_assert
(
producers
[
i
-
1
]
<
producers
[
i
],
"producer votes must be unique and sorted"
);
}
}
auto
voter
=
_voters
.
find
(
voter_name
);
eosio_assert
(
voter
!=
_voters
.
end
(),
"user must stake before they can vote"
);
/// staking creates voter object
eosio_assert
(
!
proxy
||
!
voter
->
is_proxy
,
"account registered as a proxy is not allowed to use a proxy"
);
/**
* The first time someone votes we calculate and set last_vote_weight, since they cannot unstake until
* after total_activated_stake hits threshold, we can use last_vote_weight to determine that this is
* their first vote and should consider their stake activated.
*/
if
(
voter
->
last_vote_weight
<=
0.0
)
{
_gstate
.
total_activated_stake
+=
voter
->
staked
;
if
(
_gstate
.
total_activated_stake
>=
min_activated_stake
&&
_gstate
.
thresh_activated_stake_time
==
0
)
{
_gstate
.
thresh_activated_stake_time
=
current_time
();
}
}
auto
new_vote_weight
=
stake2vote
(
voter
->
staked
);
if
(
voter
->
is_proxy
)
{
new_vote_weight
+=
voter
->
proxied_vote_weight
;
}
boost
::
container
::
flat_map
<
account_name
,
pair
<
double
,
bool
/*new*/
>
>
producer_deltas
;
if
(
voter
->
last_vote_weight
>
0
)
{
if
(
voter
->
proxy
)
{
auto
old_proxy
=
_voters
.
find
(
voter
->
proxy
);
eosio_assert
(
old_proxy
!=
_voters
.
end
(),
"old proxy not found"
);
//data corruption
_voters
.
modify
(
old_proxy
,
0
,
[
&
](
auto
&
vp
)
{
vp
.
proxied_vote_weight
-=
voter
->
last_vote_weight
;
});
propagate_weight_change
(
*
old_proxy
);
}
else
{
for
(
const
auto
&
p
:
voter
->
producers
)
{
auto
&
d
=
producer_deltas
[
p
];
d
.
first
-=
voter
->
last_vote_weight
;
d
.
second
=
false
;
}
}
}
if
(
proxy
)
{
auto
new_proxy
=
_voters
.
find
(
proxy
);
eosio_assert
(
new_proxy
!=
_voters
.
end
(),
"invalid proxy specified"
);
//if ( !voting ) { data corruption } else { wrong vote }
eosio_assert
(
!
voting
||
new_proxy
->
is_proxy
,
"proxy not found"
);
if
(
new_vote_weight
>=
0
)
{
_voters
.
modify
(
new_proxy
,
0
,
[
&
](
auto
&
vp
)
{
vp
.
proxied_vote_weight
+=
new_vote_weight
;
});
propagate_weight_change
(
*
new_proxy
);
}
}
else
{
if
(
new_vote_weight
>=
0
)
{
for
(
const
auto
&
p
:
producers
)
{
auto
&
d
=
producer_deltas
[
p
];
d
.
first
+=
new_vote_weight
;
d
.
second
=
true
;
}
}
}
for
(
const
auto
&
pd
:
producer_deltas
)
{
double
total_votes
=
0
;
auto
pitr
=
_producers
.
find
(
pd
.
first
);
if
(
pitr
!=
_producers
.
end
()
)
{
eosio_assert
(
!
voting
||
pitr
->
active
()
||
!
pd
.
second
.
second
/* not from new set */
,
"producer is not currently registered"
);
_producers
.
modify
(
pitr
,
0
,
[
&
](
auto
&
p
)
{
p
.
total_votes
+=
pd
.
second
.
first
;
if
(
p
.
total_votes
<
0
)
{
// floating point arithmetics can give small negative numbers
p
.
total_votes
=
0
;
}
_gstate
.
total_producer_vote_weight
+=
pd
.
second
.
first
;
//eosio_assert( p.total_votes >= 0, "something bad happened" );
total_votes
=
p
.
total_votes
;
});
}
else
{
eosio_assert
(
!
pd
.
second
.
second
/* not from new set */
,
"producer is not registered"
);
//data corruption
}
//##YTA-Change start:
auto
pitr2
=
_producersext
.
find
(
pd
.
first
);
if
(
pitr2
!=
_producersext
.
end
()
)
{
//pitr2->seq_num
update_producers_seq_totalvotes
(
pitr2
->
seq_num
,
pd
.
first
,
total_votes
);
}
else
{
eosio_assert
(
!
pd
.
second
.
second
/* not from new set */
,
"producer is not registered"
);
//data corruption
}
//##YTA-Change end:
}
_voters
.
modify
(
voter
,
0
,
[
&
](
auto
&
av
)
{
av
.
last_vote_weight
=
new_vote_weight
;
av
.
producers
=
producers
;
av
.
proxy
=
proxy
;
});
}
/**
* An account marked as a proxy can vote with the weight of other accounts which
* have selected it as a proxy. Other accounts must refresh their voteproducer to
* update the proxy's weight.
*
* @param isproxy - true if proxy wishes to vote on behalf of others, false otherwise
* @pre proxy must have something staked (existing row in voters table)
* @pre new state must be different than current state
*/
void
system_contract
::
regproxy
(
const
account_name
proxy
,
bool
isproxy
)
{
require_auth
(
proxy
);
auto
pitr
=
_voters
.
find
(
proxy
);
if
(
pitr
!=
_voters
.
end
()
)
{
eosio_assert
(
isproxy
!=
pitr
->
is_proxy
,
"action has no effect"
);
eosio_assert
(
!
isproxy
||
!
pitr
->
proxy
,
"account that uses a proxy is not allowed to become a proxy"
);
_voters
.
modify
(
pitr
,
0
,
[
&
](
auto
&
p
)
{
p
.
is_proxy
=
isproxy
;
});
propagate_weight_change
(
*
pitr
);
}
else
{
_voters
.
emplace
(
proxy
,
[
&
](
auto
&
p
)
{
p
.
owner
=
proxy
;
p
.
is_proxy
=
isproxy
;
});
}
}
void
system_contract
::
propagate_weight_change
(
const
voter_info
&
voter
)
{
eosio_assert
(
voter
.
proxy
==
0
||
!
voter
.
is_proxy
,
"account registered as a proxy is not allowed to use a proxy"
);
double
new_weight
=
stake2vote
(
voter
.
staked
);
if
(
voter
.
is_proxy
)
{
new_weight
+=
voter
.
proxied_vote_weight
;
}
/// don't propagate small changes (1 ~= epsilon)
if
(
fabs
(
new_weight
-
voter
.
last_vote_weight
)
>
1
)
{
if
(
voter
.
proxy
)
{
auto
&
proxy
=
_voters
.
get
(
voter
.
proxy
,
"proxy not found"
);
//data corruption
_voters
.
modify
(
proxy
,
0
,
[
&
](
auto
&
p
)
{
p
.
proxied_vote_weight
+=
new_weight
-
voter
.
last_vote_weight
;
}
);
propagate_weight_change
(
proxy
);
}
else
{
auto
delta
=
new_weight
-
voter
.
last_vote_weight
;
for
(
auto
acnt
:
voter
.
producers
)
{
auto
&
pitr
=
_producers
.
get
(
acnt
,
"producer not found"
);
//data corruption
_producers
.
modify
(
pitr
,
0
,
[
&
](
auto
&
p
)
{
p
.
total_votes
+=
delta
;
_gstate
.
total_producer_vote_weight
+=
delta
;
});
}
}
}
_voters
.
modify
(
voter
,
0
,
[
&
](
auto
&
v
)
{
v
.
last_vote_weight
=
new_weight
;
}
);
}
}
/// namespace eosiosystem
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录