Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
c75a6ff1
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,发现更多精彩内容 >>
提交
c75a6ff1
编写于
3月 07, 2018
作者:
A
Anton Perkov
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'system-contract-voting-2' of github.com:EOSIO/eos into system-contract-voting-2
上级
01316759
123193c8
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
419 addition
and
10 deletion
+419
-10
contracts/eosio.system/eosio.system.hpp
contracts/eosio.system/eosio.system.hpp
+37
-0
contracts/eosiolib/datastream.hpp
contracts/eosiolib/datastream.hpp
+48
-0
contracts/eosiolib/optional.hpp
contracts/eosiolib/optional.hpp
+282
-0
contracts/eosiolib/types.h
contracts/eosiolib/types.h
+0
-4
libraries/chain/chain_controller.cpp
libraries/chain/chain_controller.cpp
+48
-6
libraries/chain/include/eosio/chain/chain_controller.hpp
libraries/chain/include/eosio/chain/chain_controller.hpp
+4
-0
未找到文件。
contracts/eosio.system/eosio.system.hpp
浏览文件 @
c75a6ff1
...
@@ -6,11 +6,38 @@
...
@@ -6,11 +6,38 @@
#include "voting.hpp"
#include "voting.hpp"
#include "delegate_bandwith.hpp"
#include "delegate_bandwith.hpp"
#include <eosiolib/optional.hpp>
#include <eosiolib/generic_currency.hpp>
#include <eosiolib/generic_currency.hpp>
namespace
eosiosystem
{
namespace
eosiosystem
{
struct
PACKED
(
producer_key
)
{
account_name
producer_name
;
public_key
block_signing_key
;
EOSLIB_SERIALIZE
(
producer_key
,
(
producer_name
)(
block_signing_key
))
};
struct
PACKED
(
producer_schedule
)
{
uint32_t
version
;
std
::
vector
<
producer_key
>
producers
;
EOSLIB_SERIALIZE
(
producer_schedule
,
(
version
)(
producers
))
};
struct
PACKED
(
block_header
)
{
checksum256
previous
;
time
timestamp
;
checksum256
transaction_mroot
;
checksum256
action_mroot
;
checksum256
block_mroot
;
account_name
producer
;
eosio
::
optional
<
producer_schedule
>
new_producers
;
EOSLIB_SERIALIZE
(
block_header
,
(
previous
)(
timestamp
)(
transaction_mroot
)(
action_mroot
)(
block_mroot
)(
producer
)(
new_producers
))
};
template
<
account_name
SystemAccount
>
template
<
account_name
SystemAccount
>
class
contract
:
public
voting
<
SystemAccount
>
,
public
delegate_bandwith
<
SystemAccount
>
{
class
contract
:
public
voting
<
SystemAccount
>
,
public
delegate_bandwith
<
SystemAccount
>
{
public:
public:
...
@@ -29,6 +56,15 @@ namespace eosiosystem {
...
@@ -29,6 +56,15 @@ namespace eosiosystem {
static
void
on
(
const
nonce
&
)
{
static
void
on
(
const
nonce
&
)
{
}
}
ACTION
(
SystemAccount
,
onblock
)
{
block_header
header
;
EOSLIB_SERIALIZE
(
onblock
,
(
header
))
};
static
void
on
(
const
onblock
&
ob
)
{
}
static
void
apply
(
account_name
code
,
action_name
act
)
{
static
void
apply
(
account_name
code
,
action_name
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
)
)
{
if
(
!
eosio
::
dispatch
<
contract
,
typename
delegate_bandwith
<
SystemAccount
>::
delegatebw
,
if
(
!
eosio
::
dispatch
<
contract
,
typename
delegate_bandwith
<
SystemAccount
>::
delegatebw
,
...
@@ -40,6 +76,7 @@ namespace eosiosystem {
...
@@ -40,6 +76,7 @@ namespace eosiosystem {
typename
voting
<
SystemAccount
>::
stakevote
,
typename
voting
<
SystemAccount
>::
stakevote
,
typename
voting
<
SystemAccount
>::
unstakevote
,
typename
voting
<
SystemAccount
>::
unstakevote
,
typename
voting
<
SystemAccount
>::
unstake_vote_deferred
,
typename
voting
<
SystemAccount
>::
unstake_vote_deferred
,
onblock
,
nonce
>
(
code
,
act
)
)
{
nonce
>
(
code
,
act
)
)
{
eosio
::
print
(
"Unexpected action: "
,
eosio
::
name
(
act
),
"
\n
"
);
eosio
::
print
(
"Unexpected action: "
,
eosio
::
name
(
act
),
"
\n
"
);
eosio_assert
(
false
,
"received unexpected action"
);
eosio_assert
(
false
,
"received unexpected action"
);
...
...
contracts/eosiolib/datastream.hpp
浏览文件 @
c75a6ff1
...
@@ -458,4 +458,52 @@ bytes pack( const T& value ) {
...
@@ -458,4 +458,52 @@ bytes pack( const T& value ) {
return
result
;
return
result
;
}
}
template
<
typename
Stream
>
inline
eosio
::
datastream
<
Stream
>&
operator
<<
(
eosio
::
datastream
<
Stream
>&
ds
,
const
public_key
pk
)
{
ds
.
write
((
const
char
*
)
&
pk
,
sizeof
(
pk
));
return
ds
;
}
template
<
typename
Stream
>
inline
eosio
::
datastream
<
Stream
>&
operator
>>
(
eosio
::
datastream
<
Stream
>&
ds
,
public_key
&
pk
)
{
ds
.
read
((
char
*
)
&
pk
,
sizeof
(
pk
));
return
ds
;
}
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
<<
(
datastream
<
Stream
>&
ds
,
const
checksum160
&
cs
)
{
ds
.
write
((
const
char
*
)
&
cs
,
sizeof
(
cs
));
return
ds
;
}
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
>>
(
datastream
<
Stream
>&
ds
,
checksum160
&
cs
)
{
ds
.
read
((
char
*
)
&
cs
,
sizeof
(
cs
));
return
ds
;
}
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
<<
(
datastream
<
Stream
>&
ds
,
const
checksum256
&
cs
)
{
ds
.
write
((
const
char
*
)
&
cs
,
sizeof
(
cs
));
return
ds
;
}
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
>>
(
datastream
<
Stream
>&
ds
,
checksum256
&
cs
)
{
ds
.
read
((
char
*
)
&
cs
,
sizeof
(
cs
));
return
ds
;
}
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
<<
(
datastream
<
Stream
>&
ds
,
const
checksum512
&
cs
)
{
ds
.
write
((
const
char
*
)
&
cs
,
sizeof
(
cs
));
return
ds
;
}
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
>>
(
datastream
<
Stream
>&
ds
,
checksum512
&
cs
)
{
ds
.
read
((
char
*
)
&
cs
,
sizeof
(
cs
));
return
ds
;
}
}
}
contracts/eosiolib/optional.hpp
0 → 100644
浏览文件 @
c75a6ff1
#pragma once
#include <utility>
namespace
eosio
{
template
<
typename
T
>
class
optional
{
public:
typedef
T
value_type
;
optional
()
:
_valid
(
false
){}
~
optional
(){
reset
();
}
optional
(
optional
&
o
)
:
_valid
(
false
)
{
if
(
o
.
_valid
)
new
(
ptr
())
T
(
*
o
);
_valid
=
o
.
_valid
;
}
optional
(
const
optional
&
o
)
:
_valid
(
false
)
{
if
(
o
.
_valid
)
new
(
ptr
())
T
(
*
o
);
_valid
=
o
.
_valid
;
}
optional
(
optional
&&
o
)
:
_valid
(
false
)
{
if
(
o
.
_valid
)
new
(
ptr
())
T
(
std
::
move
(
*
o
)
);
_valid
=
o
.
_valid
;
o
.
reset
();
}
template
<
typename
U
>
optional
(
const
optional
<
U
>&
o
)
:
_valid
(
false
)
{
if
(
o
.
_valid
)
new
(
ptr
())
T
(
*
o
);
_valid
=
o
.
_valid
;
}
template
<
typename
U
>
optional
(
optional
<
U
>&
o
)
:
_valid
(
false
)
{
if
(
o
.
_valid
)
{
new
(
ptr
())
T
(
*
o
);
}
_valid
=
o
.
_valid
;
}
template
<
typename
U
>
optional
(
optional
<
U
>&&
o
)
:
_valid
(
false
)
{
if
(
o
.
_valid
)
new
(
ptr
())
T
(
std
::
move
(
*
o
)
);
_valid
=
o
.
_valid
;
o
.
reset
();
}
template
<
typename
U
>
optional
(
U
&&
u
)
:
_valid
(
true
)
{
new
((
char
*
)
ptr
())
T
(
std
::
forward
<
U
>
(
u
)
);
}
template
<
typename
U
>
optional
&
operator
=
(
U
&&
u
)
{
reset
();
new
(
ptr
())
T
(
std
::
forward
<
U
>
(
u
)
);
_valid
=
true
;
return
*
this
;
}
template
<
typename
...
Args
>
void
emplace
(
Args
&&
...
args
)
{
if
(
_valid
)
{
reset
();
}
new
((
char
*
)
ptr
())
T
(
std
::
forward
<
Args
>
(
args
)...
);
_valid
=
true
;
}
template
<
typename
U
>
optional
&
operator
=
(
optional
<
U
>&
o
)
{
if
(
this
!=
&
o
)
{
if
(
_valid
&&
o
.
_valid
)
{
ref
()
=
*
o
;
}
else
if
(
!
_valid
&&
o
.
_valid
)
{
new
(
ptr
())
T
(
*
o
);
_valid
=
true
;
}
else
if
(
_valid
)
{
reset
();
}
}
return
*
this
;
}
template
<
typename
U
>
optional
&
operator
=
(
const
optional
<
U
>&
o
)
{
if
(
this
!=
&
o
)
{
if
(
_valid
&&
o
.
_valid
)
{
ref
()
=
*
o
;
}
else
if
(
!
_valid
&&
o
.
_valid
)
{
new
(
ptr
())
T
(
*
o
);
_valid
=
true
;
}
else
if
(
_valid
)
{
reset
();
}
}
return
*
this
;
}
optional
&
operator
=
(
optional
&
o
)
{
if
(
this
!=
&
o
)
{
if
(
_valid
&&
o
.
_valid
)
{
ref
()
=
*
o
;
}
else
if
(
!
_valid
&&
o
.
_valid
)
{
new
(
ptr
())
T
(
*
o
);
_valid
=
true
;
}
else
if
(
_valid
)
{
reset
();
}
}
return
*
this
;
}
optional
&
operator
=
(
const
optional
&
o
)
{
if
(
this
!=
&
o
)
{
if
(
_valid
&&
o
.
_valid
)
{
ref
()
=
*
o
;
}
else
if
(
!
_valid
&&
o
.
_valid
)
{
new
(
ptr
())
T
(
*
o
);
_valid
=
true
;
}
else
if
(
_valid
)
{
reset
();
}
}
return
*
this
;
}
template
<
typename
U
>
optional
&
operator
=
(
optional
<
U
>&&
o
)
{
if
(
this
!=
&
o
)
{
if
(
_valid
&&
o
.
_valid
)
{
ref
()
=
std
::
move
(
*
o
);
o
.
reset
();
}
else
if
(
!
_valid
&&
o
.
_valid
)
{
*
this
=
std
::
move
(
*
o
);
}
else
if
(
_valid
)
{
reset
();
}
}
return
*
this
;
}
optional
&
operator
=
(
optional
&&
o
)
{
if
(
this
!=
&
o
)
{
if
(
_valid
&&
o
.
_valid
)
{
ref
()
=
std
::
move
(
*
o
);
o
.
reset
();
}
else
if
(
!
_valid
&&
o
.
_valid
)
{
*
this
=
std
::
move
(
*
o
);
}
else
if
(
_valid
)
{
reset
();
}
}
return
*
this
;
}
bool
valid
()
const
{
return
_valid
;
}
bool
operator
!
()
const
{
return
!
_valid
;
}
// this operation is not safe and can result in unintential
// casts and comparisons, use valid() or !!
explicit
operator
bool
()
const
{
return
_valid
;
}
T
&
operator
*
()
{
assert
(
_valid
);
return
ref
();
}
const
T
&
operator
*
()
const
{
assert
(
_valid
);
return
ref
();
}
T
*
operator
->
()
{
assert
(
_valid
);
return
ptr
();
}
const
T
*
operator
->
()
const
{
assert
(
_valid
);
return
ptr
();
}
optional
&
operator
=
(
std
::
nullptr_t
)
{
reset
();
return
*
this
;
}
void
reset
()
{
if
(
_valid
)
{
ref
().
~
T
();
// cal destructor
}
_valid
=
false
;
}
friend
bool
operator
<
(
const
optional
a
,
optional
b
)
{
if
(
a
.
valid
()
&&
b
.
valid
()
)
return
*
a
<
*
b
;
return
a
.
valid
()
<
b
.
valid
();
}
friend
bool
operator
==
(
const
optional
a
,
optional
b
)
{
if
(
a
.
valid
()
&&
b
.
valid
()
)
return
*
a
==
*
b
;
return
a
.
valid
()
==
b
.
valid
();
}
template
<
typename
Stream
>
friend
inline
eosio
::
datastream
<
Stream
>&
operator
>>
(
eosio
::
datastream
<
Stream
>&
ds
,
optional
&
op
)
{
char
valid
=
0
;
ds
>>
valid
;
if
(
valid
)
{
op
.
_valid
=
true
;
ds
>>
*
op
;
}
return
ds
;
}
template
<
typename
Stream
>
friend
inline
eosio
::
datastream
<
Stream
>&
operator
<<
(
eosio
::
datastream
<
Stream
>&
ds
,
const
optional
&
op
)
{
char
valid
=
op
.
_valid
;
ds
<<
valid
;
if
(
valid
)
ds
<<
*
op
;
return
ds
;
}
private:
template
<
typename
U
>
friend
class
optional
;
T
&
ref
()
{
return
*
ptr
();
}
const
T
&
ref
()
const
{
return
*
ptr
();
}
T
*
ptr
()
{
void
*
v
=
&
_value
[
0
];
return
static_cast
<
T
*>
(
v
);
}
const
T
*
ptr
()
const
{
const
void
*
v
=
&
_value
[
0
];
return
static_cast
<
const
T
*>
(
v
);
}
// force alignment... to 8 byte boundaries
uint64_t
_value
[((
sizeof
(
T
)
+
7
)
/
8
)];
bool
_valid
;
};
template
<
typename
T
>
bool
operator
==
(
const
optional
<
T
>&
left
,
const
optional
<
T
>&
right
)
{
return
(
!
left
==
!
right
)
||
(
!!
left
&&
*
left
==
*
right
);
}
template
<
typename
T
,
typename
U
>
bool
operator
==
(
const
optional
<
T
>&
left
,
const
U
&
u
)
{
return
!!
left
&&
*
left
==
u
;
}
template
<
typename
T
>
bool
operator
!=
(
const
optional
<
T
>&
left
,
const
optional
<
T
>&
right
)
{
return
(
!
left
!=
!
right
)
||
(
!!
left
&&
*
left
!=
*
right
);
}
template
<
typename
T
,
typename
U
>
bool
operator
!=
(
const
optional
<
T
>&
left
,
const
U
&
u
)
{
return
!
left
||
*
left
!=
u
;
}
}
// namespace eosio
contracts/eosiolib/types.h
浏览文件 @
c75a6ff1
...
@@ -6,10 +6,6 @@
...
@@ -6,10 +6,6 @@
#include <stdint.h>
#include <stdint.h>
#include <wchar.h>
#include <wchar.h>
/*
struct checksum_base {
};
*/
#ifdef __cplusplus
#ifdef __cplusplus
extern
"C"
{
extern
"C"
{
...
...
libraries/chain/chain_controller.cpp
浏览文件 @
c75a6ff1
...
@@ -330,6 +330,17 @@ transaction_trace chain_controller::_push_transaction( transaction_metadata&& da
...
@@ -330,6 +330,17 @@ transaction_trace chain_controller::_push_transaction( transaction_metadata&& da
return
result
;
return
result
;
}
}
block_header
chain_controller
::
head_block_header
()
const
{
auto
b
=
_fork_db
.
fetch_block
(
head_block_id
());
if
(
b
)
return
b
->
data
;
if
(
auto
head_block
=
fetch_block_by_id
(
head_block_id
()))
return
*
head_block
;
return
block_header
();
}
void
chain_controller
::
_start_pending_block
()
void
chain_controller
::
_start_pending_block
()
{
{
FC_ASSERT
(
!
_pending_block
);
FC_ASSERT
(
!
_pending_block
);
...
@@ -339,6 +350,28 @@ void chain_controller::_start_pending_block()
...
@@ -339,6 +350,28 @@ void chain_controller::_start_pending_block()
_pending_block
->
regions
.
resize
(
1
);
_pending_block
->
regions
.
resize
(
1
);
_pending_block_trace
->
region_traces
.
resize
(
1
);
_pending_block_trace
->
region_traces
.
resize
(
1
);
_start_pending_cycle
();
_start_pending_cycle
();
_apply_on_block_transaction
();
}
transaction
chain_controller
::
_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
());
return
trx
;
}
void
chain_controller
::
_apply_on_block_transaction
()
{
auto
trx
=
_get_on_block_transaction
();
transaction_metadata
mtrx
(
packed_transaction
(
trx
),
get_chain_id
(),
head_block_time
());
_push_transaction
(
std
::
move
(
mtrx
));
}
}
/**
/**
...
@@ -604,7 +637,11 @@ void chain_controller::__apply_block(const signed_block& next_block)
...
@@ -604,7 +637,11 @@ void chain_controller::__apply_block(const signed_block& next_block)
/// cache the input tranasction ids so that they can be looked up when executing the
/// cache the input tranasction ids so that they can be looked up when executing the
/// summary
/// summary
vector
<
transaction_metadata
>
input_metas
;
vector
<
transaction_metadata
>
input_metas
;
input_metas
.
reserve
(
next_block
.
input_transactions
.
size
());
input_metas
.
reserve
(
next_block
.
input_transactions
.
size
()
+
1
);
{
auto
trx
=
_get_on_block_transaction
();
input_metas
.
emplace_back
(
packed_transaction
(
trx
),
get_chain_id
(),
head_block_time
());
}
map
<
transaction_id_type
,
size_t
>
trx_index
;
map
<
transaction_id_type
,
size_t
>
trx_index
;
for
(
const
auto
&
t
:
next_block
.
input_transactions
)
{
for
(
const
auto
&
t
:
next_block
.
input_transactions
)
{
input_metas
.
emplace_back
(
t
,
chain_id_type
(),
next_block
.
timestamp
);
input_metas
.
emplace_back
(
t
,
chain_id_type
(),
next_block
.
timestamp
);
...
@@ -663,10 +700,16 @@ void chain_controller::__apply_block(const signed_block& next_block)
...
@@ -663,10 +700,16 @@ void chain_controller::__apply_block(const signed_block& next_block)
if
(
itr
!=
trx_index
.
end
()
)
{
if
(
itr
!=
trx_index
.
end
()
)
{
return
&
input_metas
.
at
(
itr
->
second
);
return
&
input_metas
.
at
(
itr
->
second
);
}
else
{
}
else
{
const
auto
&
gtrx
=
_db
.
get
<
generated_transaction_object
,
by_trx_id
>
(
receipt
.
id
);
const
auto
*
gtrx
=
_db
.
find
<
generated_transaction_object
,
by_trx_id
>
(
receipt
.
id
);
auto
trx
=
fc
::
raw
::
unpack
<
deferred_transaction
>
(
gtrx
.
packed_trx
.
data
(),
gtrx
.
packed_trx
.
size
());
if
(
gtrx
!=
nullptr
)
{
_temp
.
emplace
(
trx
,
gtrx
.
published
,
trx
.
sender
,
trx
.
sender_id
,
gtrx
.
packed_trx
.
data
(),
gtrx
.
packed_trx
.
size
()
);
auto
trx
=
fc
::
raw
::
unpack
<
deferred_transaction
>
(
gtrx
->
packed_trx
.
data
(),
gtrx
->
packed_trx
.
size
());
_temp
.
emplace
(
trx
,
gtrx
->
published
,
trx
.
sender
,
trx
.
sender_id
,
gtrx
->
packed_trx
.
data
(),
gtrx
->
packed_trx
.
size
()
);
return
&*
_temp
;
return
&*
_temp
;
}
else
{
const
auto
&
mtrx
=
input_metas
[
0
];
FC_ASSERT
(
mtrx
.
id
==
receipt
.
id
,
"on-block transaction id mismatch"
);
return
&
input_metas
[
0
];
}
}
}
};
};
...
@@ -950,7 +993,6 @@ void chain_controller::update_global_properties(const signed_block& b) { try {
...
@@ -950,7 +993,6 @@ void chain_controller::update_global_properties(const signed_block& b) { try {
{
{
FC_ASSERT
(
schedule
==
*
b
.
new_producers
,
"pending producer set different than expected"
);
FC_ASSERT
(
schedule
==
*
b
.
new_producers
,
"pending producer set different than expected"
);
}
}
const
auto
&
gpo
=
get_global_properties
();
const
auto
&
gpo
=
get_global_properties
();
if
(
_head_producer_schedule
()
!=
schedule
)
{
if
(
_head_producer_schedule
()
!=
schedule
)
{
...
...
libraries/chain/include/eosio/chain/chain_controller.hpp
浏览文件 @
c75a6ff1
...
@@ -278,6 +278,7 @@ namespace eosio { namespace chain {
...
@@ -278,6 +278,7 @@ namespace eosio { namespace chain {
uint32_t
head_block_num
()
const
;
uint32_t
head_block_num
()
const
;
block_id_type
head_block_id
()
const
;
block_id_type
head_block_id
()
const
;
account_name
head_block_producer
()
const
;
account_name
head_block_producer
()
const
;
block_header
head_block_header
()
const
;
uint32_t
last_irreversible_block_num
()
const
;
uint32_t
last_irreversible_block_num
()
const
;
...
@@ -418,6 +419,9 @@ namespace eosio { namespace chain {
...
@@ -418,6 +419,9 @@ namespace eosio { namespace chain {
void
_apply_cycle_trace
(
const
cycle_trace
&
trace
);
void
_apply_cycle_trace
(
const
cycle_trace
&
trace
);
void
_finalize_block
(
const
block_trace
&
b
);
void
_finalize_block
(
const
block_trace
&
b
);
transaction
_get_on_block_transaction
();
void
_apply_on_block_transaction
();
// producer_schedule_type calculate_next_round( const signed_block& next_block );
// producer_schedule_type calculate_next_round( const signed_block& next_block );
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录