Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
506a3fa7
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,发现更多精彩内容 >>
提交
506a3fa7
编写于
4月 22, 2018
作者:
D
Daniel Larimer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor apply trx to generate delayed receipts and hard fail receipts
上级
41bd6ee9
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
159 addition
and
81 deletion
+159
-81
libraries/chain/controller.cpp
libraries/chain/controller.cpp
+71
-75
libraries/chain/include/eosio/chain/generated_transaction_object.hpp
...hain/include/eosio/chain/generated_transaction_object.hpp
+7
-0
libraries/chain/include/eosio/chain/trace.hpp
libraries/chain/include/eosio/chain/trace.hpp
+3
-1
libraries/chain/include/eosio/chain/transaction.hpp
libraries/chain/include/eosio/chain/transaction.hpp
+11
-0
libraries/chain/include/eosio/chain/transaction_context.hpp
libraries/chain/include/eosio/chain/transaction_context.hpp
+15
-1
libraries/chain/transaction_context.cpp
libraries/chain/transaction_context.cpp
+52
-4
未找到文件。
libraries/chain/controller.cpp
浏览文件 @
506a3fa7
...
...
@@ -302,7 +302,8 @@ struct controller_impl {
self
.
accepted_block
(
head
);
}
void
apply_onerror
(
const
generated_transaction_object
&
gto
,
fc
::
time_point
deadline
)
{
transaction_trace_ptr
apply_onerror
(
const
generated_transaction_object
&
gto
,
fc
::
time_point
deadline
,
uint32_t
cpu_usage
)
{
FC_ASSERT
(
!
"not implemented"
);
/*
try {
signed_transaction etrx;
...
...
@@ -317,22 +318,60 @@ struct controller_impl {
transaction_trace_ptr
push_scheduled_transaction
(
const
generated_transaction_object
&
gto
,
fc
::
time_point
deadline
)
{
fc
::
datastream
<
const
char
*>
ds
(
gto
.
packed_trx
.
data
(),
gto
.
packed_trx
.
size
()
);
optional
<
fc
::
exception
>
except
;
FC_ASSERT
(
gto
.
delay_until
<=
self
.
pending_block_time
()
);
optional
<
fc
::
exception
>
soft_except
;
optional
<
fc
::
exception
>
hard_except
;
uint32_t
apply_cpu_usage
=
0
;
try
{
signed_transaction
dtrx
;
fc
::
raw
::
unpack
(
ds
,
static_cast
<
transaction
&>
(
dtrx
)
);
auto
trace
=
apply_transaction
(
dtrx
,
gto
.
trx_id
,
gto
.
published
,
deadline
,
0
);
trace
->
receipt
=
push_receipt
(
gto
.
trx_id
,
transaction_receipt
::
executed
,
trace
->
kcpu_usage
(),
0
);
transaction_context
trx_context
(
self
,
dtrx
,
gto
.
trx_id
);
trx_context
.
deadline
=
deadline
;
trx_context
.
published
=
gto
.
published
;
trx_context
.
net_usage
=
0
;
trx_context
.
apply_context_free
=
false
;
trx_context
.
is_input
=
false
;
try
{
trx_context
.
exec
();
}
catch
(
...
)
{
apply_cpu_usage
=
trx_context
.
trace
->
cpu_usage
;
throw
;
}
fc
::
move_append
(
pending
->
_actions
,
move
(
trx_context
.
executed
)
);
trx_context
.
trace
->
receipt
=
push_receipt
(
gto
.
trx_id
,
transaction_receipt
::
executed
,
trx_context
.
trace
->
kcpu_usage
(),
0
);
db
.
remove
(
gto
);
return
trace
;
trx_context
.
squash
();
return
move
(
trx_context
.
trace
);
}
catch
(
const
fc
::
exception
&
e
)
{
except
=
e
;
soft_
except
=
e
;
}
if
(
except
)
{
apply_onerror
(
gto
,
deadline
);
if
(
soft_except
)
{
/// TODO: soft errors should not go to error handlers (deadline error)
edump
((
soft_except
->
to_detail_string
()));
try
{
auto
trace
=
apply_onerror
(
gto
,
deadline
,
apply_cpu_usage
);
trace
->
soft_except
=
soft_except
;
return
trace
;
}
catch
(
const
fc
::
exception
&
e
)
{
hard_except
=
e
;
}
}
if
(
hard_except
)
{
edump
((
hard_except
->
to_detail_string
()));
db
.
remove
(
gto
);
auto
trace
=
std
::
make_shared
<
transaction_trace
>
();
trace
->
receipt
=
push_receipt
(
gto
.
trx_id
,
transaction_receipt
::
hard_fail
,
(
apply_cpu_usage
+
999
)
/
1000
,
0
);
trace
->
soft_except
=
soft_except
;
trace
->
hard_except
=
hard_except
;
return
trace
;
}
return
transaction_trace_ptr
();
}
/// push_scheduled_transaction
...
...
@@ -352,90 +391,47 @@ struct controller_impl {
}
void
apply_delayed_transaction
(
const
transaction_metadata_ptr
&
trx
,
fc
::
microseconds
delay
)
{
/// store this in generated transactions
/// bill storage to first authorized account
}
/**
* This is the entry point for new transactions to the block state. It will check authorization and
* determine whether to execute it now or to delay it. Lastly it inserts a transaction receipt into
* the pending block.
*/
transaction_trace_ptr
push_transaction
(
const
transaction_metadata_ptr
&
trx
,
fc
::
time_point
deadline
=
fc
::
time_point
::
maximum
()
)
{
transaction_trace_ptr
push_transaction
(
const
transaction_metadata_ptr
&
trx
,
fc
::
time_point
deadline
=
fc
::
time_point
::
maximum
(),
bool
implicit
=
false
)
{
unapplied_transactions
.
erase
(
trx
->
signed_id
);
/// TODO: add chain id
auto
required_delay
=
authorization
.
check_authorization
(
trx
->
trx
.
actions
,
trx
->
recover_keys
()
);
required_delay
=
std
::
max
(
fc
::
seconds
(
trx
->
trx
.
delay_sec
),
required_delay
);
record_transaction
(
trx
->
id
,
trx
->
trx
.
expiration
);
/// checks for dupes
transaction_context
trx_context
(
self
,
trx
->
trx
,
trx
->
id
);
trx_context
.
deadline
=
deadline
;
trx_context
.
published
=
self
.
pending_block_time
();
trx_context
.
net_usage
=
self
.
validate_net_usage
(
trx
);
trx_context
.
is_input
=
!
implicit
;
trx_context
.
delay
=
std
::
max
(
fc
::
seconds
(
trx
->
trx
.
delay_sec
),
required_delay
);
trx_context
.
exec
();
transaction_trace_ptr
trace
;
auto
net_usage
=
self
.
validate_net_usage
(
trx
);
fc
::
move_append
(
pending
->
_actions
,
move
(
trx_context
.
executed
)
);
if
(
required_delay
>
fc
::
microseconds
()
)
{
apply_delayed_transaction
(
trx
,
required_delay
);
/// TODO: apply a fixed CPU usage for the delay...
trace
->
receipt
=
push_receipt
(
trx
->
packed_trx
,
transaction_receipt
::
delayed
,
0
,
net_usage
);
}
else
{
trace
=
apply_transaction
(
trx
,
deadline
,
net_usage
);
trace
->
receipt
=
push_receipt
(
trx
->
packed_trx
,
transaction_receipt
::
executed
,
trace
->
kcpu_usage
(),
net_usage
);
const
auto
&
trace
=
trx_context
.
trace
;
if
(
!
implicit
)
{
if
(
trx_context
.
delay
==
fc
::
seconds
(
0
)
)
{
trace
->
receipt
=
push_receipt
(
trx
->
packed_trx
,
transaction_receipt
::
executed
,
trace
->
kcpu_usage
(),
trx_context
.
net_usage
);
}
else
{
trace
->
receipt
=
push_receipt
(
trx
->
packed_trx
,
transaction_receipt
::
delayed
,
trace
->
kcpu_usage
(),
trx_context
.
net_usage
);
}
}
pending
->
_pending_block_state
->
trxs
.
emplace_back
(
trx
);
self
.
accepted_transaction
(
trx
);
trx_context
.
squash
();
return
trace
;
return
move
(
trx_context
.
trace
);
}
/// push_transaction
/**
* This method will apply a transaction with a wall-clock deadline, after applying the transaction the
* authorizing accounts are billed for CPU/Network usage.
*
* Dispatched actions are added to the executed action receipt list, but no transaction receipt is generated
* because this method may be called from several different locations including:
* 1. push_transaction for new trx coming form users
* 2. push_scheduled_transaction for delayed and generated transactions
* 3. applying error handler for soft-fail generated transactions
*/
transaction_trace_ptr
apply_transaction
(
const
signed_transaction
&
trx
,
const
transaction_id_type
&
id
,
fc
::
time_point
published
,
fc
::
time_point
deadline
=
fc
::
time_point
::
maximum
(),
uint32_t
net_usage
=
0
)
{
transaction_context
trx_context
(
self
,
trx
,
id
);
trx_context
.
processing_deadline
=
deadline
;
trx_context
.
published
=
published
;
trx_context
.
net_usage
=
net_usage
;
trx_context
.
exec
();
auto
&
acts
=
pending
->
_actions
;
fc
::
move_append
(
acts
,
move
(
trx_context
.
executed
)
);
return
move
(
trx_context
.
trace
);
}
transaction_trace_ptr
apply_transaction
(
const
transaction_metadata_ptr
&
trx
,
fc
::
time_point
deadline
=
fc
::
time_point
::
maximum
(),
uint32_t
net_usage
=
0
)
{
return
apply_transaction
(
trx
->
trx
,
trx
->
id
,
self
.
pending_block_time
(),
deadline
,
net_usage
);
}
void
record_transaction
(
const
transaction_id_type
&
id
,
fc
::
time_point_sec
expire
)
{
try
{
db
.
create
<
transaction_object
>
([
&
](
transaction_object
&
transaction
)
{
transaction
.
trx_id
=
id
;
transaction
.
expiration
=
expire
;
});
}
catch
(
...
)
{
EOS_ASSERT
(
false
,
transaction_exception
,
"duplicate transaction ${id}"
,
(
"id"
,
id
)
);
}
}
/// record_transaction
void
start_block
(
block_timestamp_type
when
)
{
FC_ASSERT
(
!
pending
);
...
...
@@ -446,7 +442,7 @@ struct controller_impl {
try
{
auto
onbtrx
=
std
::
make_shared
<
transaction_metadata
>
(
get_on_block_transaction
()
);
apply_transaction
(
onbtrx
);
push_transaction
(
onbtrx
,
fc
::
time_point
::
maximum
(),
true
);
}
catch
(
...
)
{
ilog
(
"on block transaction failed, but shouldn't impact block generation, system contract needs update"
);
}
...
...
libraries/chain/include/eosio/chain/generated_transaction_object.hpp
浏览文件 @
506a3fa7
...
...
@@ -35,6 +35,13 @@ namespace eosio { namespace chain {
time_point
expiration
;
/// this generated transaction will not be applied after this time
time_point
published
;
shared_vector
<
char
>
packed_trx
;
void
set
(
const
transaction
&
trx
)
{
auto
trxsize
=
fc
::
raw
::
pack_size
(
static_cast
<
const
transaction
&>
(
trx
)
);
packed_trx
.
resize
(
trxsize
);
fc
::
datastream
<
char
*>
ds
(
packed_trx
.
data
(),
trxsize
);
fc
::
raw
::
pack
(
ds
,
trx
);
}
};
struct
by_trx_id
;
...
...
libraries/chain/include/eosio/chain/trace.hpp
浏览文件 @
506a3fa7
...
...
@@ -31,6 +31,8 @@ namespace eosio { namespace chain {
uint64_t
cpu_usage
=
0
;
bool
scheduled
=
false
;
vector
<
action_trace
>
action_traces
;
///< disposable
fc
::
optional
<
fc
::
exception
>
soft_except
;
fc
::
optional
<
fc
::
exception
>
hard_except
;
uint32_t
kcpu_usage
()
const
{
return
(
cpu_usage
+
999
)
/
1000
;
}
};
...
...
@@ -47,5 +49,5 @@ namespace eosio { namespace chain {
FC_REFLECT
(
eosio
::
chain
::
action_trace
,
(
receipt
)(
act
)(
elapsed
)(
cpu_usage
)(
console
)(
total_inline_cpu_usage
)(
inline_traces
)
)
FC_REFLECT
(
eosio
::
chain
::
transaction_trace
,
(
id
)(
receipt
)(
elapsed
)(
cpu_usage
)(
action_traces
)
)
FC_REFLECT
(
eosio
::
chain
::
transaction_trace
,
(
id
)(
receipt
)(
elapsed
)(
cpu_usage
)(
action_traces
)
(
soft_except
)(
hard_except
)
)
FC_REFLECT
(
eosio
::
chain
::
block_trace
,
(
elapsed
)(
cpu_usage
)(
trx_traces
)
)
libraries/chain/include/eosio/chain/transaction.hpp
浏览文件 @
506a3fa7
...
...
@@ -62,6 +62,14 @@ namespace eosio { namespace chain {
bool
allow_duplicate_keys
=
false
)
const
;
uint32_t
total_actions
()
const
{
return
context_free_actions
.
size
()
+
actions
.
size
();
}
account_name
first_authorizor
()
const
{
for
(
const
auto
&
a
:
actions
)
{
for
(
const
auto
&
u
:
a
.
authorization
)
return
u
.
actor
;
}
return
account_name
();
}
};
struct
signed_transaction
:
public
transaction
...
...
@@ -163,6 +171,9 @@ namespace eosio { namespace chain {
account_name
sender
;
uint128_t
sender_id
;
};
uint128_t
transaction_id_to_sender_id
(
const
transaction_id_type
&
tid
);
}
}
/// namespace eosio::chain
FC_REFLECT
(
eosio
::
chain
::
transaction_header
,
(
expiration
)(
ref_block_num
)(
ref_block_prefix
)
...
...
libraries/chain/include/eosio/chain/transaction_context.hpp
浏览文件 @
506a3fa7
...
...
@@ -21,13 +21,27 @@ namespace eosio { namespace chain {
}
void
exec
();
void
squash
();
void
dispatch_action
(
const
action
&
a
,
account_name
receiver
,
bool
context_free
=
false
);
void
schedule_transaction
();
void
record_transaction
(
const
transaction_id_type
&
id
,
fc
::
time_point_sec
expire
);
bool
apply_context_free
=
true
;
bool
apply_actions
=
true
;
bool
is_input
=
true
;
fc
::
microseconds
delay
;
vector
<
action_receipt
>
executed
;
transaction_trace_ptr
trace
;
fc
::
time_point
processing_
deadline
;
fc
::
time_point
deadline
;
controller
&
control
;
transaction_id_type
id
;
...
...
libraries/chain/transaction_context.cpp
浏览文件 @
506a3fa7
...
...
@@ -2,6 +2,8 @@
#include <eosio/chain/transaction_context.hpp>
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/resource_limits.hpp>
#include <eosio/chain/generated_transaction_object.hpp>
#include <eosio/chain/transaction_object.hpp>
namespace
eosio
{
namespace
chain
{
...
...
@@ -15,18 +17,31 @@ namespace eosio { namespace chain {
control
.
validate_referenced_accounts
(
trx
);
control
.
validate_expiration
(
trx
);
if
(
is_input
)
{
record_transaction
(
id
,
trx
.
expiration
);
/// checks for dupes
}
if
(
trx
.
max_kcpu_usage
.
value
!=
0
)
{
max_cpu
=
uint64_t
(
trx
.
max_kcpu_usage
.
value
)
*
1000
;
}
else
{
max_cpu
=
uint64_t
(
-
1
);
}
for
(
const
auto
&
act
:
trx
.
context_free_actions
)
{
dispatch_action
(
act
,
act
.
account
,
true
);
if
(
apply_context_free
)
{
for
(
const
auto
&
act
:
trx
.
context_free_actions
)
{
dispatch_action
(
act
,
act
.
account
,
true
);
}
}
if
(
delay
==
fc
::
microseconds
()
)
{
for
(
const
auto
&
act
:
trx
.
actions
)
{
dispatch_action
(
act
,
act
.
account
,
false
);
}
}
else
{
schedule_transaction
();
}
for
(
const
auto
&
act
:
trx
.
actions
)
{
dispatch_action
(
act
,
act
.
account
,
false
);
for
(
const
auto
&
auth
:
act
.
authorization
)
bill_to_accounts
.
insert
(
auth
.
actor
);
}
...
...
@@ -38,6 +53,9 @@ namespace eosio { namespace chain {
vector
<
account_name
>
bta
(
bill_to_accounts
.
begin
(),
bill_to_accounts
.
end
()
);
rl
.
add_transaction_usage
(
bta
,
trace
->
cpu_usage
,
net_usage
,
block_timestamp_type
(
control
.
pending_block_time
()).
slot
);
}
void
transaction_context
::
squash
()
{
undo_session
.
squash
();
}
...
...
@@ -47,7 +65,7 @@ namespace eosio { namespace chain {
acontext
.
id
=
id
;
acontext
.
context_free
=
context_free
;
acontext
.
receiver
=
receiver
;
acontext
.
processing_deadline
=
processing_
deadline
;
acontext
.
processing_deadline
=
deadline
;
acontext
.
published_time
=
published
;
acontext
.
max_cpu
=
max_cpu
-
trace
->
cpu_usage
;
acontext
.
exec
();
...
...
@@ -58,5 +76,35 @@ namespace eosio { namespace chain {
trace
->
action_traces
.
emplace_back
(
move
(
acontext
.
trace
)
);
}
void
transaction_context
::
schedule_transaction
()
{
auto
first_auth
=
trx
.
first_authorizor
();
const
auto
&
cgto
=
control
.
db
().
create
<
generated_transaction_object
>
(
[
&
](
auto
&
gto
)
{
gto
.
trx_id
=
id
;
gto
.
payer
=
first_auth
;
gto
.
sender
=
config
::
system_account_name
;
gto
.
sender_id
=
transaction_id_to_sender_id
(
gto
.
trx_id
);
gto
.
expiration
=
trx
.
expiration
;
gto
.
published
=
control
.
pending_block_time
();
gto
.
delay_until
=
gto
.
published
+
delay
;
gto
.
set
(
trx
);
});
control
.
get_mutable_resource_limits_manager
().
add_pending_account_ram_usage
(
cgto
.
payer
,
(
config
::
billable_size_v
<
generated_transaction_object
>
+
cgto
.
packed_trx
.
size
()));
}
void
transaction_context
::
record_transaction
(
const
transaction_id_type
&
id
,
fc
::
time_point_sec
expire
)
{
try
{
control
.
db
().
create
<
transaction_object
>
([
&
](
transaction_object
&
transaction
)
{
transaction
.
trx_id
=
id
;
transaction
.
expiration
=
expire
;
});
}
catch
(
...
)
{
EOS_ASSERT
(
false
,
transaction_exception
,
"duplicate transaction ${id}"
,
(
"id"
,
id
)
);
}
}
/// record_transaction
}
}
/// eosio::chain
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录