Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
7bce267c
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,发现更多精彩内容 >>
提交
7bce267c
编写于
5月 16, 2018
作者:
A
Anton Perkov
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into multisig-optimization-and-system-contract-upgrade
上级
6c6f227e
48ee386b
变更
11
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
412 addition
and
329 deletion
+412
-329
contracts/eosio.system/delegate_bandwidth.cpp
contracts/eosio.system/delegate_bandwidth.cpp
+7
-7
contracts/eosio.system/eosio.system.abi
contracts/eosio.system/eosio.system.abi
+26
-21
contracts/eosio.system/eosio.system.hpp
contracts/eosio.system/eosio.system.hpp
+17
-19
contracts/eosio.system/producer_pay.cpp
contracts/eosio.system/producer_pay.cpp
+59
-96
contracts/eosio.system/voting.cpp
contracts/eosio.system/voting.cpp
+10
-10
contracts/eosiolib/datastream.hpp
contracts/eosiolib/datastream.hpp
+6
-6
contracts/eosiolib/types.h
contracts/eosiolib/types.h
+0
-1
libraries/chain/include/eosio/chain/asset.hpp
libraries/chain/include/eosio/chain/asset.hpp
+1
-1
tests/nodeos_run_test.py
tests/nodeos_run_test.py
+33
-15
tests/testUtils.py
tests/testUtils.py
+60
-14
unittests/eosio.system_tests.cpp
unittests/eosio.system_tests.cpp
+193
-139
未找到文件。
contracts/eosio.system/delegate_bandwidth.cpp
浏览文件 @
7bce267c
...
...
@@ -162,7 +162,7 @@ namespace eosiosystem {
eosio_assert
(
bytes_out
>
0
,
"must reserve a positive amount"
);
_gstate
.
total_ram_bytes_reserved
+=
uint64_t
(
bytes_out
);
_gstate
.
total_ram_stake
.
amount
+=
quant
.
amount
;
_gstate
.
total_ram_stake
+=
quant
.
amount
;
user_resources_table
userres
(
_self
,
receiver
);
auto
res_itr
=
userres
.
find
(
receiver
);
...
...
@@ -185,28 +185,28 @@ namespace eosiosystem {
* refunds the purchase price to the account. In this way there is no profit to be made through buying
* and selling ram.
*/
void
system_contract
::
sellram
(
account_name
account
,
u
int64_t
bytes
)
{
void
system_contract
::
sellram
(
account_name
account
,
int64_t
bytes
)
{
require_auth
(
account
);
int64_t
ibytes
=
static_cast
<
int64_t
>
(
bytes
);
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
>=
i
bytes
,
"insufficient quota"
);
eosio_assert
(
res_itr
->
ram_bytes
>=
bytes
,
"insufficient quota"
);
asset
tokens_out
;
auto
itr
=
_rammarket
.
find
(
S
(
4
,
RAMEOS
));
_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
(
i
bytes
,
S
(
0
,
RAM
)),
S
(
4
,
EOS
)
);
tokens_out
=
es
.
convert
(
asset
(
bytes
,
S
(
0
,
RAM
)),
S
(
4
,
EOS
)
);
// print( "out: ", tokens_out, "\n" );
});
_gstate
.
total_ram_bytes_reserved
-=
bytes
;
_gstate
.
total_ram_stake
.
amount
-=
tokens_out
.
amount
;
_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
.
amount
>=
0
,
"error, attempt to unstake more tokens than previously staked"
);
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
;
...
...
contracts/eosio.system/eosio.system.abi
浏览文件 @
7bce267c
...
...
@@ -87,24 +87,26 @@
"name": "blockchain_parameters",
"base": "",
"fields": [
{"name":"max_block_net_usage", "type": "uint32"},
{"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":"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": "uint64"},
{"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":"max_generated_transaction_count", "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":"max_generated_transaction_count", "type":"uint32"}
]
},{
"name": "eosio_parameters",
...
...
@@ -117,13 +119,16 @@
"base": "eosio_parameters",
"fields": [
{"name":"total_ram_bytes_reserved", "type":"uint64"},
{"name":"total_ram_stake", "type":"
asset
"},
{"name":"total_ram_stake", "type":"
int64
"},
{"name":"last_producer_schedule_update", "type":"time_point_sec"},
{"name":"last_pervote_bucket_fill", "type":"uint64"},
{"name":"pervote_bucket", "type":"asset"},
{"name":"savings", "type":"asset"},
{"name":"pervote_bucket", "type":"int64"},
{"name":"perblock_bucket", "type":"int64"},
{"name":"savings", "type":"int64"},
{"name":"total_unpaid_blocks", "type":"uint32"},
{"name":"total_activated_stake", "type":"int64"},
{"name":"last_producer_schedule_id", "type":"checksum160"},
{"name":"total_
activatied_stake", "type":"in
t64"}
{"name":"total_
producer_vote_weight", "type":"floa
t64"}
]
},{
"name": "producer_info",
...
...
@@ -133,7 +138,7 @@
{"name":"total_votes", "type":"float64"},
{"name":"producer_key", "type":"public_key"},
{"name":"url", "type":"string"},
{"name":"
produced_blocks",
"type":"uint32"},
{"name":"
unpaid_blocks",
"type":"uint32"},
{"name":"last_claim_time", "type":"uint64"},
{"name":"location", "type":"uint16"},
{"name":"time_became_active", "type":"uint32"},
...
...
contracts/eosio.system/eosio.system.hpp
浏览文件 @
7bce267c
...
...
@@ -6,6 +6,7 @@
#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>
...
...
@@ -17,6 +18,7 @@ namespace eosiosystem {
using
eosio
::
asset
;
using
eosio
::
indexed_by
;
using
eosio
::
const_mem_fun
;
using
eosio
::
block_timestamp
;
struct
eosio_parameters
:
eosio
::
blockchain_parameters
{
uint64_t
max_ram_size
=
64ll
*
1024
*
1024
*
1024
;
...
...
@@ -29,21 +31,23 @@ namespace eosiosystem {
uint64_t
free_ram
()
const
{
return
max_ram_size
-
total_ram_bytes_reserved
;
}
uint64_t
total_ram_bytes_reserved
=
0
;
eosio
::
asset
total_ram_stake
;
int64_t
total_ram_stake
=
0
;
block_timestamp
last_producer_schedule_update
=
0
;
block_timestamp
last_producer_schedule_update
;
uint64_t
last_pervote_bucket_fill
=
0
;
eosio
::
asset
pervote_bucket
;
eosio
::
asset
savings
;
checksum160
last_producer_schedule_id
;
int64_t
pervote_bucket
=
0
;
int64_t
perblock_bucket
=
0
;
int64_t
savings
=
0
;
uint32_t
total_unpaid_blocks
=
0
;
/// all blocks which have been produced but not paid
int64_t
total_activated_stake
=
0
;
checksum160
last_producer_schedule_id
;
double
total_producer_vote_weight
=
0
;
/// the sum of all producer votes
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE_DERIVED
(
eosio_global_state
,
eosio_parameters
,
(
total_ram_bytes_reserved
)(
total_ram_stake
)
(
last_producer_schedule_update
)
(
last_pervote_bucket_fill
)
(
pervote_bucket
)(
savings
)(
last_producer_schedule_id
)(
total_activated_stake
)
)
(
pervote_bucket
)(
perblock_bucket
)(
savings
)(
total_unpaid_blocks
)(
total_activated_stake
)(
last_producer_schedule_id
)(
total_producer_vote_weight
)
)
};
struct
producer_info
{
...
...
@@ -51,11 +55,11 @@ namespace eosiosystem {
double
total_votes
=
0
;
eosio
::
public_key
producer_key
;
/// a packed public key object
std
::
string
url
;
uint32_t
produced_blocks
;
uint32_t
unpaid_blocks
=
0
;
uint64_t
last_claim_time
=
0
;
uint16_t
location
=
0
;
block_timestamp
time_became_active
=
0
;
block_timestamp
last_produced_block_time
=
0
;
block_timestamp
time_became_active
;
block_timestamp
last_produced_block_time
;
uint64_t
primary_key
()
const
{
return
owner
;
}
double
by_votes
()
const
{
return
-
total_votes
;
}
...
...
@@ -63,7 +67,7 @@ namespace eosiosystem {
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE
(
producer_info
,
(
owner
)(
total_votes
)(
producer_key
)(
url
)
(
produce
d_blocks
)(
last_claim_time
)(
location
)
(
unpai
d_blocks
)(
last_claim_time
)(
location
)
(
time_became_active
)(
last_produced_block_time
)
)
};
...
...
@@ -125,7 +129,7 @@ namespace eosiosystem {
~
system_contract
();
// Actions:
void
onblock
(
uint32_t
timestamp_slot
,
account_name
producer
);
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
...
...
@@ -171,7 +175,7 @@ namespace eosiosystem {
* 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
,
u
int64_t
bytes
);
void
sellram
(
account_name
receiver
,
int64_t
bytes
);
/**
* This action is called after the delegation-period to claim all pending
...
...
@@ -197,12 +201,6 @@ namespace eosiosystem {
void
setpriv
(
account_name
account
,
uint8_t
ispriv
);
private:
eosio
::
asset
payment_per_block
(
double
rate
,
const
eosio
::
asset
&
token_supply
,
uint32_t
num_blocks
);
eosio
::
asset
payment_per_vote
(
const
account_name
&
owner
,
double
owners_votes
,
const
eosio
::
asset
&
pervote_bucket
);
eosio
::
asset
supply_growth
(
double
rate
,
const
eosio
::
asset
&
token_supply
,
time
seconds
);
void
update_elected_producers
(
block_timestamp
timestamp
);
// Implementation details:
...
...
contracts/eosio.system/producer_pay.cpp
浏览文件 @
7bce267c
...
...
@@ -6,24 +6,16 @@ namespace eosiosystem {
const
int64_t
min_daily_tokens
=
100
;
const
double
continuous_rate
=
0.04879
;
// 5% annual rate
const
double
perblock_rate
=
0.0025
;
// 0.25%
const
double
standby_rate
=
0.0075
;
// 0.75%
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
);
eosio
::
asset
system_contract
::
payment_per_block
(
double
rate
,
const
eosio
::
asset
&
token_supply
,
uint32_t
num_blocks
)
{
const
int64_t
payment
=
static_cast
<
int64_t
>
(
(
rate
*
double
(
token_supply
.
amount
)
*
double
(
num_blocks
))
/
double
(
blocks_per_year
)
);
return
eosio
::
asset
(
payment
,
token_supply
.
symbol
);
}
const
double
continuous_rate
=
0.04879
;
// 5% annual rate
const
double
perblock_rate
=
0.0025
;
// 0.25%
const
double
standby_rate
=
0.0075
;
// 0.75%
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
;
eosio
::
asset
system_contract
::
supply_growth
(
double
rate
,
const
eosio
::
asset
&
token_supply
,
time
seconds
)
{
const
int64_t
payment
=
static_cast
<
int64_t
>
(
(
rate
*
double
(
token_supply
.
amount
)
*
double
(
seconds
))
/
double
(
seconds_per_year
)
);
return
eosio
::
asset
(
payment
,
token_supply
.
symbol
);
}
void
system_contract
::
onblock
(
block_timestamp
timestamp
,
account_name
producer
)
{
using
namespace
eosio
;
...
...
@@ -37,107 +29,78 @@ namespace eosiosystem {
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
.
produce
d_blocks
++
;
p
.
unpai
d_blocks
++
;
p
.
last_produced_block_time
=
timestamp
;
});
}
/// only update block producers once every minute, block_timestamp is in half seconds
if
(
timestamp
-
_gstate
.
last_producer_schedule_update
>
120
)
{
if
(
timestamp
.
slot
-
_gstate
.
last_producer_schedule_update
.
slot
>
120
)
{
update_elected_producers
(
timestamp
);
}
}
eosio
::
asset
system_contract
::
payment_per_vote
(
const
account_name
&
owner
,
double
owners_votes
,
const
eosio
::
asset
&
pervote_bucket
)
{
eosio
::
asset
payment
(
0
,
S
(
4
,
EOS
));
const
int64_t
min_daily_amount
=
100
*
10000
;
if
(
pervote_bucket
.
amount
<
min_daily_amount
)
{
return
payment
;
}
auto
idx
=
_producers
.
template
get_index
<
N
(
prototalvote
)>();
double
total_producer_votes
=
0
;
double
running_payment_amount
=
0
;
bool
to_be_payed
=
false
;
for
(
auto
itr
=
idx
.
cbegin
();
itr
!=
idx
.
cend
();
++
itr
)
{
if
(
!
(
itr
->
total_votes
>
0
)
)
{
break
;
}
if
(
!
itr
->
active
()
)
{
continue
;
}
if
(
itr
->
owner
==
owner
)
{
to_be_payed
=
true
;
}
total_producer_votes
+=
itr
->
total_votes
;
running_payment_amount
=
(
itr
->
total_votes
)
*
double
(
pervote_bucket
.
amount
)
/
total_producer_votes
;
if
(
running_payment_amount
<
min_daily_amount
)
{
if
(
itr
->
owner
==
owner
)
{
to_be_payed
=
false
;
}
total_producer_votes
-=
itr
->
total_votes
;
break
;
}
}
if
(
to_be_payed
)
{
payment
.
amount
=
static_cast
<
int64_t
>
(
(
double
(
pervote_bucket
.
amount
)
*
owners_votes
)
/
total_producer_votes
);
}
return
payment
;
}
using
namespace
eosio
;
void
system_contract
::
claimrewards
(
const
account_name
&
owner
)
{
using
namespace
eosio
;
require_auth
(
owner
);
auto
prod
=
_producers
.
find
(
owner
);
eosio_assert
(
prod
!=
_producers
.
end
(),
"account name is not in producer list"
);
eosio_assert
(
prod
->
active
(),
"producer does not have an active key"
);
if
(
prod
->
last_claim_time
>
0
)
{
eosio_assert
(
current_time
()
>=
prod
->
last_claim_time
+
useconds_per_day
,
"already claimed rewards within a day"
);
}
const
auto
&
prod
=
_producers
.
get
(
owner
);
eosio_assert
(
prod
.
active
(),
"producer does not have an active key"
);
const
asset
token_supply
=
token
(
N
(
eosio
.
token
)).
get_supply
(
symbol_type
(
system_token_symbol
).
name
()
);
const
uint32_t
secs_since_last_fill
=
static_cast
<
uint32_t
>
(
(
current_time
()
-
_gstate
.
last_pervote_bucket_fill
)
/
1000000
);
auto
ct
=
current_time
();
const
asset
to_pervote_bucket
=
supply_growth
(
standby_rate
,
token_supply
,
secs_since_last_fill
);
const
asset
to_savings
=
supply_growth
(
continuous_rate
-
(
perblock_rate
+
standby_rate
),
token_supply
,
secs_since_last_fill
);
const
asset
perblock_pay
=
payment_per_block
(
perblock_rate
,
token_supply
,
prod
->
produced_blocks
);
const
asset
issue_amount
=
to_pervote_bucket
+
to_savings
+
perblock_pay
;
const
asset
pervote_pay
=
payment_per_vote
(
owner
,
prod
->
total_votes
,
to_pervote_bucket
+
_gstate
.
pervote_bucket
);
eosio_assert
(
ct
-
prod
.
last_claim_time
>
useconds_per_day
,
"already claimed rewards within past day"
);
if
(
perblock_pay
.
amount
+
pervote_pay
.
amount
==
0
)
{
_producers
.
modify
(
prod
,
0
,
[
&
](
auto
&
p
)
{
p
.
last_claim_time
=
current_time
();
});
return
;
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
;
if
(
usecs_since_last_fill
>
0
)
{
auto
new_tokens
=
static_cast
<
int64_t
>
(
(
continuous_rate
*
double
(
token_supply
.
amount
)
*
double
(
usecs_since_last_fill
))
/
double
(
useconds_per_year
)
);
auto
to_producers
=
new_tokens
/
5
;
auto
to_savings
=
new_tokens
-
to_producers
;
auto
to_per_block_pay
=
to_producers
/
4
;
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 and savings"
)}
);
_gstate
.
pervote_bucket
+=
to_per_vote_pay
;
_gstate
.
perblock_bucket
+=
to_per_block_pay
;
_gstate
.
savings
+=
to_savings
;
_gstate
.
last_pervote_bucket_fill
=
ct
;
}
INLINE_ACTION_SENDER
(
eosio
::
token
,
issue
)(
N
(
eosio
.
token
),
{{
N
(
eosio
),
N
(
active
)}},
{
N
(
eosio
),
issue_amount
,
std
::
string
(
"issue tokens for producer pay and savings"
)}
);
_gstate
.
pervote_bucket
+=
(
to_pervote_bucket
-
pervote_pay
)
;
_gstate
.
last_pervote_bucket_fill
=
current_time
(
);
_gstate
.
savings
+=
to_savings
;
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
),
N
(
active
)},
{
N
(
eosio
),
owner
,
perblock_pay
+
pervote_pay
,
std
::
string
(
"producer claiming rewards"
)
}
)
;
int64_t
producer_per_block_pay
=
(
_gstate
.
perblock_bucket
*
prod
.
unpaid_blocks
)
/
_gstate
.
total_unpaid_blocks
;
int64_t
producer_per_vote_pay
=
int64_t
((
_gstate
.
pervote_bucket
*
prod
.
total_votes
)
/
_gstate
.
total_producer_vote_weight
);
if
(
producer_per_vote_pay
<
100'0000
)
{
producer_per_vote_pay
=
0
;
}
int64_t
total_pay
=
producer_per_block_pay
+
producer_per_vote_pay
;
_producers
.
modify
(
prod
,
0
,
[
&
](
auto
&
p
)
{
p
.
last_claim_time
=
current_time
();
p
.
produced_blocks
=
0
;
});
_gstate
.
pervote_bucket
-=
producer_per_vote_pay
;
_gstate
.
perblock_bucket
-=
producer_per_block_pay
;
_gstate
.
total_unpaid_blocks
-=
prod
.
unpaid_blocks
;
_producers
.
modify
(
prod
,
0
,
[
&
](
auto
&
p
)
{
p
.
last_claim_time
=
ct
;
p
.
unpaid_blocks
=
0
;
});
if
(
total_pay
>
0
)
{
INLINE_ACTION_SENDER
(
eosio
::
token
,
transfer
)(
N
(
eosio
.
token
),
{
N
(
eosio
),
N
(
active
)},
{
N
(
eosio
),
owner
,
asset
(
total_pay
),
std
::
string
(
"producer pay"
)
}
);
}
}
}
//namespace eosiosystem
contracts/eosio.system/voting.cpp
浏览文件 @
7bce267c
...
...
@@ -53,7 +53,7 @@ namespace eosiosystem {
_producers
.
emplace
(
producer
,
[
&
](
producer_info
&
info
){
info
.
owner
=
producer
;
info
.
total_votes
=
0
;
info
.
producer_key
=
producer_key
;
info
.
producer_key
=
producer_key
;
info
.
url
=
url
;
info
.
location
=
location
;
});
...
...
@@ -81,15 +81,15 @@ namespace eosiosystem {
for
(
auto
it
=
idx
.
cbegin
();
it
!=
idx
.
cend
()
&&
top_producers
.
size
()
<
21
&&
0
<
it
->
total_votes
;
++
it
)
{
if
(
!
it
->
active
()
)
continue
;
if
(
it
->
time_became_active
==
0
)
{
if
(
it
->
time_became_active
.
slot
==
0
)
{
_producers
.
modify
(
*
it
,
0
,
[
&
](
auto
&
p
)
{
p
.
time_became_active
=
block_time
;
});
}
else
if
(
block_time
>
2
*
21
*
12
+
it
->
time_became_active
&&
block_time
>
it
->
last_produced_block_time
+
blocks_per_day
)
{
}
else
if
(
block_time
.
slot
>
2
*
21
*
12
+
it
->
time_became_active
.
slot
&&
block_time
.
slot
>
it
->
last_produced_block_time
.
slot
+
blocks_per_day
)
{
_producers
.
modify
(
*
it
,
0
,
[
&
](
auto
&
p
)
{
p
.
producer_key
=
public_key
();
p
.
time_became_active
=
0
;
p
.
time_became_active
.
slot
=
0
;
});
continue
;
...
...
@@ -216,9 +216,8 @@ namespace eosiosystem {
if
(
pitr
!=
_producers
.
end
()
)
{
eosio_assert
(
pitr
->
active
()
||
!
pd
.
second
.
second
/* not from new set */
,
"producer is not currently registered"
);
_producers
.
modify
(
pitr
,
0
,
[
&
](
auto
&
p
)
{
print
(
"orig total_votes: "
,
p
.
total_votes
,
" delta: "
,
pd
.
second
.
first
,
"
\n
"
);
p
.
total_votes
+=
pd
.
second
.
first
;
print
(
"new total_votes: "
,
p
.
total_votes
,
"
\n
"
)
;
_gstate
.
total_producer_vote_weight
+=
pd
.
second
.
first
;
//eosio_assert( p.total_votes >= 0, "something bad happened" );
});
}
else
{
...
...
@@ -282,12 +281,13 @@ namespace eosiosystem {
);
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
+=
new_weight
-
voter
.
last_vote_weight
;
}
);
p
.
total_votes
+=
delta
;
_gstate
.
total_producer_vote_weight
+=
delta
;
}
);
}
}
}
...
...
contracts/eosiolib/datastream.hpp
浏览文件 @
7bce267c
...
...
@@ -209,7 +209,7 @@ inline datastream<Stream>& operator>>(datastream<Stream>& ds, bool& d) {
*/
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
<<
(
datastream
<
Stream
>&
ds
,
const
checksum256
&
d
)
{
ds
.
write
(
(
const
char
*
)
&
d
,
sizeof
(
d
)
);
ds
.
write
(
(
const
char
*
)
&
d
.
hash
[
0
],
sizeof
(
d
.
hash
)
);
return
ds
;
}
/**
...
...
@@ -220,7 +220,7 @@ inline datastream<Stream>& operator<<(datastream<Stream>& ds, const checksum256&
*/
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
>>
(
datastream
<
Stream
>&
ds
,
checksum256
&
d
)
{
ds
.
read
((
char
*
)
&
d
,
sizeof
(
d
)
);
ds
.
read
((
char
*
)
&
d
.
hash
[
0
],
sizeof
(
d
.
hash
)
);
return
ds
;
}
...
...
@@ -514,25 +514,25 @@ bytes pack( const T& value ) {
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
<<
(
datastream
<
Stream
>&
ds
,
const
checksum160
&
cs
)
{
ds
.
write
((
const
char
*
)
&
cs
,
sizeof
(
cs
));
ds
.
write
((
const
char
*
)
&
cs
.
hash
[
0
],
sizeof
(
cs
.
hash
));
return
ds
;
}
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
>>
(
datastream
<
Stream
>&
ds
,
checksum160
&
cs
)
{
ds
.
read
((
char
*
)
&
cs
,
sizeof
(
cs
));
ds
.
read
((
char
*
)
&
cs
.
hash
[
0
],
sizeof
(
cs
.
hash
));
return
ds
;
}
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
<<
(
datastream
<
Stream
>&
ds
,
const
checksum512
&
cs
)
{
ds
.
write
((
const
char
*
)
&
cs
,
sizeof
(
cs
));
ds
.
write
((
const
char
*
)
&
cs
.
hash
[
0
],
sizeof
(
cs
.
hash
));
return
ds
;
}
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
>>
(
datastream
<
Stream
>&
ds
,
checksum512
&
cs
)
{
ds
.
read
((
char
*
)
&
cs
,
sizeof
(
cs
));
ds
.
read
((
char
*
)
&
cs
.
hash
[
0
],
sizeof
(
cs
.
hash
));
return
ds
;
}
...
...
contracts/eosiolib/types.h
浏览文件 @
7bce267c
...
...
@@ -24,7 +24,6 @@ typedef uint64_t permission_name;
typedef
uint64_t
token_name
;
typedef
uint64_t
table_name
;
typedef
uint32_t
time
;
typedef
uint32_t
block_timestamp
;
typedef
uint64_t
scope_name
;
typedef
uint64_t
action_name
;
typedef
uint16_t
region_id
;
...
...
libraries/chain/include/eosio/chain/asset.hpp
浏览文件 @
7bce267c
...
...
@@ -7,7 +7,7 @@
#include <eosio/chain/types.hpp>
#include <eosio/chain/symbol.hpp>
/// eos with
8
digits of precision
/// eos with
4
digits of precision
#define EOS_SYMBOL_VALUE (int64_t(4) | (uint64_t('E') << 8) | (uint64_t('O') << 16) | (uint64_t('S') << 24))
static
const
eosio
::
chain
::
symbol
EOS_SYMBOL
(
EOS_SYMBOL_VALUE
);
...
...
tests/nodeos_run_test.py
浏览文件 @
7bce267c
...
...
@@ -101,6 +101,9 @@ try:
cluster
.
initializeNodes
(
defproduceraPrvtKey
=
defproduceraPrvtKey
,
defproducerbPrvtKey
=
defproducerbPrvtKey
)
killEosInstances
=
False
Print
(
"Validating system accounts after bootstrap"
)
cluster
.
validateAccounts
(
None
)
accounts
=
testUtils
.
Cluster
.
createAccountKeys
(
3
)
if
accounts
is
None
:
errorExit
(
"FAILURE - create keys"
)
...
...
@@ -223,12 +226,31 @@ try:
if
node
is
None
:
errorExit
(
"Cluster in bad state, received None node"
)
Print
(
"Validating accounts before user accounts creation"
)
cluster
.
validateAccounts
(
None
)
Print
(
"Create new account %s via %s"
%
(
testeraAccount
.
name
,
defproduceraAccount
.
name
))
transId
=
node
.
createInitializeAccount
(
testeraAccount
,
defproduceraAccount
,
stakedDeposit
=
0
,
waitForTransBlock
=
False
)
if
transId
is
None
:
cmdError
(
"%s create account"
%
(
ClientN
ame
))
cmdError
(
"%s create account"
%
(
testeraAccount
.
n
ame
))
errorExit
(
"Failed to create account %s"
%
(
testeraAccount
.
name
))
Print
(
"Create new account %s via %s"
%
(
currencyAccount
.
name
,
defproducerbAccount
.
name
))
transId
=
node
.
createInitializeAccount
(
currencyAccount
,
defproducerbAccount
,
stakedDeposit
=
5000
)
if
transId
is
None
:
cmdError
(
"%s create account"
%
(
ClientName
))
errorExit
(
"Failed to create account %s"
%
(
currencyAccount
.
name
))
Print
(
"Create new account %s via %s"
%
(
exchangeAccount
.
name
,
defproduceraAccount
.
name
))
transId
=
node
.
createInitializeAccount
(
exchangeAccount
,
defproduceraAccount
,
waitForTransBlock
=
True
)
if
transId
is
None
:
cmdError
(
"%s create account"
%
(
ClientName
))
errorExit
(
"Failed to create account %s"
%
(
exchangeAccount
.
name
))
Print
(
"Validating accounts after user accounts creation"
)
accounts
=
[
testeraAccount
,
currencyAccount
,
exchangeAccount
]
cluster
.
validateAccounts
(
accounts
)
Print
(
"Verify account %s"
%
(
testeraAccount
))
if
not
node
.
verifyAccount
(
testeraAccount
):
errorExit
(
"FAILURE - account creation failed."
,
raw
=
True
)
...
...
@@ -262,17 +284,9 @@ try:
cmdError
(
"FAILURE - transfer failed"
)
errorExit
(
"Transfer verification failed. Excepted %s, actual: %s"
%
(
expectedAmount
,
actualAmount
))
Print
(
"Create new account %s via %s"
%
(
currencyAccount
.
name
,
defproducerbAccount
.
name
))
transId
=
node
.
createInitializeAccount
(
currencyAccount
,
defproducerbAccount
,
stakedDeposit
=
5000
)
if
transId
is
None
:
cmdError
(
"%s create account"
%
(
ClientName
))
errorExit
(
"Failed to create account %s"
%
(
currencyAccount
.
name
))
Print
(
"Create new account %s via %s"
%
(
exchangeAccount
.
name
,
defproduceraAccount
.
name
))
transId
=
node
.
createInitializeAccount
(
exchangeAccount
,
defproduceraAccount
,
waitForTransBlock
=
True
)
if
transId
is
None
:
cmdError
(
"%s create account"
%
(
ClientName
))
errorExit
(
"Failed to create account %s"
%
(
exchangeAccount
.
name
))
Print
(
"Validating accounts after some user trasactions"
)
accounts
=
[
testeraAccount
,
currencyAccount
,
exchangeAccount
]
cluster
.
validateAccounts
(
accounts
)
Print
(
"Locking all wallets."
)
if
not
walletMgr
.
lockAllWallets
():
...
...
@@ -306,7 +320,7 @@ try:
assert
(
actions
)
try
:
assert
(
actions
[
"actions"
][
0
][
"action_trace"
][
"act"
][
"name"
]
==
"transfer"
)
except
(
AssertionError
,
KeyError
)
as
e
:
except
(
AssertionError
,
TypeError
,
KeyError
)
as
e
:
Print
(
"Last action validation failed. Actions: %s"
%
(
actions
))
raise
...
...
@@ -381,7 +395,7 @@ try:
typeVal
=
transaction
[
"name"
]
amountVal
=
transaction
[
"data"
][
"quantity"
]
amountVal
=
int
(
decimal
.
Decimal
(
amountVal
.
split
()[
0
])
*
10000
)
except
(
Assertion
Error
,
KeyError
)
as
e
:
except
(
Type
Error
,
KeyError
)
as
e
:
Print
(
"Transaction validation parsing failed. Transaction: %s"
%
(
transaction
))
raise
...
...
@@ -605,7 +619,7 @@ try:
# errorExit("mongo get messages by transaction id %s" % (transId))
Print
(
"Request invalid block numbered %d. This will generate an ex
t
pected error message."
%
(
currentBlockNum
+
1000
))
Print
(
"Request invalid block numbered %d. This will generate an expected error message."
%
(
currentBlockNum
+
1000
))
block
=
node
.
getBlock
(
currentBlockNum
+
1000
,
silentErrors
=
True
,
retry
=
False
)
if
block
is
not
None
:
errorExit
(
"ERROR: Received block where not expected"
)
...
...
@@ -627,6 +641,10 @@ try:
Print
(
"WARNING: Asserts in var/lib/node_00/stderr.txt"
)
#errorExit("FAILURE - Assert in var/lib/node_00/stderr.txt")
Print
(
"Validating accounts at end of test"
)
accounts
=
[
testeraAccount
,
currencyAccount
,
exchangeAccount
]
cluster
.
validateAccounts
(
accounts
)
testSuccessful
=
True
finally
:
if
testSuccessful
:
...
...
tests/testUtils.py
浏览文件 @
7bce267c
...
...
@@ -278,6 +278,22 @@ class Node(object):
def
setWalletEndpointArgs
(
self
,
args
):
self
.
endpointArgs
=
"--url http://%s:%d %s"
%
(
self
.
host
,
self
.
port
,
args
)
def
validateAccounts
(
self
,
accounts
):
assert
(
accounts
)
assert
(
isinstance
(
accounts
,
list
))
for
account
in
accounts
:
assert
(
account
)
assert
(
isinstance
(
account
,
Account
))
if
Utils
.
Debug
:
Utils
.
Print
(
"Validating account %s"
%
(
account
.
name
))
accountInfo
=
self
.
getEosAccount
(
account
.
name
)
try
:
assert
(
accountInfo
)
assert
(
accountInfo
[
"account_name"
]
==
account
.
name
)
except
(
AssertionError
,
TypeError
,
KeyError
)
as
_
:
Utils
.
Print
(
"account validation failed. account: %s"
%
(
account
.
name
))
raise
# pylint: disable=too-many-branches
def
getBlock
(
self
,
blockNum
,
retry
=
True
,
silentErrors
=
False
):
if
not
self
.
enableMongo
:
...
...
@@ -337,15 +353,18 @@ class Node(object):
def
doesNodeHaveBlockNum
(
self
,
blockNum
):
assert
isinstance
(
blockNum
,
int
)
assert
(
blockNum
>
0
)
info
=
self
.
getInfo
(
silentErrors
=
True
)
if
info
is
None
:
return
False
last_irreversible_block_num
=
int
(
info
[
"last_irreversible_block_num"
])
if
blockNum
>
last_irreversible_block_num
:
return
False
else
:
return
True
assert
(
info
)
last_irreversible_block_num
=
0
try
:
last_irreversible_block_num
=
int
(
info
[
"last_irreversible_block_num"
])
except
(
TypeError
,
KeyError
)
as
_
:
Utils
.
Print
(
"Failure in get info parsing. %s"
%
(
trans
))
raise
return
True
if
blockNum
<=
last_irreversible_block_num
else
True
# pylint: disable=too-many-branches
def
getTransaction
(
self
,
transId
,
retry
=
True
,
silentErrors
=
False
):
...
...
@@ -452,16 +471,21 @@ class Node(object):
return
None
def
doesNodeHaveTransId
(
self
,
transId
):
trans
=
self
.
getTransaction
(
transId
,
silentErrors
=
True
)
def
doesNodeHaveTransId
(
self
,
transId
,
silentErrors
=
True
):
trans
=
self
.
getTransaction
(
transId
,
silentErrors
)
if
trans
is
None
:
return
False
blockNum
=
None
if
not
self
.
enableMongo
:
blockNum
=
int
(
trans
[
"trx"
][
"trx"
][
"ref_block_num"
])
else
:
blockNum
=
int
(
trans
[
"ref_block_num"
])
try
:
if
not
self
.
enableMongo
:
blockNum
=
int
(
trans
[
"trx"
][
"trx"
][
"ref_block_num"
])
else
:
blockNum
=
int
(
trans
[
"ref_block_num"
])
except
(
TypeError
,
KeyError
)
as
_
:
if
not
silentErrors
:
Utils
.
Print
(
"Failure in transaction parsing. %s"
%
(
trans
))
return
False
blockNum
+=
1
if
Utils
.
Debug
:
Utils
.
Print
(
"Check if block %d is irreversible."
%
(
blockNum
))
...
...
@@ -521,6 +545,7 @@ class Node(object):
return
trans
def
getEosAccount
(
self
,
name
):
assert
(
isinstance
(
name
,
str
))
cmd
=
"%s %s get account -j %s"
%
(
Utils
.
EosClientPath
,
self
.
endpointArgs
,
name
)
if
Utils
.
Debug
:
Utils
.
Print
(
"cmd: %s"
%
(
cmd
))
try
:
...
...
@@ -563,7 +588,7 @@ class Node(object):
assert
(
trans
)
try
:
return
trans
[
"rows"
][
0
][
"balance"
]
except
(
Assertion
Error
,
KeyError
)
as
e
:
except
(
Type
Error
,
KeyError
)
as
e
:
print
(
"Transaction parsing failed. Transaction: %s"
%
(
trans
))
raise
...
...
@@ -1595,6 +1620,19 @@ class Cluster(object):
return
True
def
validateAccounts
(
self
,
accounts
,
testSysAccounts
=
True
):
assert
(
len
(
self
.
nodes
)
>
0
)
node
=
self
.
nodes
[
0
]
myAccounts
=
[]
if
testSysAccounts
:
myAccounts
+=
[
self
.
eosioAccount
,
self
.
defproduceraAccount
,
self
.
defproducerbAccount
]
if
accounts
:
assert
(
isinstance
(
accounts
,
list
))
myAccounts
+=
accounts
node
.
validateAccounts
(
myAccounts
)
# create account, verify account and return transaction id
def
createAccountAndVerify
(
self
,
account
,
creator
,
stakedDeposit
=
1000
):
assert
(
len
(
self
.
nodes
)
>
0
)
...
...
@@ -1746,7 +1784,9 @@ class Cluster(object):
Utils
.
Print
(
"Creating accounts: %s "
%
", "
.
join
(
producerKeys
.
keys
()))
producerKeys
.
pop
(
eosioName
)
accounts
=
[]
for
name
,
keys
in
producerKeys
.
items
():
initx
=
None
initx
=
Account
(
name
)
initx
.
ownerPrivateKey
=
keys
[
"private"
]
initx
.
ownerPublicKey
=
keys
[
"public"
]
...
...
@@ -1757,10 +1797,14 @@ class Cluster(object):
Utils
.
Print
(
"ERROR: Failed to create account %s"
%
(
name
))
return
False
Node
.
validateTransaction
(
trans
)
accounts
.
append
(
initx
)
transId
=
Node
.
getTransId
(
trans
)
biosNode
.
waitForTransIdOnNode
(
transId
)
Utils
.
Print
(
"Validating system accounts within bootstrap"
)
biosNode
.
validateAccounts
(
accounts
)
if
not
onlyBios
:
if
prodCount
==
-
1
:
setProdsFile
=
"setprods.json"
...
...
@@ -1845,6 +1889,8 @@ class Cluster(object):
return
False
Node
.
validateTransaction
(
trans
[
1
])
transId
=
Node
.
getTransId
(
trans
[
1
])
biosNode
.
waitForTransIdOnNode
(
transId
)
contract
=
eosioTokenAccount
.
name
Utils
.
Print
(
"push issue action to %s contract"
%
(
contract
))
...
...
unittests/eosio.system_tests.cpp
浏览文件 @
7bce267c
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录