Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
9a5dbab4
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,发现更多精彩内容 >>
提交
9a5dbab4
编写于
4月 11, 2018
作者:
D
Daniel Larimer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
progress
上级
bc836de8
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
190 addition
and
83 deletion
+190
-83
libraries/chain2/CMakeLists.txt
libraries/chain2/CMakeLists.txt
+1
-0
libraries/chain2/block_header_state.cpp
libraries/chain2/block_header_state.cpp
+30
-40
libraries/chain2/block_state.cpp
libraries/chain2/block_state.cpp
+31
-17
libraries/chain2/controller.cpp
libraries/chain2/controller.cpp
+107
-17
libraries/chain2/include/eosio/chain/block_header_state.hpp
libraries/chain2/include/eosio/chain/block_header_state.hpp
+1
-2
libraries/chain2/include/eosio/chain/block_state.hpp
libraries/chain2/include/eosio/chain/block_state.hpp
+2
-0
libraries/chain2/include/eosio/chain/controller.hpp
libraries/chain2/include/eosio/chain/controller.hpp
+18
-7
未找到文件。
libraries/chain2/CMakeLists.txt
浏览文件 @
9a5dbab4
...
...
@@ -9,6 +9,7 @@ add_library( eosio_chain2
block_header_state.cpp
block_state.cpp
fork_database.cpp
controller.cpp
# chain_config.cpp
# block_trace.cpp
# wast_to_wasm.cpp
...
...
libraries/chain2/block_header_state.cpp
浏览文件 @
9a5dbab4
...
...
@@ -4,36 +4,28 @@
namespace
eosio
{
namespace
chain
{
uint32_t
block_header_state
::
calc_dpos_last_irreversible
()
const
{
vector
<
uint32_t
>
irb
;
irb
.
reserve
(
producer_to_last_produced
.
size
()
);
for
(
const
auto
&
item
:
producer_to_last_produced
)
irb
.
push_back
(
item
.
second
);
vector
<
uint32_t
>
irb
;
irb
.
reserve
(
producer_to_last_produced
.
size
()
);
for
(
const
auto
&
item
:
producer_to_last_produced
)
irb
.
push_back
(
item
.
second
);
size_t
offset
=
EOS_PERCENT
(
irb
.
size
(),
config
::
percent_100
-
config
::
irreversible_threshold_percent
);
std
::
nth_element
(
irb
.
begin
(),
irb
.
begin
()
+
offset
,
irb
.
end
()
);
size_t
offset
=
EOS_PERCENT
(
irb
.
size
(),
config
::
percent_100
-
config
::
irreversible_threshold_percent
);
std
::
nth_element
(
irb
.
begin
(),
irb
.
begin
()
+
offset
,
irb
.
end
()
);
return
irb
[
offset
];
return
irb
[
offset
];
}
bool
block_header_state
::
is_active_producer
(
account_name
n
)
const
{
return
producer_to_last_produced
.
find
(
n
)
!=
producer_to_last_produced
.
end
();
return
producer_to_last_produced
.
find
(
n
)
!=
producer_to_last_produced
.
end
();
}
producer_key
block_header_state
::
scheduled_producer
(
block_timestamp_type
t
)
const
{
auto
index
=
t
.
slot
%
(
active_schedule
.
producers
.
size
()
*
config
::
producer_repetitions
);
index
/=
config
::
producer_repetitions
;
return
active_schedule
.
producers
[
index
];
auto
index
=
t
.
slot
%
(
active_schedule
.
producers
.
size
()
*
config
::
producer_repetitions
);
index
/=
config
::
producer_repetitions
;
return
active_schedule
.
producers
[
index
];
}
bool
block_header_state
::
is_start_of_round
(
uint32_t
block_num
)
const
{
return
0
==
(
block_num
%
blocks_per_round
());
}
uint32_t
block_header_state
::
blocks_per_round
()
const
{
return
active_schedule
.
producers
.
size
()
*
config
::
producer_repetitions
;
}
/**
* Transitions the current header state into the next header state given the supplied signed block header.
...
...
@@ -60,30 +52,28 @@ namespace eosio { namespace chain {
FC_ASSERT
(
h
.
block_mroot
==
result
.
blockroot_merkle
.
get_root
(),
"unexpected block merkle root"
);
if
(
result
.
dpos_last_irreversible_blocknum
>=
pending_schedule_lib_num
)
{
result
.
active_schedule
=
move
(
result
.
pending_schedule
);
flat_map
<
account_name
,
uint32_t
>
new_producer_to_last_produced
;
for
(
const
auto
&
pro
:
result
.
active_schedule
.
producers
)
{
auto
existing
=
producer_to_last_produced
.
find
(
pro
.
producer_name
);
if
(
existing
!=
producer_to_last_produced
.
end
()
)
{
new_producer_to_last_produced
[
pro
.
producer_name
]
=
existing
->
second
;
}
else
{
new_producer_to_last_produced
[
pro
.
producer_name
]
=
result
.
dpos_last_irreversible_blocknum
;
}
}
result
.
producer_to_last_produced
=
move
(
new_producer_to_last_produced
);
result
.
active_schedule
=
move
(
result
.
pending_schedule
);
flat_map
<
account_name
,
uint32_t
>
new_producer_to_last_produced
;
for
(
const
auto
&
pro
:
result
.
active_schedule
.
producers
)
{
auto
existing
=
producer_to_last_produced
.
find
(
pro
.
producer_name
);
if
(
existing
!=
producer_to_last_produced
.
end
()
)
{
new_producer_to_last_produced
[
pro
.
producer_name
]
=
existing
->
second
;
}
else
{
new_producer_to_last_produced
[
pro
.
producer_name
]
=
result
.
dpos_last_irreversible_blocknum
;
}
}
result
.
producer_to_last_produced
=
move
(
new_producer_to_last_produced
);
}
if
(
h
.
new_producers
)
{
EOS_ASSERT
(
is_start_of_round
(
result
.
block_num
),
block_validate_exception
,
"Producer changes may only occur at the end of a round."
);
FC_ASSERT
(
h
.
new_producers
->
version
==
result
.
active_schedule
.
version
+
1
,
"wrong producer schedule version specified"
);
FC_ASSERT
(
result
.
pending_schedule
.
producers
.
size
()
==
0
,
"cannot set new pending producers until last pending is confirmed"
);
result
.
pending_schedule
=
*
h
.
new_producers
;
result
.
pending_schedule_hash
=
digest_type
::
hash
(
result
.
pending_schedule
);
result
.
pending_schedule_lib_num
=
h
.
block_num
();
FC_ASSERT
(
h
.
new_producers
->
version
==
result
.
active_schedule
.
version
+
1
,
"wrong producer schedule version specified"
);
FC_ASSERT
(
result
.
pending_schedule
.
producers
.
size
()
==
0
,
"cannot set new pending producers until last pending is confirmed"
);
result
.
pending_schedule
=
*
h
.
new_producers
;
result
.
pending_schedule_hash
=
digest_type
::
hash
(
result
.
pending_schedule
);
result
.
pending_schedule_lib_num
=
h
.
block_num
();
}
result
.
header
=
h
;
...
...
libraries/chain2/block_state.cpp
浏览文件 @
9a5dbab4
...
...
@@ -91,28 +91,42 @@ namespace eosio { namespace chain {
for
(
uint32_t
i
=
1
;
i
<
block
->
regions
.
size
();
++
i
)
FC_ASSERT
(
block
->
regions
[
i
-
1
].
region
<
block
->
regions
[
i
].
region
);
reset_trace
();
bool
found_trx
=
false
;
trace
=
std
::
make_shared
<
block_trace
>
(
block
);
/// reserve region_trace
for
(
uint32_t
r
=
0
;
r
<
block
->
regions
.
size
();
++
r
)
{
// FC_ASSERT( block->regions[r].cycles_summary.size() >= 1, "must be at least one cycle" );
/// reserve cycle traces
for
(
uint32_t
c
=
0
;
c
<
block
->
regions
[
r
].
cycles_summary
.
size
();
c
++
)
{
// FC_ASSERT( block->regions[r].cycles_summary.size() >= 1, "must be at least one shard" );
/// reserve shard traces
for
(
uint32_t
s
=
0
;
s
<
block
->
regions
[
r
].
cycles_summary
[
c
][
s
].
transactions
.
size
();
s
++
)
{
}
// end if block
}
void
block_state
::
reset_trace
()
{
validated
=
false
;
bool
found_trx
=
false
;
trace
=
std
::
make_shared
<
block_trace
>
(
block
);
auto
num_regions
=
block
->
regions
.
size
();
trace
->
region_traces
.
resize
(
num_regions
);
/// reserve region_trace
for
(
uint32_t
r
=
0
;
r
<
num_regions
;
++
r
)
{
auto
num_cycles
=
block
->
regions
[
r
].
cycles_summary
.
size
();
trace
->
region_traces
[
r
].
cycle_traces
.
resize
(
num_cycles
);
// FC_ASSERT( block->regions[r].cycles_summary.size() >= 1, "must be at least one cycle" );
/// reserve cycle traces
for
(
uint32_t
c
=
0
;
c
<
num_cycles
;
c
++
)
{
auto
num_shards
=
block
->
regions
[
r
].
cycles_summary
[
c
].
size
();
trace
->
region_traces
[
r
].
cycle_traces
[
c
].
shard_traces
.
resize
(
num_shards
);
// FC_ASSERT( block->regions[r].cycles_summary.size() >= 1, "must be at least one shard" );
/// reserve shard traces
for
(
uint32_t
s
=
0
;
s
<
num_shards
;
++
s
)
{
validate_shard_locks
(
block
->
regions
[
r
].
cycles_summary
[
c
][
s
],
s
);
auto
num_trx
=
block
->
regions
[
r
].
cycles_summary
[
c
][
s
].
transactions
.
size
();
trace
->
region_traces
[
r
].
cycle_traces
[
c
].
shard_traces
[
s
].
transaction_traces
.
resize
(
num_trx
);
for
(
uint32_t
t
=
0
;
t
<
num_trx
;
++
t
)
{
found_trx
=
true
;
// FC_ASSERT( block->regions[r].cycles.size() >= 1, "must be at least one trx" ); ///
//validate_shard_locks( block->.... )
/// reserve transaction trace...
}
}
}
FC_ASSERT
(
found_trx
,
"a block must contain at least one transaction (the implicit on block trx)"
);
}
// end if block
}
}
FC_ASSERT
(
found_trx
,
"a block must contain at least one transaction (the implicit on block trx)"
);
}
...
...
libraries/chain2/controller.cpp
浏览文件 @
9a5dbab4
#include <eosio/chain/controller.hpp>
#include <chainbase/database.hpp>
#include <chainbase/chainbase.hpp>
#include <eosio/chain/block_log.hpp>
#include <eosio/chain/fork_database.hpp>
#include <eosio/chain/block_summary_object.hpp>
#include <eosio/chain/global_property_object.hpp>
...
...
@@ -18,7 +21,7 @@ using resource_limits::resource_limits_manager;
struct
pending_state
{
pending_state
(
database
::
session
&&
s
)
:
_db_session
(
s
){}
:
_db_session
(
move
(
s
)
){}
block_timestamp_type
_pending_time
;
database
::
session
_db_session
;
...
...
@@ -36,6 +39,19 @@ struct controller_impl {
controller
::
config
conf
;
controller
&
self
;
block_id_type
head_block_id
()
const
{
return
head
->
id
;
}
time_point
head_block_time
()
const
{
return
head
->
header
.
timestamp
;
}
const
block_header
&
head_block_header
()
const
{
return
head
->
header
;
}
void
pop_block
()
{
}
controller_impl
(
const
controller
::
config
&
cfg
,
controller
&
s
)
:
db
(
cfg
.
shared_memory_dir
,
...
...
@@ -66,6 +82,7 @@ struct controller_impl {
}
void
initialize_indicies
()
{
/*
db.add_index<account_index>();
db.add_index<permission_index>();
db.add_index<permission_usage_index>();
...
...
@@ -86,6 +103,7 @@ struct controller_impl {
db.add_index<generated_transaction_multi_index>();
db.add_index<producer_multi_index>();
db.add_index<scope_sequence_multi_index>();
*/
resource_limits
.
initialize_database
();
}
...
...
@@ -114,6 +132,39 @@ struct controller_impl {
}
/**
* This method will backup all tranasctions in the current pending block,
* undo the pending block, call f(), and then push the pending transactions
* on top of the new state.
*/
template
<
typename
Function
>
auto
without_pending_transactions
(
Function
&&
f
)
{
#if 0
vector<transaction_metadata> old_input;
if( _pending_block )
old_input = move(_pending_transaction_metas);
clear_pending();
/** after applying f() push previously input transactions on top */
auto on_exit = fc::make_scoped_exit( [&](){
for( auto& t : old_input ) {
try {
if (!is_known_transaction(t.id))
_push_transaction( std::move(t) );
} catch ( ... ){}
}
});
#endif
pending
.
reset
();
return
f
();
}
block_state_ptr
push_block
(
const
signed_block_ptr
&
b
)
{
return
without_pending_transactions
(
[
&
](){
return
db
.
with_write_lock
(
[
&
](){
...
...
@@ -122,6 +173,7 @@ struct controller_impl {
});
}
block_state_ptr
push_block_impl
(
const
signed_block_ptr
&
b
)
{
auto
head_state
=
fork_db
.
add
(
b
);
...
...
@@ -149,7 +201,8 @@ struct controller_impl {
// pop all blocks from the bad fork
while
(
head_block_id
()
!=
branches
.
second
.
back
()
->
header
.
previous
)
pop_block
();
// re-apply good blocks
for
(
auto
ritr
=
branches
.
second
.
rbegin
();
ritr
!=
branches
.
second
.
rend
();
++
ritr
)
{
apply_block
(
(
*
ritr
)
);
}
...
...
@@ -167,6 +220,7 @@ struct controller_impl {
fork_db
.
set_validity
(
head_state
,
false
);
throw
;
}
return
head
;
}
/// push_block_impl
bool
should_enforce_runtime_limits
()
const
{
...
...
@@ -185,6 +239,7 @@ struct controller_impl {
{
try
{
const
auto
&
b
=
trace
.
block
;
/* TODO RESTORE
update_global_properties( b );
update_global_dynamic_data( b );
update_signing_producer(signing_producer, b);
...
...
@@ -193,18 +248,21 @@ struct controller_impl {
clear_expired_transactions();
update_last_irreversible_block();
resource_limits.process_account_limit_updates();
const auto& chain_config = self.get_global_properties().configuration;
_
resource_limits
.
set_block_parameters
(
resource_limits.set_block_parameters(
{EOS_PERCENT(chain_config.max_block_cpu_usage, chain_config.target_block_cpu_usage_pct), chain_config.max_block_cpu_usage, config::block_cpu_usage_average_window_ms / config::block_interval_ms, 1000, {99, 100}, {1000, 999}},
{EOS_PERCENT(chain_config.max_block_net_usage, chain_config.target_block_net_usage_pct), chain_config.max_block_net_usage, config::block_size_average_window_ms / config::block_interval_ms, 1000, {99, 100}, {1000, 999}}
);
*/
}
FC_CAPTURE_AND_RETHROW
()
}
void
clear_expired_transactions
()
{
//Look for expired transactions in the deduplication list, and remove them.
auto
&
transaction_idx
=
_
db
.
get_mutable_index
<
transaction_multi_index
>
();
auto
&
transaction_idx
=
db
.
get_mutable_index
<
transaction_multi_index
>
();
const
auto
&
dedupe_index
=
transaction_idx
.
indices
().
get
<
by_expiration
>
();
while
(
(
!
dedupe_index
.
empty
())
&&
(
head_block_time
()
>
fc
::
time_point
(
dedupe_index
.
begin
()
->
expiration
)
)
)
{
transaction_idx
.
remove
(
*
dedupe_index
.
begin
());
...
...
@@ -212,10 +270,10 @@ struct controller_impl {
// Look for expired transactions in the pending generated list, and remove them.
// TODO: expire these by sending error to handler
auto
&
generated_transaction_idx
=
_
db
.
get_mutable_index
<
generated_transaction_multi_index
>
();
auto
&
generated_transaction_idx
=
db
.
get_mutable_index
<
generated_transaction_multi_index
>
();
const
auto
&
generated_index
=
generated_transaction_idx
.
indices
().
get
<
by_expiration
>
();
while
(
(
!
generated_index
.
empty
())
&&
(
head_block_time
()
>
generated_index
.
begin
()
->
expiration
)
)
{
_
destroy_generated_transaction
(
*
generated_index
.
begin
());
// TODO:
destroy_generated_transaction(*generated_index.begin());
}
}
...
...
@@ -224,7 +282,7 @@ struct controller_impl {
void
validate_tapos
(
const
transaction
&
trx
)
const
{
if
(
!
should_check_tapos
()
)
return
;
const
auto
&
tapos_block_summary
=
_
db
.
get
<
block_summary_object
>
((
uint16_t
)
trx
.
ref_block_num
);
const
auto
&
tapos_block_summary
=
db
.
get
<
block_summary_object
>
((
uint16_t
)
trx
.
ref_block_num
);
//Verify TaPoS block summary has correct ID prefix, and that this block's time is not past the expiration
EOS_ASSERT
(
trx
.
verify_reference_block
(
tapos_block_summary
.
block_id
),
invalid_ref_block_exception
,
...
...
@@ -232,12 +290,44 @@ struct controller_impl {
(
"tapos_summary"
,
tapos_block_summary
));
}
/**
* At the start of each block we notify the system contract with a transaction that passes in
* the block header of the prior block (which is currently our head block)
*/
transaction
get_on_block_transaction
()
{
action
on_block_act
;
on_block_act
.
account
=
config
::
system_account_name
;
on_block_act
.
name
=
N
(
onblock
);
on_block_act
.
authorization
=
vector
<
permission_level
>
{{
config
::
system_account_name
,
config
::
active_name
}};
on_block_act
.
data
=
fc
::
raw
::
pack
(
head_block_header
());
transaction
trx
;
trx
.
actions
.
emplace_back
(
std
::
move
(
on_block_act
));
trx
.
set_reference_block
(
head_block_id
());
trx
.
expiration
=
head_block_time
()
+
fc
::
seconds
(
1
);
return
trx
;
}
/**
* apply_block
*
* This method starts an undo session, whose revision number should match
* the block number.
*
* It first does some parallel read-only sanity checks on all input transactions.
*
* It then follows the transaction delivery schedule defined by the block_summary.
*
*/
void
apply_block
(
block_state_ptr
bstate
)
{
auto
session
=
_
db
.
start_undo_session
(
true
);
auto
session
=
db
.
start_undo_session
(
true
);
optional
<
fc
::
time_point
>
processing_deadline
;
if
(
should_enforce_runtime_limits
()
)
{
processing_deadline
=
fc
::
time_point
::
now
()
+
c
fg
.
limits
.
max_push_block_us
;
processing_deadline
=
fc
::
time_point
::
now
()
+
c
onf
.
limits
.
max_push_block_us
;
}
auto
&
next_block_trace
=
bstate
->
trace
;
...
...
@@ -251,22 +341,22 @@ struct controller_impl {
validate_net_usage
(
trx
,
item
.
second
->
billable_packed_size
);
}
for
(
uint32_t
region_index
=
0
;
region_index
<
next_block
.
regions
.
size
();
++
region_index
)
{
apply_region
(
region_index
,
next_block_trace
,
bstate
->
block
.
regions
[
region_index
]
);
for
(
uint32_t
region_index
=
0
;
region_index
<
bstate
->
block
->
regions
.
size
();
++
region_index
)
{
apply_region
(
region_index
,
*
bstate
);
}
FC_ASSERT
(
bstate
->
header
.
action_mroot
==
next_block_trace
.
calculate_action_merkle_root
(),
"action merkle root does not match"
);
finalize_block
(
*
next_block_trace
);
"action merkle root does not match"
);
finalize_block
(
*
next_block_trace
);
fork_db
.
set_validity
(
bstate
,
true
);
applied_block
(
next_block_trace
);
/// emit signal to plugins before exiting undo state
self
.
applied_block
(
next_block_trace
);
/// emit signal to plugins before exiting undo state
session
.
push
();
head
=
move
(
bstate
);
}
/// apply_block
void
apply_region
(
uint32_t
region_index
,
block_trace
&
b_trace
,
const
block_state
&
bstate
)
{
void
apply_region
(
uint32_t
region_index
,
const
block_state
&
bstate
)
{
const
auto
&
r
=
bstate
.
block
->
regions
[
region_index
];
EOS_ASSERT
(
!
r
.
cycles_summary
.
empty
(),
tx_empty_region
,
"region[${r_index}] has no cycles"
,
(
"r_index"
,
region_index
));
...
...
libraries/chain2/include/eosio/chain/block_header_state.hpp
浏览文件 @
9a5dbab4
...
...
@@ -21,11 +21,10 @@ struct block_header_state {
flat_map
<
account_name
,
uint32_t
>
producer_to_last_produced
;
block_header_state
next
(
const
signed_block_header
&
h
)
const
;
uint32_t
calc_dpos_last_irreversible
()
const
;
bool
is_active_producer
(
account_name
n
)
const
;
producer_key
scheduled_producer
(
block_timestamp_type
t
)
const
;
bool
is_start_of_round
(
uint32_t
block_num
)
const
;
uint32_t
blocks_per_round
()
const
;
};
...
...
libraries/chain2/include/eosio/chain/block_state.hpp
浏览文件 @
9a5dbab4
...
...
@@ -13,6 +13,8 @@ namespace eosio { namespace chain {
map
<
transaction_id_type
,
transaction_metadata_ptr
>
input_transactions
;
bool
validated
=
false
;
block_trace_ptr
trace
;
void
reset_trace
();
};
typedef
std
::
shared_ptr
<
block_state
>
block_state_ptr
;
...
...
libraries/chain2/include/eosio/chain/controller.hpp
浏览文件 @
9a5dbab4
#pragma once
#include <eosio/chain/block_state.hpp>
#include <eosio/chain/genesis_state.hpp>
#include <boost/signals2/signal.hpp>
namespace
chainbase
{
class
database
;
...
...
@@ -8,6 +11,7 @@ namespace eosio { namespace chain {
struct
controller_impl
;
using
chainbase
::
database
;
using
boost
::
signals2
::
signal
;
class
controller
{
public:
...
...
@@ -18,14 +22,14 @@ namespace eosio { namespace chain {
fc
::
microseconds
max_deferred_transactions_us
=
fc
::
microseconds
(
-
1
);
};
path
block_log_dir
=
config
::
default_block_log_dir
;
path
shared_memory_dir
=
config
::
default_shared_memory_dir
;
uint64_t
shared_memory_size
=
config
::
default_shared_memory_size
;
path
block_log_dir
=
c
hain
::
c
onfig
::
default_block_log_dir
;
path
shared_memory_dir
=
c
hain
::
c
onfig
::
default_shared_memory_dir
;
uint64_t
shared_memory_size
=
c
hain
::
c
onfig
::
default_shared_memory_size
;
bool
read_only
=
false
;
contracts
::
genesis_state_type
genesis
;
genesis_state
genesis
;
runtime_limits
limits
;
wasm_interface
::
vm_type
wasm_runtime
=
config
::
default_wasm_runtime
;
wasm_interface
::
vm_type
wasm_runtime
=
c
hain
::
c
onfig
::
default_wasm_runtime
;
};
...
...
@@ -39,7 +43,7 @@ namespace eosio { namespace chain {
* be pushed.
*/
void
start_block
(
block_timestamp_type
time
);
void
finalize_block
(
signing_lambda
);
//
void finalize_block( signing_lambda );
block_state_ptr
push_block
(
const
signed_block_ptr
&
b
);
transaction_trace
push_transaction
(
const
signed_transaction
&
t
);
...
...
@@ -49,7 +53,7 @@ namespace eosio { namespace chain {
uint32_t
head_block_num
();
signal
<
void
(
const
block_trace
&
)
>
applied_block
;
signal
<
void
(
const
block_trace
_ptr
&
)
>
applied_block
;
signal
<
void
(
const
signed_block
&
)
>
applied_irreversible_block
;
private:
...
...
@@ -58,3 +62,10 @@ namespace eosio { namespace chain {
};
}
}
/// eosio::chain
FC_REFLECT
(
eosio
::
chain
::
controller
::
config
,
(
block_log_dir
)
(
shared_memory_dir
)(
shared_memory_size
)(
read_only
)
(
genesis
)
(
limits
)(
wasm_runtime
)
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录