Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
5a3ff040
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,发现更多精彩内容 >>
提交
5a3ff040
编写于
2月 21, 2018
作者:
A
Anton Perkov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
system contract split into 2 parts #1455
上级
d8f3fbfa
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
417 addition
and
367 deletion
+417
-367
contracts/eosio.system/delegate_bandwith.hpp
contracts/eosio.system/delegate_bandwith.hpp
+189
-0
contracts/eosio.system/eosio.system.hpp
contracts/eosio.system/eosio.system.hpp
+16
-367
contracts/eosio.system/producers_election.hpp
contracts/eosio.system/producers_election.hpp
+212
-0
未找到文件。
contracts/eosio.system/delegate_bandwith.hpp
0 → 100644
浏览文件 @
5a3ff040
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#pragma once
#include <eosiolib/eosio.hpp>
#include <eosiolib/token.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/generic_currency.hpp>
#include <eosiolib/datastream.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/multi_index.hpp>
#include <eosiolib/privileged.h>
#include <map>
namespace
eosiosystem
{
using
eosio
::
indexed_by
;
using
eosio
::
const_mem_fun
;
using
eosio
::
bytes
;
using
eosio
::
print
;
using
std
::
map
;
using
std
::
pair
;
template
<
account_name
SystemAccount
>
class
delegate_bandwith
{
public:
static
const
account_name
system_account
=
SystemAccount
;
typedef
eosio
::
generic_currency
<
eosio
::
token
<
system_account
,
S
(
4
,
EOS
)
>
>
currency
;
typedef
typename
currency
::
token_type
system_token_type
;
struct
total_resources
{
account_name
owner
;
typename
currency
::
token_type
total_net_weight
;
typename
currency
::
token_type
total_cpu_weight
;
uint32_t
total_ram
=
0
;
uint64_t
primary_key
()
const
{
return
owner
;
}
EOSLIB_SERIALIZE
(
total_resources
,
(
owner
)(
total_net_weight
)(
total_cpu_weight
)(
total_ram
)
)
};
/**
* 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
;
typename
currency
::
token_type
net_weight
;
typename
currency
::
token_type
cpu_weight
;
uint32_t
start_pending_net_withdraw
=
0
;
typename
currency
::
token_type
pending_net_withdraw
;
uint64_t
deferred_net_withdraw_handler
=
0
;
uint32_t
start_pending_cpu_withdraw
=
0
;
typename
currency
::
token_type
pending_cpu_withdraw
;
uint64_t
deferred_cpu_withdraw_handler
=
0
;
uint64_t
primary_key
()
const
{
return
to
;
}
EOSLIB_SERIALIZE
(
delegated_bandwidth
,
(
from
)(
to
)(
net_weight
)(
cpu_weight
)
(
start_pending_net_withdraw
)(
pending_net_withdraw
)(
deferred_net_withdraw_handler
)
(
start_pending_cpu_withdraw
)(
pending_cpu_withdraw
)(
deferred_cpu_withdraw_handler
)
)
};
typedef
eosio
::
multi_index
<
N
(
totalband
),
total_resources
>
total_resources_index_type
;
typedef
eosio
::
multi_index
<
N
(
delband
),
delegated_bandwidth
>
del_bandwidth_index_type
;
ACTION
(
SystemAccount
,
finshundel
)
{
account_name
from
;
account_name
to
;
};
ACTION
(
SystemAccount
,
delegatebw
)
{
account_name
from
;
account_name
receiver
;
typename
currency
::
token_type
stake_net_quantity
;
typename
currency
::
token_type
stake_cpu_quantity
;
EOSLIB_SERIALIZE
(
delegatebw
,
(
from
)(
receiver
)(
stake_net_quantity
)(
stake_cpu_quantity
)
)
};
ACTION
(
SystemAccount
,
undelegatebw
)
{
account_name
from
;
account_name
receiver
;
typename
currency
::
token_type
unstake_net_quantity
;
typename
currency
::
token_type
unstake_cpu_quantity
;
EOSLIB_SERIALIZE
(
undelegatebw
,
(
from
)(
receiver
)(
unstake_net_quantity
)(
unstake_cpu_quantity
)
)
};
/// new id options:
// 1. hash + collision
// 2. incrementing count (key=> tablename
static
void
on
(
const
delegatebw
&
del
)
{
eosio_assert
(
del
.
stake_cpu_quantity
.
quantity
>=
0
,
"must stake a positive amount"
);
eosio_assert
(
del
.
stake_net_quantity
.
quantity
>=
0
,
"must stake a positive amount"
);
auto
total_stake
=
del
.
stake_cpu_quantity
+
del
.
stake_net_quantity
;
eosio_assert
(
total_stake
.
quantity
>=
0
,
"must stake a positive amount"
);
require_auth
(
del
.
from
);
del_bandwidth_index_type
del_index
(
SystemAccount
,
del
.
from
);
total_resources_index_type
total_index
(
SystemAccount
,
del
.
receiver
);
//eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" );
auto
itr
=
del_index
.
find
(
del
.
receiver
);
if
(
itr
!=
nullptr
)
{
del_index
.
emplace
(
del
.
from
,
[
&
](
auto
&
dbo
){
dbo
.
from
=
del
.
from
;
dbo
.
to
=
del
.
receiver
;
dbo
.
net_weight
=
del
.
stake_net_quantity
;
dbo
.
cpu_weight
=
del
.
stake_cpu_quantity
;
});
}
else
{
del_index
.
update
(
*
itr
,
del
.
from
,
[
&
](
auto
&
dbo
){
dbo
.
net_weight
=
del
.
stake_net_quantity
;
dbo
.
cpu_weight
=
del
.
stake_cpu_quantity
;
});
}
auto
tot_itr
=
total_index
.
find
(
del
.
receiver
);
if
(
tot_itr
==
nullptr
)
{
tot_itr
=
&
total_index
.
emplace
(
del
.
from
,
[
&
](
auto
&
tot
)
{
tot
.
owner
=
del
.
receiver
;
tot
.
total_net_weight
+=
del
.
stake_net_quantity
;
tot
.
total_cpu_weight
+=
del
.
stake_cpu_quantity
;
});
}
else
{
total_index
.
update
(
*
tot_itr
,
0
,
[
&
](
auto
&
tot
)
{
tot
.
total_net_weight
+=
del
.
stake_net_quantity
;
tot
.
total_cpu_weight
+=
del
.
stake_cpu_quantity
;
});
}
set_resource_limits
(
tot_itr
->
owner
,
tot_itr
->
total_ram
,
tot_itr
->
total_net_weight
.
quantity
,
tot_itr
->
total_cpu_weight
.
quantity
,
0
);
currency
::
inline_transfer
(
del
.
from
,
SystemAccount
,
total_stake
,
"stake bandwidth"
);
}
// delegatebw
static
void
on
(
const
undelegatebw
&
del
)
{
eosio_assert
(
del
.
unstake_cpu_quantity
.
quantity
>=
0
,
"must stake a positive amount"
);
eosio_assert
(
del
.
unstake_net_quantity
.
quantity
>=
0
,
"must stake a positive amount"
);
auto
total_stake
=
del
.
unstake_cpu_quantity
+
del
.
unstake_net_quantity
;
eosio_assert
(
total_stake
.
quantity
>=
0
,
"must stake a positive amount"
);
require_auth
(
del
.
from
);
del_bandwidth_index_type
del_index
(
SystemAccount
,
del
.
from
);
total_resources_index_type
total_index
(
SystemAccount
,
del
.
receiver
);
//eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" );
const
auto
&
dbw
=
del_index
.
get
(
del
.
receiver
);
eosio_assert
(
dbw
.
net_weight
>=
del
.
unstake_net_quantity
,
"insufficient staked net bandwidth"
);
eosio_assert
(
dbw
.
cpu_weight
>=
del
.
unstake_cpu_quantity
,
"insufficient staked cpu bandwidth"
);
del_index
.
update
(
dbw
,
del
.
from
,
[
&
](
auto
&
dbo
){
dbo
.
net_weight
-=
del
.
unstake_net_quantity
;
dbo
.
cpu_weight
-=
del
.
unstake_cpu_quantity
;
});
const
auto
&
totals
=
total_index
.
get
(
del
.
receiver
);
total_index
.
update
(
totals
,
0
,
[
&
](
auto
&
tot
)
{
tot
.
total_net_weight
-=
del
.
unstake_net_quantity
;
tot
.
total_cpu_weight
-=
del
.
unstake_cpu_quantity
;
});
set_resource_limits
(
totals
.
owner
,
totals
.
total_ram
,
totals
.
total_net_weight
.
quantity
,
totals
.
total_cpu_weight
.
quantity
,
0
);
/// TODO: implement / enforce time delays on withdrawing
currency
::
inline_transfer
(
SystemAccount
,
del
.
from
,
total_stake
,
"unstake bandwidth"
);
}
// undelegatebw
};
}
contracts/eosio.system/eosio.system.hpp
浏览文件 @
5a3ff040
...
@@ -2,152 +2,25 @@
...
@@ -2,152 +2,25 @@
* @file
* @file
* @copyright defined in eos/LICENSE.txt
* @copyright defined in eos/LICENSE.txt
*/
*/
#include <eosiolib/eosio.hpp>
#pragma once
#include <eosiolib/token.hpp>
#include <eosiolib/db.hpp>
#include <eosiolib/reflect.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/generic_currency.hpp>
#include "producers_election.hpp"
#include <eosiolib/datastream.hpp>
#include "delegate_bandwith.hpp"
#include <eosiolib/serialize.hpp>
#include <eosiolib/multi_index.hpp>
#include <eosiolib/privileged.h>
#include <algorithm>
#include <eosiolib/generic_currency.hpp>
#include <map>
namespace
eosiosystem
{
namespace
eosiosystem
{
using
eosio
::
indexed_by
;
using
eosio
::
const_mem_fun
;
using
eosio
::
bytes
;
using
std
::
map
;
using
std
::
pair
;
using
eosio
::
print
;
template
<
account_name
SystemAccount
>
template
<
account_name
SystemAccount
>
class
contract
{
class
contract
:
public
producers_election
<
SystemAccount
>
,
public
delegate_bandwith
<
SystemAccount
>
{
public:
public:
using
producers_election
<
SystemAccount
>::
on
;
using
delegate_bandwith
<
SystemAccount
>::
on
;
using
pe
=
producers_election
<
SystemAccount
>
;
using
db
=
delegate_bandwith
<
SystemAccount
>
;
static
const
account_name
system_account
=
SystemAccount
;
static
const
account_name
system_account
=
SystemAccount
;
typedef
eosio
::
generic_currency
<
eosio
::
token
<
system_account
,
S
(
4
,
EOS
)
>
>
currency
;
typedef
eosio
::
generic_currency
<
eosio
::
token
<
system_account
,
S
(
4
,
EOS
)
>
>
currency
;
typedef
typename
currency
::
token_type
system_token_type
;
struct
producer_votes
{
account_name
owner
;
uint64_t
padding
=
0
;
uint128_t
total_votes
;
uint64_t
primary_key
()
const
{
return
owner
;
}
uint128_t
by_votes
()
const
{
return
total_votes
;
}
EOSLIB_SERIALIZE
(
producer_votes
,
(
owner
)(
total_votes
)
)
};
typedef
eosio
::
multi_index
<
N
(
producervote
),
producer_votes
,
indexed_by
<
N
(
prototalvote
),
const_mem_fun
<
producer_votes
,
uint128_t
,
&
producer_votes
::
by_votes
>
>
>
producer_votes_index_type
;
struct
account_votes
{
account_name
owner
;
account_name
proxy
;
uint32_t
last_update
;
system_token_type
staked
;
std
::
vector
<
account_name
>
producers
;
uint64_t
primary_key
()
const
{
return
owner
;
}
EOSLIB_SERIALIZE
(
account_votes
,
(
owner
)(
proxy
)(
last_update
)(
staked
)(
producers
)
)
};
typedef
eosio
::
multi_index
<
N
(
accountvotes
),
account_votes
>
account_votes_index_type
;
struct
producer_config
{
account_name
owner
;
eosio
::
bytes
packed_key
;
/// a packed public key object
uint64_t
primary_key
()
const
{
return
owner
;
}
EOSLIB_SERIALIZE
(
producer_config
,
(
owner
)(
packed_key
)
)
};
typedef
eosio
::
multi_index
<
N
(
producercfg
),
producer_config
>
producer_config_index_type
;
struct
total_resources
{
account_name
owner
;
typename
currency
::
token_type
total_net_weight
;
typename
currency
::
token_type
total_cpu_weight
;
uint32_t
total_ram
=
0
;
uint64_t
primary_key
()
const
{
return
owner
;
}
EOSLIB_SERIALIZE
(
total_resources
,
(
owner
)(
total_net_weight
)(
total_cpu_weight
)(
total_ram
)
)
};
/**
* 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
;
typename
currency
::
token_type
net_weight
;
typename
currency
::
token_type
cpu_weight
;
uint32_t
start_pending_net_withdraw
=
0
;
typename
currency
::
token_type
pending_net_withdraw
;
uint64_t
deferred_net_withdraw_handler
=
0
;
uint32_t
start_pending_cpu_withdraw
=
0
;
typename
currency
::
token_type
pending_cpu_withdraw
;
uint64_t
deferred_cpu_withdraw_handler
=
0
;
uint64_t
primary_key
()
const
{
return
to
;
}
EOSLIB_SERIALIZE
(
delegated_bandwidth
,
(
from
)(
to
)(
net_weight
)(
cpu_weight
)
(
start_pending_net_withdraw
)(
pending_net_withdraw
)(
deferred_net_withdraw_handler
)
(
start_pending_cpu_withdraw
)(
pending_cpu_withdraw
)(
deferred_cpu_withdraw_handler
)
)
};
typedef
eosio
::
multi_index
<
N
(
totalband
),
total_resources
>
total_resources_index_type
;
typedef
eosio
::
multi_index
<
N
(
delband
),
delegated_bandwidth
>
del_bandwidth_index_type
;
ACTION
(
SystemAccount
,
finshundel
)
{
account_name
from
;
account_name
to
;
};
ACTION
(
SystemAccount
,
regproducer
)
{
account_name
producer
;
bytes
producer_key
;
EOSLIB_SERIALIZE
(
regproducer
,
(
producer
)(
producer_key
)
)
};
ACTION
(
SystemAccount
,
regproxy
)
{
account_name
proxy_to_register
;
EOSLIB_SERIALIZE
(
regproxy
,
(
proxy_to_register
)
)
};
ACTION
(
SystemAccount
,
delegatebw
)
{
account_name
from
;
account_name
receiver
;
typename
currency
::
token_type
stake_net_quantity
;
typename
currency
::
token_type
stake_cpu_quantity
;
EOSLIB_SERIALIZE
(
delegatebw
,
(
from
)(
receiver
)(
stake_net_quantity
)(
stake_cpu_quantity
)
)
};
ACTION
(
SystemAccount
,
undelegatebw
)
{
account_name
from
;
account_name
receiver
;
typename
currency
::
token_type
unstake_net_quantity
;
typename
currency
::
token_type
unstake_cpu_quantity
;
EOSLIB_SERIALIZE
(
undelegatebw
,
(
from
)(
receiver
)(
unstake_net_quantity
)(
unstake_cpu_quantity
)
)
};
ACTION
(
SystemAccount
,
nonce
)
{
ACTION
(
SystemAccount
,
nonce
)
{
eosio
::
string
value
;
eosio
::
string
value
;
...
@@ -155,240 +28,16 @@ namespace eosiosystem {
...
@@ -155,240 +28,16 @@ namespace eosiosystem {
EOSLIB_SERIALIZE
(
nonce
,
(
value
)
)
EOSLIB_SERIALIZE
(
nonce
,
(
value
)
)
};
};
/// new id options:
// 1. hash + collision
// 2. incrementing count (key=> tablename
static
void
on
(
const
delegatebw
&
del
)
{
eosio_assert
(
del
.
stake_cpu_quantity
.
quantity
>=
0
,
"must stake a positive amount"
);
eosio_assert
(
del
.
stake_net_quantity
.
quantity
>=
0
,
"must stake a positive amount"
);
auto
total_stake
=
del
.
stake_cpu_quantity
+
del
.
stake_net_quantity
;
eosio_assert
(
total_stake
.
quantity
>=
0
,
"must stake a positive amount"
);
require_auth
(
del
.
from
);
del_bandwidth_index_type
del_index
(
SystemAccount
,
del
.
from
);
total_resources_index_type
total_index
(
SystemAccount
,
del
.
receiver
);
//eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" );
auto
itr
=
del_index
.
find
(
del
.
receiver
);
if
(
itr
!=
nullptr
)
{
del_index
.
emplace
(
del
.
from
,
[
&
](
auto
&
dbo
){
dbo
.
from
=
del
.
from
;
dbo
.
to
=
del
.
receiver
;
dbo
.
net_weight
=
del
.
stake_net_quantity
;
dbo
.
cpu_weight
=
del
.
stake_cpu_quantity
;
});
}
else
{
del_index
.
update
(
*
itr
,
del
.
from
,
[
&
](
auto
&
dbo
){
dbo
.
net_weight
=
del
.
stake_net_quantity
;
dbo
.
cpu_weight
=
del
.
stake_cpu_quantity
;
});
}
auto
tot_itr
=
total_index
.
find
(
del
.
receiver
);
if
(
tot_itr
==
nullptr
)
{
tot_itr
=
&
total_index
.
emplace
(
del
.
from
,
[
&
](
auto
&
tot
)
{
tot
.
owner
=
del
.
receiver
;
tot
.
total_net_weight
+=
del
.
stake_net_quantity
;
tot
.
total_cpu_weight
+=
del
.
stake_cpu_quantity
;
});
}
else
{
total_index
.
update
(
*
tot_itr
,
0
,
[
&
](
auto
&
tot
)
{
tot
.
total_net_weight
+=
del
.
stake_net_quantity
;
tot
.
total_cpu_weight
+=
del
.
stake_cpu_quantity
;
});
}
set_resource_limits
(
tot_itr
->
owner
,
tot_itr
->
total_ram
,
tot_itr
->
total_net_weight
.
quantity
,
tot_itr
->
total_cpu_weight
.
quantity
,
0
);
currency
::
inline_transfer
(
del
.
from
,
SystemAccount
,
total_stake
,
"stake bandwidth"
);
}
// delegatebw
static
void
on
(
const
undelegatebw
&
del
)
{
eosio_assert
(
del
.
unstake_cpu_quantity
.
quantity
>=
0
,
"must stake a positive amount"
);
eosio_assert
(
del
.
unstake_net_quantity
.
quantity
>=
0
,
"must stake a positive amount"
);
auto
total_stake
=
del
.
unstake_cpu_quantity
+
del
.
unstake_net_quantity
;
eosio_assert
(
total_stake
.
quantity
>=
0
,
"must stake a positive amount"
);
require_auth
(
del
.
from
);
del_bandwidth_index_type
del_index
(
SystemAccount
,
del
.
from
);
total_resources_index_type
total_index
(
SystemAccount
,
del
.
receiver
);
//eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" );
const
auto
&
dbw
=
del_index
.
get
(
del
.
receiver
);
eosio_assert
(
dbw
.
net_weight
>=
del
.
unstake_net_quantity
,
"insufficient staked net bandwidth"
);
eosio_assert
(
dbw
.
cpu_weight
>=
del
.
unstake_cpu_quantity
,
"insufficient staked cpu bandwidth"
);
del_index
.
update
(
dbw
,
del
.
from
,
[
&
](
auto
&
dbo
){
dbo
.
net_weight
-=
del
.
unstake_net_quantity
;
dbo
.
cpu_weight
-=
del
.
unstake_cpu_quantity
;
});
const
auto
&
totals
=
total_index
.
get
(
del
.
receiver
);
total_index
.
update
(
totals
,
0
,
[
&
](
auto
&
tot
)
{
tot
.
total_net_weight
-=
del
.
unstake_net_quantity
;
tot
.
total_cpu_weight
-=
del
.
unstake_cpu_quantity
;
});
set_resource_limits
(
totals
.
owner
,
totals
.
total_ram
,
totals
.
total_net_weight
.
quantity
,
totals
.
total_cpu_weight
.
quantity
,
0
);
/// TODO: implement / enforce time delays on withdrawing
currency
::
inline_transfer
(
SystemAccount
,
del
.
from
,
total_stake
,
"unstake bandwidth"
);
}
// undelegatebw
/**
* This method will create a producr_config and producer_votes object for 'producer'
*
* @pre producer is not already registered
* @pre producer to register is an account
* @pre authority of producer to register
*
*/
static
void
on
(
const
regproducer
&
reg
)
{
auto
producer
=
reg
.
producer
;
require_auth
(
producer
);
producer_votes_index_type
votes
(
SystemAccount
,
SystemAccount
);
const
auto
*
existing
=
votes
.
find
(
producer
);
eosio_assert
(
!
existing
,
"producer already registered"
);
votes
.
emplace
(
producer
,
[
&
](
auto
&
pv
){
pv
.
owner
=
producer
;
pv
.
total_votes
=
0
;
});
producer_config_index_type
proconfig
(
SystemAccount
,
SystemAccount
);
proconfig
.
emplace
(
producer
,
[
&
](
auto
&
pc
)
{
pc
.
owner
=
producer
;
pc
.
packed_key
=
reg
.
producer_key
;
});
}
ACTION
(
SystemAccount
,
stakevote
)
{
account_name
voter
;
system_token_type
amount
;
EOSLIB_SERIALIZE
(
stakevote
,
(
voter
)(
amount
)
)
};
static
void
on
(
const
stakevote
&
sv
)
{
print
(
"on stake vote
\n
"
);
eosio_assert
(
sv
.
amount
.
quantity
>
0
,
"must stake some tokens"
);
require_auth
(
sv
.
voter
);
account_votes_index_type
avotes
(
SystemAccount
,
SystemAccount
);
const
auto
*
acv
=
avotes
.
find
(
sv
.
voter
);
if
(
!
acv
)
{
acv
=
&
avotes
.
emplace
(
sv
.
voter
,
[
&
](
auto
&
av
)
{
av
.
owner
=
sv
.
voter
;
av
.
last_update
=
now
();
av
.
proxy
=
0
;
});
}
uint128_t
old_weight
=
acv
->
staked
.
quantity
;
uint128_t
new_weight
=
old_weight
+
sv
.
amount
.
quantity
;
producer_votes_index_type
votes
(
SystemAccount
,
SystemAccount
);
for
(
auto
p
:
acv
->
producers
)
{
votes
.
update
(
votes
.
get
(
p
),
0
,
[
&
](
auto
&
v
)
{
v
.
total_votes
-=
old_weight
;
v
.
total_votes
+=
new_weight
;
});
}
avotes
.
update
(
*
acv
,
0
,
[
&
](
auto
av
)
{
av
.
last_update
=
now
();
av
.
staked
+=
sv
.
amount
;
});
currency
::
inline_transfer
(
sv
.
voter
,
SystemAccount
,
sv
.
amount
,
"stake for voting"
);
}
ACTION
(
SystemAccount
,
voteproducer
)
{
account_name
voter
;
account_name
proxy
;
std
::
vector
<
account_name
>
producers
;
EOSLIB_SERIALIZE
(
voteproducer
,
(
voter
)(
proxy
)(
producers
)
)
};
/**
* @pre vp.producers must be sorted from lowest to highest
* @pre if proxy is set then no producers can be voted for
* @pre every listed producer or proxy must have been previously registered
* @pre vp.voter must authorize this action
* @pre voter must have previously staked some EOS for voting
*/
static
void
on
(
const
voteproducer
&
vp
)
{
eosio_assert
(
std
::
is_sorted
(
vp
.
producers
.
begin
(),
vp
.
producers
.
end
()
),
"producer votes must be sorted"
);
eosio_assert
(
vp
.
producers
.
size
()
<=
30
,
"attempt to vote for too many producers"
);
if
(
vp
.
proxy
!=
0
)
eosio_assert
(
vp
.
producers
.
size
()
==
0
,
"cannot vote for producers and proxy at same time"
);
require_auth
(
vp
.
voter
);
account_votes_index_type
avotes
(
SystemAccount
,
SystemAccount
);
const
auto
&
existing
=
avotes
.
get
(
vp
.
voter
);
std
::
map
<
account_name
,
pair
<
uint128_t
,
uint128_t
>
>
producer_vote_changes
;
uint128_t
old_weight
=
existing
.
staked
.
quantity
;
/// old time
uint128_t
new_weight
=
old_weight
;
/// TODO: update for current weight
for
(
const
auto
&
p
:
existing
.
producers
)
producer_vote_changes
[
p
].
first
=
old_weight
;
for
(
const
auto
&
p
:
vp
.
producers
)
producer_vote_changes
[
p
].
second
=
new_weight
;
producer_votes_index_type
votes
(
SystemAccount
,
SystemAccount
);
for
(
const
auto
&
delta
:
producer_vote_changes
)
{
if
(
delta
.
second
.
first
!=
delta
.
second
.
second
)
{
const
auto
&
provote
=
votes
.
get
(
delta
.
first
);
votes
.
update
(
provote
,
0
,
[
&
](
auto
&
pv
){
pv
.
total_votes
-=
delta
.
second
.
first
;
pv
.
total_votes
+=
delta
.
second
.
second
;
});
}
}
avotes
.
update
(
existing
,
0
,
[
&
](
auto
&
av
)
{
av
.
proxy
=
vp
.
proxy
;
av
.
last_update
=
now
();
av
.
producers
=
vp
.
producers
;
});
}
static
void
on
(
const
regproxy
&
reg
)
{
require_auth
(
reg
.
proxy_to_register
);
}
static
void
on
(
const
nonce
&
)
{
static
void
on
(
const
nonce
&
)
{
}
}
static
void
apply
(
account_name
code
,
action_name
act
)
{
static
void
apply
(
account_name
code
,
action_name
act
)
{
if
(
!
eosio
::
dispatch
<
contract
,
typename
delegate_bandwith
<
SystemAccount
>::
delegatebw
,
if
(
!
eosio
::
dispatch
<
contract
,
typename
delegate_bandwith
<
SystemAccount
>::
undelegatebw
,
regproducer
,
regproxy
,
typename
producers_election
<
SystemAccount
>::
regproxy
,
delegatebw
,
undelegatebw
,
typename
producers_election
<
SystemAccount
>::
regproducer
,
regproducer
,
voteproducer
,
stakevote
,
typename
producers_election
<
SystemAccount
>::
voteproducer
,
typename
producers_election
<
SystemAccount
>::
stakevote
,
nonce
>
(
code
,
act
)
)
{
nonce
>
(
code
,
act
)
)
{
if
(
!
eosio
::
dispatch
<
currency
,
typename
currency
::
transfer
,
typename
currency
::
issue
>
(
code
,
act
)
)
{
if
(
!
eosio
::
dispatch
<
currency
,
typename
currency
::
transfer
,
typename
currency
::
issue
>
(
code
,
act
)
)
{
eosio
::
print
(
"Unexpected action: "
,
eosio
::
name
(
act
),
"
\n
"
);
eosio
::
print
(
"Unexpected action: "
,
eosio
::
name
(
act
),
"
\n
"
);
...
...
contracts/eosio.system/producers_election.hpp
0 → 100644
浏览文件 @
5a3ff040
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#pragma once
#include <eosiolib/eosio.hpp>
#include <eosiolib/token.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/generic_currency.hpp>
#include <eosiolib/datastream.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/multi_index.hpp>
#include <map>
namespace
eosiosystem
{
using
eosio
::
indexed_by
;
using
eosio
::
const_mem_fun
;
using
eosio
::
bytes
;
using
eosio
::
print
;
using
std
::
map
;
using
std
::
pair
;
template
<
account_name
SystemAccount
>
class
producers_election
{
public:
static
const
account_name
system_account
=
SystemAccount
;
typedef
eosio
::
generic_currency
<
eosio
::
token
<
system_account
,
S
(
4
,
EOS
)
>
>
currency
;
typedef
typename
currency
::
token_type
system_token_type
;
struct
producer_votes
{
account_name
owner
;
uint64_t
padding
=
0
;
uint128_t
total_votes
;
uint64_t
primary_key
()
const
{
return
owner
;
}
uint128_t
by_votes
()
const
{
return
total_votes
;
}
EOSLIB_SERIALIZE
(
producer_votes
,
(
owner
)(
total_votes
)
)
};
typedef
eosio
::
multi_index
<
N
(
producervote
),
producer_votes
,
indexed_by
<
N
(
prototalvote
),
const_mem_fun
<
producer_votes
,
uint128_t
,
&
producer_votes
::
by_votes
>
>
>
producer_votes_index_type
;
struct
account_votes
{
account_name
owner
;
account_name
proxy
;
uint32_t
last_update
;
system_token_type
staked
;
std
::
vector
<
account_name
>
producers
;
uint64_t
primary_key
()
const
{
return
owner
;
}
EOSLIB_SERIALIZE
(
account_votes
,
(
owner
)(
proxy
)(
last_update
)(
staked
)(
producers
)
)
};
typedef
eosio
::
multi_index
<
N
(
accountvotes
),
account_votes
>
account_votes_index_type
;
struct
producer_config
{
account_name
owner
;
eosio
::
bytes
packed_key
;
/// a packed public key object
uint64_t
primary_key
()
const
{
return
owner
;
}
EOSLIB_SERIALIZE
(
producer_config
,
(
owner
)(
packed_key
)
)
};
typedef
eosio
::
multi_index
<
N
(
producercfg
),
producer_config
>
producer_config_index_type
;
ACTION
(
SystemAccount
,
regproducer
)
{
account_name
producer
;
bytes
producer_key
;
EOSLIB_SERIALIZE
(
regproducer
,
(
producer
)(
producer_key
)
)
};
/**
* This method will create a producer_config and producer_votes object for 'producer'
*
* @pre producer is not already registered
* @pre producer to register is an account
* @pre authority of producer to register
*
*/
static
void
on
(
const
regproducer
&
reg
)
{
auto
producer
=
reg
.
producer
;
require_auth
(
producer
);
producer_votes_index_type
votes
(
SystemAccount
,
SystemAccount
);
const
auto
*
existing
=
votes
.
find
(
producer
);
eosio_assert
(
!
existing
,
"producer already registered"
);
votes
.
emplace
(
producer
,
[
&
](
auto
&
pv
){
pv
.
owner
=
producer
;
pv
.
total_votes
=
0
;
});
producer_config_index_type
proconfig
(
SystemAccount
,
SystemAccount
);
proconfig
.
emplace
(
producer
,
[
&
](
auto
&
pc
)
{
pc
.
owner
=
producer
;
pc
.
packed_key
=
reg
.
producer_key
;
});
}
ACTION
(
SystemAccount
,
stakevote
)
{
account_name
voter
;
system_token_type
amount
;
EOSLIB_SERIALIZE
(
stakevote
,
(
voter
)(
amount
)
)
};
static
void
on
(
const
stakevote
&
sv
)
{
print
(
"on stake vote
\n
"
);
eosio_assert
(
sv
.
amount
.
quantity
>
0
,
"must stake some tokens"
);
require_auth
(
sv
.
voter
);
account_votes_index_type
avotes
(
SystemAccount
,
SystemAccount
);
const
auto
*
acv
=
avotes
.
find
(
sv
.
voter
);
if
(
!
acv
)
{
acv
=
&
avotes
.
emplace
(
sv
.
voter
,
[
&
](
auto
&
av
)
{
av
.
owner
=
sv
.
voter
;
av
.
last_update
=
now
();
av
.
proxy
=
0
;
});
}
uint128_t
old_weight
=
acv
->
staked
.
quantity
;
uint128_t
new_weight
=
old_weight
+
sv
.
amount
.
quantity
;
producer_votes_index_type
votes
(
SystemAccount
,
SystemAccount
);
for
(
auto
p
:
acv
->
producers
)
{
votes
.
update
(
votes
.
get
(
p
),
0
,
[
&
](
auto
&
v
)
{
v
.
total_votes
-=
old_weight
;
v
.
total_votes
+=
new_weight
;
});
}
avotes
.
update
(
*
acv
,
0
,
[
&
](
auto
av
)
{
av
.
last_update
=
now
();
av
.
staked
+=
sv
.
amount
;
});
currency
::
inline_transfer
(
sv
.
voter
,
SystemAccount
,
sv
.
amount
,
"stake for voting"
);
}
ACTION
(
SystemAccount
,
voteproducer
)
{
account_name
voter
;
account_name
proxy
;
std
::
vector
<
account_name
>
producers
;
EOSLIB_SERIALIZE
(
voteproducer
,
(
voter
)(
proxy
)(
producers
)
)
};
/**
* @pre vp.producers must be sorted from lowest to highest
* @pre if proxy is set then no producers can be voted for
* @pre every listed producer or proxy must have been previously registered
* @pre vp.voter must authorize this action
* @pre voter must have previously staked some EOS for voting
*/
static
void
on
(
const
voteproducer
&
vp
)
{
eosio_assert
(
std
::
is_sorted
(
vp
.
producers
.
begin
(),
vp
.
producers
.
end
()
),
"producer votes must be sorted"
);
eosio_assert
(
vp
.
producers
.
size
()
<=
30
,
"attempt to vote for too many producers"
);
if
(
vp
.
proxy
!=
0
)
eosio_assert
(
vp
.
producers
.
size
()
==
0
,
"cannot vote for producers and proxy at same time"
);
require_auth
(
vp
.
voter
);
account_votes_index_type
avotes
(
SystemAccount
,
SystemAccount
);
const
auto
&
existing
=
avotes
.
get
(
vp
.
voter
);
std
::
map
<
account_name
,
pair
<
uint128_t
,
uint128_t
>
>
producer_vote_changes
;
uint128_t
old_weight
=
existing
.
staked
.
quantity
;
/// old time
uint128_t
new_weight
=
old_weight
;
/// TODO: update for current weight
for
(
const
auto
&
p
:
existing
.
producers
)
producer_vote_changes
[
p
].
first
=
old_weight
;
for
(
const
auto
&
p
:
vp
.
producers
)
producer_vote_changes
[
p
].
second
=
new_weight
;
producer_votes_index_type
votes
(
SystemAccount
,
SystemAccount
);
for
(
const
auto
&
delta
:
producer_vote_changes
)
{
if
(
delta
.
second
.
first
!=
delta
.
second
.
second
)
{
const
auto
&
provote
=
votes
.
get
(
delta
.
first
);
votes
.
update
(
provote
,
0
,
[
&
](
auto
&
pv
){
pv
.
total_votes
-=
delta
.
second
.
first
;
pv
.
total_votes
+=
delta
.
second
.
second
;
});
}
}
avotes
.
update
(
existing
,
0
,
[
&
](
auto
&
av
)
{
av
.
proxy
=
vp
.
proxy
;
av
.
last_update
=
now
();
av
.
producers
=
vp
.
producers
;
});
}
ACTION
(
SystemAccount
,
regproxy
)
{
account_name
proxy_to_register
;
EOSLIB_SERIALIZE
(
regproxy
,
(
proxy_to_register
)
)
};
static
void
on
(
const
regproxy
&
reg
)
{
require_auth
(
reg
.
proxy_to_register
);
}
};
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录