Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
5a520fb2
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,发现更多精彩内容 >>
未验证
提交
5a520fb2
编写于
6月 27, 2018
作者:
A
Anton Perkov
提交者:
GitHub
6月 27, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4373 from EOSIO/revert-speculative-state-2
Revert speculative state #4196
上级
e9ad34e6
db7b7896
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
131 addition
and
47 deletion
+131
-47
libraries/chain/controller.cpp
libraries/chain/controller.cpp
+69
-47
libraries/chain/include/eosio/chain/controller.hpp
libraries/chain/include/eosio/chain/controller.hpp
+10
-0
libraries/chain/include/eosio/chain/transaction_context.hpp
libraries/chain/include/eosio/chain/transaction_context.hpp
+1
-0
libraries/chain/transaction_context.cpp
libraries/chain/transaction_context.cpp
+3
-0
plugins/chain_plugin/chain_plugin.cpp
plugins/chain_plugin/chain_plugin.cpp
+45
-0
plugins/producer_plugin/producer_plugin.cpp
plugins/producer_plugin/producer_plugin.cpp
+3
-0
未找到文件。
libraries/chain/controller.cpp
浏览文件 @
5a520fb2
...
...
@@ -57,6 +57,7 @@ struct controller_impl {
controller
::
config
conf
;
chain_id_type
chain_id
;
bool
replaying
=
false
;
db_read_mode
read_mode
=
db_read_mode
::
SPECULATIVE
;
bool
in_trx_requiring_checks
=
false
;
///< if true, checks that are normally skipped on replay (e.g. auth checks) cannot be skipped
typedef
pair
<
scope_name
,
action_name
>
handler_key
;
...
...
@@ -78,8 +79,10 @@ struct controller_impl {
reversible_blocks
.
remove
(
*
b
);
}
for
(
const
auto
&
t
:
head
->
trxs
)
unapplied_transactions
[
t
->
signed_id
]
=
t
;
if
(
read_mode
==
db_read_mode
::
SPECULATIVE
)
{
for
(
const
auto
&
t
:
head
->
trxs
)
unapplied_transactions
[
t
->
signed_id
]
=
t
;
}
head
=
prev
;
db
.
undo
();
...
...
@@ -104,7 +107,8 @@ struct controller_impl {
resource_limits
(
db
),
authorization
(
s
,
db
),
conf
(
cfg
),
chain_id
(
cfg
.
genesis
.
compute_chain_id
()
)
chain_id
(
cfg
.
genesis
.
compute_chain_id
()
),
read_mode
(
cfg
.
read_mode
)
{
#define SET_APP_HANDLER( receiver, contract, action) \
...
...
@@ -699,8 +703,14 @@ struct controller_impl {
emit
(
self
.
applied_transaction
,
trace
);
trx_context
.
squash
();
restore
.
cancel
();
if
(
read_mode
!=
db_read_mode
::
SPECULATIVE
&&
pending
->
_block_status
==
controller
::
block_status
::
incomplete
)
{
//this may happen automatically in destructor, but I prefere make it more explicit
trx_context
.
undo
();
}
else
{
restore
.
cancel
();
trx_context
.
squash
();
}
if
(
!
implicit
)
{
unapplied_transactions
.
erase
(
trx
->
signed_id
);
...
...
@@ -741,48 +751,50 @@ struct controller_impl {
auto
was_pending_promoted
=
pending
->
_pending_block_state
->
maybe_promote_pending
();
//modify state in speculative block only if we are speculative reads mode (other wise we need clean state for head or irreversible reads)
if
(
read_mode
==
db_read_mode
::
SPECULATIVE
||
pending
->
_block_status
!=
controller
::
block_status
::
incomplete
)
{
const
auto
&
gpo
=
db
.
get
<
global_property_object
>
();
if
(
gpo
.
proposed_schedule_block_num
.
valid
()
&&
// if there is a proposed schedule that was proposed in a block ...
(
*
gpo
.
proposed_schedule_block_num
<=
pending
->
_pending_block_state
->
dpos_irreversible_blocknum
)
&&
// ... that has now become irreversible ...
pending
->
_pending_block_state
->
pending_schedule
.
producers
.
size
()
==
0
&&
// ... and there is room for a new pending schedule ...
!
was_pending_promoted
// ... and not just because it was promoted to active at the start of this block, then:
)
{
// Promote proposed schedule to pending schedule.
if
(
!
replaying
)
{
ilog
(
"promoting proposed schedule (set in block ${proposed_num}) to pending; current block: ${n} lib: ${lib} schedule: ${schedule} "
,
(
"proposed_num"
,
*
gpo
.
proposed_schedule_block_num
)(
"n"
,
pending
->
_pending_block_state
->
block_num
)
(
"lib"
,
pending
->
_pending_block_state
->
dpos_irreversible_blocknum
)
(
"schedule"
,
static_cast
<
producer_schedule_type
>
(
gpo
.
proposed_schedule
)
)
);
}
pending
->
_pending_block_state
->
set_new_producers
(
gpo
.
proposed_schedule
);
db
.
modify
(
gpo
,
[
&
](
auto
&
gp
)
{
gp
.
proposed_schedule_block_num
=
optional
<
block_num_type
>
();
gp
.
proposed_schedule
.
clear
();
});
}
const
auto
&
gpo
=
db
.
get
<
global_property_object
>
(
);
if
(
gpo
.
proposed_schedule_block_num
.
valid
()
&&
// if there is a proposed schedule that was proposed in a block ...
(
*
gpo
.
proposed_schedule_block_num
<=
pending
->
_pending_block_state
->
dpos_irreversible_blocknum
)
&&
// ... that has now become irreversible ...
pending
->
_pending_block_state
->
pending_schedule
.
producers
.
size
()
==
0
&&
// ... and there is room for a new pending schedule ...
!
was_pending_promoted
// ... and not just because it was promoted to active at the start of this block, then:
)
{
// Promote proposed schedule to pending schedule.
if
(
!
replaying
)
{
ilog
(
"promoting proposed schedule (set in block ${proposed_num}) to pending; current block: ${n} lib: ${lib} schedule: ${schedule} "
,
(
"proposed_num"
,
*
gpo
.
proposed_schedule_block_num
)(
"n"
,
pending
->
_pending_block_state
->
block_num
)
(
"lib"
,
pending
->
_pending_block_state
->
dpos_irreversible_blocknum
)
(
"schedule"
,
static_cast
<
producer_schedule_type
>
(
gpo
.
proposed_schedule
)
)
);
try
{
auto
onbtrx
=
std
::
make_shared
<
transaction_metadata
>
(
get_on_block_transaction
()
);
auto
reset_in_trx_requiring_checks
=
fc
::
make_scoped_exit
([
old_value
=
in_trx_requiring_checks
,
this
](){
in_trx_requiring_checks
=
old_value
;
});
in_trx_requiring_checks
=
true
;
push_transaction
(
onbtrx
,
fc
::
time_point
::
maximum
(),
true
,
self
.
get_global_properties
().
configuration
.
min_transaction_cpu_usage
);
}
catch
(
const
boost
::
interprocess
::
bad_alloc
&
e
)
{
elog
(
"on block transaction failed due to a bad allocation"
);
throw
;
}
catch
(
const
fc
::
exception
&
e
)
{
wlog
(
"on block transaction failed, but shouldn't impact block generation, system contract needs update"
);
edump
((
e
.
to_detail_string
()));
}
catch
(
...
)
{
}
pending
->
_pending_block_state
->
set_new_producers
(
gpo
.
proposed_schedule
);
db
.
modify
(
gpo
,
[
&
](
auto
&
gp
)
{
gp
.
proposed_schedule_block_num
=
optional
<
block_num_type
>
();
gp
.
proposed_schedule
.
clear
();
});
}
try
{
auto
onbtrx
=
std
::
make_shared
<
transaction_metadata
>
(
get_on_block_transaction
()
);
auto
reset_in_trx_requiring_checks
=
fc
::
make_scoped_exit
([
old_value
=
in_trx_requiring_checks
,
this
](){
in_trx_requiring_checks
=
old_value
;
});
in_trx_requiring_checks
=
true
;
push_transaction
(
onbtrx
,
fc
::
time_point
::
maximum
(),
true
,
self
.
get_global_properties
().
configuration
.
min_transaction_cpu_usage
);
}
catch
(
const
boost
::
interprocess
::
bad_alloc
&
e
)
{
elog
(
"on block transaction failed due to a bad allocation"
);
throw
;
}
catch
(
const
fc
::
exception
&
e
)
{
wlog
(
"on block transaction failed, but shouldn't impact block generation, system contract needs update"
);
edump
((
e
.
to_detail_string
()));
}
catch
(
...
)
{
wlog
(
"on block transaction failed, but shouldn't impact block generation, system contract needs update"
);
clear_expired_input_transactions
();
update_producers_authority
();
}
clear_expired_input_transactions
();
update_producers_authority
();
guard_pending
.
cancel
();
}
// start_block
...
...
@@ -939,8 +951,10 @@ struct controller_impl {
void
abort_block
()
{
if
(
pending
)
{
for
(
const
auto
&
t
:
pending
->
_pending_block_state
->
trxs
)
unapplied_transactions
[
t
->
signed_id
]
=
t
;
if
(
read_mode
==
db_read_mode
::
SPECULATIVE
)
{
for
(
const
auto
&
t
:
pending
->
_pending_block_state
->
trxs
)
unapplied_transactions
[
t
->
signed_id
]
=
t
;
}
pending
.
reset
();
}
}
...
...
@@ -1416,6 +1430,10 @@ chain_id_type controller::get_chain_id()const {
return
my
->
chain_id
;
}
db_read_mode
controller
::
get_read_mode
()
const
{
return
my
->
read_mode
;
}
const
apply_handler
*
controller
::
find_apply_handler
(
account_name
receiver
,
account_name
scope
,
action_name
act
)
const
{
auto
native_handler_scope
=
my
->
apply_handlers
.
find
(
receiver
);
...
...
@@ -1437,9 +1455,13 @@ const account_object& controller::get_account( account_name name )const
vector
<
transaction_metadata_ptr
>
controller
::
get_unapplied_transactions
()
const
{
vector
<
transaction_metadata_ptr
>
result
;
result
.
reserve
(
my
->
unapplied_transactions
.
size
());
for
(
const
auto
&
entry
:
my
->
unapplied_transactions
)
{
result
.
emplace_back
(
entry
.
second
);
if
(
my
->
read_mode
==
db_read_mode
::
SPECULATIVE
)
{
result
.
reserve
(
my
->
unapplied_transactions
.
size
());
for
(
const
auto
&
entry
:
my
->
unapplied_transactions
)
{
result
.
emplace_back
(
entry
.
second
);
}
}
else
{
EOS_ASSERT
(
my
->
unapplied_transactions
.
empty
(),
transaction_exception
,
"not empty unapplied_transactions in non-speculative mode"
);
//should never happen
}
return
result
;
}
...
...
libraries/chain/include/eosio/chain/controller.hpp
浏览文件 @
5a520fb2
...
...
@@ -33,8 +33,14 @@ namespace eosio { namespace chain {
class
fork_database
;
enum
class
db_read_mode
{
SPECULATIVE
,
HEAD
};
class
controller
{
public:
struct
config
{
flat_set
<
account_name
>
actor_whitelist
;
flat_set
<
account_name
>
actor_blacklist
;
...
...
@@ -52,6 +58,8 @@ namespace eosio { namespace chain {
genesis_state
genesis
;
wasm_interface
::
vm_type
wasm_runtime
=
chain
::
config
::
default_wasm_runtime
;
db_read_mode
read_mode
=
db_read_mode
::
SPECULATIVE
;
};
enum
class
block_status
{
...
...
@@ -180,6 +188,8 @@ namespace eosio { namespace chain {
chain_id_type
get_chain_id
()
const
;
db_read_mode
get_read_mode
()
const
;
signal
<
void
(
const
block_state_ptr
&
)
>
accepted_block_header
;
signal
<
void
(
const
block_state_ptr
&
)
>
accepted_block
;
signal
<
void
(
const
block_state_ptr
&
)
>
irreversible_block
;
...
...
libraries/chain/include/eosio/chain/transaction_context.hpp
浏览文件 @
5a520fb2
...
...
@@ -26,6 +26,7 @@ namespace eosio { namespace chain {
void
exec
();
void
finalize
();
void
squash
();
void
undo
();
inline
void
add_net_usage
(
uint64_t
u
)
{
net_usage
+=
u
;
check_net_usage
();
}
...
...
libraries/chain/transaction_context.cpp
浏览文件 @
5a520fb2
...
...
@@ -265,6 +265,9 @@ namespace eosio { namespace chain {
undo_session
.
squash
();
}
void
transaction_context
::
undo
()
{
undo_session
.
undo
();
}
void
transaction_context
::
check_net_usage
()
const
{
if
(
BOOST_UNLIKELY
(
net_usage
>
eager_net_limit
)
)
{
...
...
plugins/chain_plugin/chain_plugin.cpp
浏览文件 @
5a520fb2
...
...
@@ -13,6 +13,7 @@
#include <eosio/chain/wasm_interface.hpp>
#include <eosio/chain/resource_limits.hpp>
#include <eosio/chain/reversible_block_object.hpp>
#include <eosio/chain/controller.hpp>
#include <eosio/chain/eosio_contract.hpp>
...
...
@@ -30,6 +31,43 @@
namespace
eosio
{
//declare operator<< and validate funciton for read_mode in the same namespace as read_mode itself
namespace
chain
{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
osm
,
eosio
::
chain
::
db_read_mode
m
)
{
if
(
m
==
eosio
::
chain
::
db_read_mode
::
SPECULATIVE
)
{
osm
<<
"speculative"
;
}
else
if
(
m
==
eosio
::
chain
::
db_read_mode
::
HEAD
)
{
osm
<<
"head"
;
}
return
osm
;
}
void
validate
(
boost
::
any
&
v
,
std
::
vector
<
std
::
string
>
const
&
values
,
eosio
::
chain
::
db_read_mode
*
/* target_type */
,
int
)
{
using
namespace
boost
::
program_options
;
// Make sure no previous assignment to 'v' was made.
validators
::
check_first_occurrence
(
v
);
// Extract the first string from 'values'. If there is more than
// one string, it's an error, and exception will be thrown.
std
::
string
const
&
s
=
validators
::
get_single_string
(
values
);
if
(
s
==
"speculative"
)
{
v
=
boost
::
any
(
eosio
::
chain
::
db_read_mode
::
SPECULATIVE
);
}
else
if
(
s
==
"head"
)
{
v
=
boost
::
any
(
eosio
::
chain
::
db_read_mode
::
HEAD
);
}
else
{
throw
validation_error
(
validation_error
::
invalid_option_value
);
}
}
}
using
namespace
eosio
;
using
namespace
eosio
::
chain
;
using
namespace
eosio
::
chain
::
config
;
...
...
@@ -145,6 +183,8 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip
"Action (in the form code::action) added to action blacklist (may specify multiple times)"
)
(
"key-blacklist"
,
boost
::
program_options
::
value
<
vector
<
string
>>
()
->
composing
()
->
multitoken
(),
"Public key added to blacklist of keys that should not be included in authorities (may specify multiple times)"
)
(
"read-mode"
,
boost
::
program_options
::
value
<
eosio
::
chain
::
db_read_mode
>
()
->
default_value
(
eosio
::
chain
::
db_read_mode
::
SPECULATIVE
),
"Database read mode (
\"
speculative
\"
or
\"
head
\"
)"
)
;
// TODO: rate limiting
...
...
@@ -177,6 +217,7 @@ void chain_plugin::set_program_options(options_description& cli, options_descrip
(
"truncate-at-block"
,
bpo
::
value
<
uint32_t
>
()
->
default_value
(
0
),
"stop hard replay / block log recovery at this block number (if set to non-zero number)"
)
;
}
#define LOAD_VALUE_SET(options, name, container) \
...
...
@@ -395,6 +436,10 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
wlog
(
"Starting up fresh blockchain with default genesis state."
);
}
if
(
options
.
count
(
"read-mode"
)
)
{
my
->
chain_config
->
read_mode
=
options
.
at
(
"read-mode"
).
as
<
db_read_mode
>
();
}
my
->
chain
.
emplace
(
*
my
->
chain_config
);
my
->
chain_id
.
emplace
(
my
->
chain
->
get_chain_id
());
...
...
plugins/producer_plugin/producer_plugin.cpp
浏览文件 @
5a520fb2
...
...
@@ -577,6 +577,9 @@ void producer_plugin::plugin_startup()
ilog
(
"producer plugin: plugin_startup() begin"
);
chain
::
controller
&
chain
=
app
().
get_plugin
<
chain_plugin
>
().
chain
();
FC_ASSERT
(
my
->
_producers
.
empty
()
||
chain
.
get_read_mode
()
==
chain
::
db_read_mode
::
SPECULATIVE
,
"node cannot have any producer-name configured because block production is impossible when read_mode is not
\"
speculative
\"
"
);
my
->
_accepted_block_connection
.
emplace
(
chain
.
accepted_block
.
connect
(
[
this
](
const
auto
&
bsp
){
my
->
on_block
(
bsp
);
}
));
my
->
_irreversible_block_connection
.
emplace
(
chain
.
irreversible_block
.
connect
(
[
this
](
const
auto
&
bsp
){
my
->
on_irreversible_block
(
bsp
->
block
);
}
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录