Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
596244e1
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,发现更多精彩内容 >>
提交
596244e1
编写于
2月 14, 2018
作者:
D
Daniel Larimer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add context free api
上级
27b89b2d
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
136 addition
and
34 deletion
+136
-34
contracts/eosiolib/transaction.hpp
contracts/eosiolib/transaction.hpp
+5
-2
libraries/chain/apply_context.cpp
libraries/chain/apply_context.cpp
+39
-0
libraries/chain/chain_controller.cpp
libraries/chain/chain_controller.cpp
+14
-0
libraries/chain/include/eosio/chain/apply_context.hpp
libraries/chain/include/eosio/chain/apply_context.hpp
+6
-1
libraries/chain/include/eosio/chain/transaction.hpp
libraries/chain/include/eosio/chain/transaction.hpp
+7
-3
libraries/chain/include/eosio/chain/transaction_metadata.hpp
libraries/chain/include/eosio/chain/transaction_metadata.hpp
+1
-0
libraries/chain/wasm_interface.cpp
libraries/chain/wasm_interface.cpp
+64
-28
未找到文件。
contracts/eosiolib/transaction.hpp
浏览文件 @
596244e1
...
...
@@ -36,11 +36,14 @@ namespace eosio {
time
expiration
;
region_id
region
;
uint16_t
ref_block_num
;
uint32_t
ref_block_id
;
uint32_t
ref_block_prefix
;
uint16_t
packed_bandwidth_words
=
0
;
/// number of 8 byte words this transaction can compress into
uint16_t
context_free_cpu_bandwidth
=
0
;
/// number of CPU usage units to bill transaction for
vector
<
action
>
context_free_actions
;
vector
<
action
>
actions
;
EOSLIB_SERIALIZE
(
transaction
,
(
expiration
)(
region
)(
ref_block_num
)(
ref_block_
id
)(
actions
)
);
EOSLIB_SERIALIZE
(
transaction
,
(
expiration
)(
region
)(
ref_block_num
)(
ref_block_
prefix
)(
packed_bandwidth_words
)(
context_free_cpu_bandwidth
)(
context_free_actions
)(
actions
)
);
};
class
deferred_transaction
:
public
transaction
{
...
...
libraries/chain/apply_context.cpp
浏览文件 @
596244e1
...
...
@@ -304,6 +304,45 @@ void apply_context::update_db_usage( const account_name& payer, int64_t delta )
}
int
apply_context
::
get_action
(
uint32_t
type
,
uint32_t
index
,
char
*
buffer
,
size_t
buffer_size
)
const
{
const
transaction
&
trx
=
trx_meta
.
trx
();
const
action
*
act
=
nullptr
;
if
(
type
==
0
)
{
if
(
index
>=
trx
.
context_free_actions
.
size
()
)
return
-
1
;
act
=
&
trx
.
context_free_actions
[
index
];
}
else
if
(
type
==
1
)
{
if
(
index
>=
trx
.
actions
.
size
()
)
return
-
1
;
act
=
&
trx
.
actions
[
index
];
}
auto
ps
=
fc
::
raw
::
pack_size
(
*
act
);
if
(
ps
<=
buffer_size
)
{
fc
::
datastream
<
char
*>
ds
(
buffer
,
buffer_size
);
fc
::
raw
::
pack
(
ds
,
*
act
);
}
return
ps
;
}
int
apply_context
::
get_context_free_data
(
uint32_t
index
,
char
*
buffer
,
size_t
buffer_size
)
const
{
if
(
index
>=
trx_meta
.
context_free_data
.
size
()
)
return
-
1
;
auto
s
=
trx_meta
.
context_free_data
[
index
].
size
();
if
(
buffer_size
==
0
)
return
s
;
if
(
buffer_size
<
s
)
memcpy
(
buffer
,
trx_meta
.
context_free_data
.
data
(),
buffer_size
);
else
memcpy
(
buffer
,
trx_meta
.
context_free_data
.
data
(),
s
);
return
s
;
}
int
apply_context
::
db_store_i64
(
uint64_t
scope
,
uint64_t
table
,
const
account_name
&
payer
,
uint64_t
id
,
const
char
*
buffer
,
size_t
buffer_size
)
{
require_write_lock
(
scope
);
const
auto
&
tab
=
find_or_create_table
(
receiver
,
scope
,
table
);
...
...
libraries/chain/chain_controller.cpp
浏览文件 @
596244e1
...
...
@@ -1406,9 +1406,23 @@ static void log_handled_exceptions(const transaction& trx) {
transaction_trace
chain_controller
::
__apply_transaction
(
transaction_metadata
&
meta
)
{
transaction_trace
result
(
meta
.
id
);
for
(
const
auto
&
act
:
meta
.
trx
().
context_free_actions
)
{
FC_ASSERT
(
act
.
authorization
.
size
()
==
0
,
"context free actions cannot require authorization"
);
apply_context
context
(
*
this
,
_db
,
act
,
meta
);
context
.
context_free
=
true
;
context
.
exec
();
fc
::
move_append
(
result
.
action_traces
,
std
::
move
(
context
.
results
.
applied_actions
));
FC_ASSERT
(
result
.
deferred_transactions
.
size
()
==
0
);
FC_ASSERT
(
result
.
canceled_deferred
.
size
()
==
0
);
}
for
(
const
auto
&
act
:
meta
.
trx
().
actions
)
{
apply_context
context
(
*
this
,
_db
,
act
,
meta
);
context
.
exec
();
context
.
used_context_free_api
|=
act
.
authorization
.
size
();
FC_ASSERT
(
context
.
used_context_free_api
,
"action did not reference database state, it should be moved to context_free_actions"
,
(
"act"
,
act
)
);
fc
::
move_append
(
result
.
action_traces
,
std
::
move
(
context
.
results
.
applied_actions
));
fc
::
move_append
(
result
.
deferred_transactions
,
std
::
move
(
context
.
results
.
generated_transactions
));
fc
::
move_append
(
result
.
canceled_deferred
,
std
::
move
(
context
.
results
.
canceled_deferred
));
...
...
libraries/chain/include/eosio/chain/apply_context.hpp
浏览文件 @
596244e1
...
...
@@ -389,7 +389,9 @@ class apply_context {
const
chainbase
::
database
&
db
;
///< database where state is stored
const
action
&
act
;
///< message being applied
account_name
receiver
;
///< the code that is currently running
bool
privileged
=
false
;
bool
privileged
=
false
;
bool
context_free
=
false
;
bool
used_context_free_api
=
false
;
chain_controller
&
mutable_controller
;
chainbase
::
database
&
mutable_db
;
...
...
@@ -425,6 +427,9 @@ class apply_context {
void
checktime
(
uint32_t
instruction_count
)
const
;
int
get_action
(
uint32_t
type
,
uint32_t
index
,
char
*
buffer
,
size_t
buffer_size
)
const
;
int
get_context_free_data
(
uint32_t
index
,
char
*
buffer
,
size_t
buffer_size
)
const
;
void
update_db_usage
(
const
account_name
&
payer
,
int64_t
delta
);
int
db_store_i64
(
uint64_t
scope
,
uint64_t
table
,
const
account_name
&
payer
,
uint64_t
id
,
const
char
*
buffer
,
size_t
buffer_size
);
void
db_update_i64
(
int
iterator
,
account_name
payer
,
const
char
*
buffer
,
size_t
buffer_size
);
...
...
libraries/chain/include/eosio/chain/transaction.hpp
浏览文件 @
596244e1
...
...
@@ -115,6 +115,8 @@ namespace eosio { namespace chain {
uint16_t
region
=
0
;
///< the computational memory region this transaction applies to.
uint16_t
ref_block_num
=
0
;
///< specifies a block num in the last 2^16 blocks.
uint32_t
ref_block_prefix
=
0
;
///< specifies the lower 32 bits of the blockid at get_ref_blocknum
uint16_t
packed_bandwidth_words
=
0
;
/// number of 8 byte words this transaction can compress into
uint16_t
context_free_cpu_bandwidth
=
0
;
/// number of CPU usage units to bill transaction for
/**
* @return the absolute block number given the relative ref_block_num
...
...
@@ -132,6 +134,7 @@ namespace eosio { namespace chain {
* read and write scopes.
*/
struct
transaction
:
public
transaction_header
{
vector
<
action
>
context_free_actions
;
vector
<
action
>
actions
;
transaction_id_type
id
()
const
;
...
...
@@ -152,6 +155,7 @@ namespace eosio { namespace chain {
}
vector
<
signature_type
>
signatures
;
vector
<
vector
<
char
>>
context_free_data
;
///< for each context-free action, there is an entry here
const
signature_type
&
sign
(
const
private_key_type
&
key
,
const
chain_id_type
&
chain_id
);
signature_type
sign
(
const
private_key_type
&
key
,
const
chain_id_type
&
chain_id
)
const
;
...
...
@@ -252,9 +256,9 @@ namespace eosio { namespace chain {
FC_REFLECT
(
eosio
::
chain
::
permission_level
,
(
actor
)(
permission
)
)
FC_REFLECT
(
eosio
::
chain
::
action
,
(
account
)(
name
)(
authorization
)(
data
)
)
FC_REFLECT
(
eosio
::
chain
::
transaction_header
,
(
expiration
)(
region
)(
ref_block_num
)(
ref_block_prefix
)
)
FC_REFLECT_DERIVED
(
eosio
::
chain
::
transaction
,
(
eosio
::
chain
::
transaction_header
),
(
actions
)
)
FC_REFLECT_DERIVED
(
eosio
::
chain
::
signed_transaction
,
(
eosio
::
chain
::
transaction
),
(
signatures
)
)
FC_REFLECT
(
eosio
::
chain
::
transaction_header
,
(
expiration
)(
region
)(
ref_block_num
)(
ref_block_prefix
)
(
packed_bandwidth_words
)(
context_free_cpu_bandwidth
)
)
FC_REFLECT_DERIVED
(
eosio
::
chain
::
transaction
,
(
eosio
::
chain
::
transaction_header
),
(
context_free_actions
)(
actions
)
)
FC_REFLECT_DERIVED
(
eosio
::
chain
::
signed_transaction
,
(
eosio
::
chain
::
transaction
),
(
signatures
)
(
context_free_data
)
)
FC_REFLECT_ENUM
(
eosio
::
chain
::
packed_transaction
::
compression_type
,
(
none
)(
zlib
))
FC_REFLECT
(
eosio
::
chain
::
packed_transaction
,
(
signatures
)(
compression
)(
data
)
)
FC_REFLECT_DERIVED
(
eosio
::
chain
::
deferred_transaction
,
(
eosio
::
chain
::
transaction
),
(
sender_id
)(
sender
)(
execute_after
)
)
...
...
libraries/chain/include/eosio/chain/transaction_metadata.hpp
浏览文件 @
596244e1
...
...
@@ -27,6 +27,7 @@ class transaction_metadata {
// things for packed_transaction
optional
<
bytes
>
raw_trx
;
optional
<
transaction
>
decompressed_trx
;
vector
<
vector
<
char
>>
context_free_data
;
// things for signed/packed transactions
optional
<
flat_set
<
public_key_type
>>
signing_keys
;
...
...
libraries/chain/wasm_interface.cpp
浏览文件 @
596244e1
...
...
@@ -408,10 +408,15 @@ namespace eosio { namespace chain {
class
context_aware_api
{
public:
context_aware_api
(
wasm_interface
&
wasm
)
:
context
(
intrinsics_accessor
::
get_context
(
wasm
).
context
),
code
(
intrinsics_accessor
::
get_context
(
wasm
).
code
),
sbrk_bytes
(
intrinsics_accessor
::
get_context
(
wasm
).
sbrk_bytes
)
{}
context_aware_api
(
wasm_interface
&
wasm
,
bool
context_free
=
false
)
:
sbrk_bytes
(
intrinsics_accessor
::
get_context
(
wasm
).
sbrk_bytes
),
code
(
intrinsics_accessor
::
get_context
(
wasm
).
code
),
context
(
intrinsics_accessor
::
get_context
(
wasm
).
context
)
{
if
(
context
.
context_free
)
FC_ASSERT
(
context_free
,
"only context free api's can be used in this context"
);
context
.
used_context_free_api
|=
!
context_free
;
}
protected:
uint32_t
&
sbrk_bytes
;
...
...
@@ -419,6 +424,18 @@ class context_aware_api {
apply_context
&
context
;
};
class
context_free_api
:
public
context_aware_api
{
public:
context_free_api
(
wasm_interface
&
wasm
)
:
context_aware_api
(
wasm
,
true
)
{
/* the context_free_data is not available during normal application because it is prunable */
FC_ASSERT
(
context
.
context_free
,
"this API may only be called from context_free apply"
);
}
int
get_context_free_data
(
uint32_t
index
,
array_ptr
<
char
>
buffer
,
size_t
buffer_size
)
const
{
return
context
.
get_context_free_data
(
index
,
buffer
,
buffer_size
);
}
};
class
privileged_api
:
public
context_aware_api
{
public:
privileged_api
(
wasm_interface
&
wasm
)
...
...
@@ -909,7 +926,8 @@ class db_index_api : public context_aware_api {
class
memory_api
:
public
context_aware_api
{
public:
using
context_aware_api
::
context_aware_api
;
memory_api
(
wasm_interface
&
wasm
)
:
context_aware_api
(
wasm
,
true
){}
char
*
memcpy
(
array_ptr
<
char
>
dest
,
array_ptr
<
const
char
>
src
,
size_t
length
)
{
return
(
char
*
)
::
memcpy
(
dest
,
src
,
length
);
...
...
@@ -966,6 +984,36 @@ class transaction_api : public context_aware_api {
public:
using
context_aware_api
::
context_aware_api
;
void
send_inline
(
array_ptr
<
char
>
data
,
size_t
data_len
)
{
// TODO: use global properties object for dynamic configuration of this default_max_gen_trx_size
FC_ASSERT
(
data_len
<
config
::
default_max_inline_action_size
,
"inline action too big"
);
action
act
;
fc
::
raw
::
unpack
<
action
>
(
data
,
data_len
,
act
);
context
.
execute_inline
(
std
::
move
(
act
));
}
void
send_deferred
(
uint32_t
sender_id
,
const
fc
::
time_point_sec
&
execute_after
,
array_ptr
<
char
>
data
,
size_t
data_len
)
{
try
{
// TODO: use global properties object for dynamic configuration of this default_max_gen_trx_size
FC_ASSERT
(
data_len
<
config
::
default_max_gen_trx_size
,
"generated transaction too big"
);
deferred_transaction
dtrx
;
fc
::
raw
::
unpack
<
transaction
>
(
data
,
data_len
,
dtrx
);
dtrx
.
sender
=
context
.
receiver
;
dtrx
.
sender_id
=
sender_id
;
dtrx
.
execute_after
=
execute_after
;
context
.
execute_deferred
(
std
::
move
(
dtrx
));
}
FC_CAPTURE_AND_RETHROW
((
fc
::
to_hex
(
data
,
data_len
)));
}
};
class
context_free_transaction_api
:
public
context_aware_api
{
public:
context_free_transaction_api
(
wasm_interface
&
wasm
)
:
context_aware_api
(
wasm
,
true
){}
int
read_transaction
(
array_ptr
<
char
>
data
,
size_t
data_len
)
{
bytes
trx
=
context
.
get_packed_transaction
();
if
(
data_len
>=
trx
.
size
())
{
...
...
@@ -989,28 +1037,8 @@ class transaction_api : public context_aware_api {
return
context
.
trx_meta
.
trx
().
ref_block_prefix
;
}
void
send_inline
(
array_ptr
<
char
>
data
,
size_t
data_len
)
{
// TODO: use global properties object for dynamic configuration of this default_max_gen_trx_size
FC_ASSERT
(
data_len
<
config
::
default_max_inline_action_size
,
"inline action too big"
);
action
act
;
fc
::
raw
::
unpack
<
action
>
(
data
,
data_len
,
act
);
context
.
execute_inline
(
std
::
move
(
act
));
}
void
send_deferred
(
uint32_t
sender_id
,
const
fc
::
time_point_sec
&
execute_after
,
array_ptr
<
char
>
data
,
size_t
data_len
)
{
try
{
// TODO: use global properties object for dynamic configuration of this default_max_gen_trx_size
FC_ASSERT
(
data_len
<
config
::
default_max_gen_trx_size
,
"generated transaction too big"
);
deferred_transaction
dtrx
;
fc
::
raw
::
unpack
<
transaction
>
(
data
,
data_len
,
dtrx
);
dtrx
.
sender
=
context
.
receiver
;
dtrx
.
sender_id
=
sender_id
;
dtrx
.
execute_after
=
execute_after
;
context
.
execute_deferred
(
std
::
move
(
dtrx
));
}
FC_CAPTURE_AND_RETHROW
((
fc
::
to_hex
(
data
,
data_len
)));
int
get_action
(
uint32_t
type
,
uint32_t
index
,
array_ptr
<
char
>
buffer
,
size_t
buffer_size
)
const
{
return
context
.
get_action
(
type
,
index
,
buffer
,
buffer_size
);
}
};
...
...
@@ -1113,16 +1141,24 @@ REGISTER_INTRINSICS(console_api,
(
printhex
,
void
(
int
,
int
)
)
);
REGISTER_INTRINSICS
(
transaction_api
,
REGISTER_INTRINSICS
(
context_free_
transaction_api
,
(
read_transaction
,
int
(
int
,
int
)
)
(
transaction_size
,
int
()
)
(
expiration
,
int
()
)
(
tapos_block_prefix
,
int
()
)
(
tapos_block_num
,
int
()
)
(
get_action
,
int
(
int
,
int
,
int
,
int
)
)
);
REGISTER_INTRINSICS
(
transaction_api
,
(
send_inline
,
void
(
int
,
int
)
)
(
send_deferred
,
void
(
int
,
int
,
int
,
int
)
)
);
REGISTER_INTRINSICS
(
context_free_api
,
(
get_context_free_data
,
int
(
int
,
int
,
int
)
)
)
REGISTER_INTRINSICS
(
memory_api
,
(
memcpy
,
int
(
int
,
int
,
int
)
)
(
memmove
,
int
(
int
,
int
,
int
)
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录