Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
45ad2937
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,发现更多精彩内容 >>
提交
45ad2937
编写于
9月 04, 2017
作者:
B
Bart Wyatt
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
initial implementation of wasm interface for transaction contract api ref EOSIO/eos#175
上级
f7158527
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
176 addition
and
28 deletion
+176
-28
contracts/eoslib/transaction.h
contracts/eoslib/transaction.h
+5
-2
libraries/chain/include/eos/chain/exceptions.hpp
libraries/chain/include/eos/chain/exceptions.hpp
+2
-0
libraries/chain/include/eos/chain/message_handling_contexts.hpp
...ies/chain/include/eos/chain/message_handling_contexts.hpp
+42
-3
libraries/chain/message_handling_contexts.cpp
libraries/chain/message_handling_contexts.cpp
+45
-0
libraries/chain/wasm_interface.cpp
libraries/chain/wasm_interface.cpp
+82
-23
未找到文件。
contracts/eoslib/transaction.h
浏览文件 @
45ad2937
...
@@ -58,6 +58,8 @@ extern "C" {
...
@@ -58,6 +58,8 @@ extern "C" {
typedef
uint32_t
TransactionHandle
;
typedef
uint32_t
TransactionHandle
;
#define InvalidTransactionHandle (0xFFFFFFFFUL)
#define InvalidTransactionHandle (0xFFFFFFFFUL)
#define SendInline (1)
#define SendDeferred (0)
/**
/**
* @brief create a pending transaction
* @brief create a pending transaction
...
@@ -103,9 +105,10 @@ extern "C" {
...
@@ -103,9 +105,10 @@ extern "C" {
* This function adds a @ref PermissionName to the pending message
* This function adds a @ref PermissionName to the pending message
*
*
* @param trx - the `TransactionHandle` of the pending transaction to modify
* @param trx - the `TransactionHandle` of the pending transaction to modify
* @param account - the `AccountName` to add
* @param permission - the `PermissionName` to add
* @param permission - the `PermissionName` to add
*/
*/
void
transactionAddMessagePermission
(
TransactionHandle
trx
,
PermissionName
permission
);
void
transactionAddMessagePermission
(
TransactionHandle
trx
,
AccountName
account
,
PermissionName
permission
);
/**
/**
...
@@ -147,7 +150,7 @@ extern "C" {
...
@@ -147,7 +150,7 @@ extern "C" {
* @param trx - the `TransactionHandle` of the pending transaction to send
* @param trx - the `TransactionHandle` of the pending transaction to send
* @param inlineMode - whether to send as an inline transaction (!=0) or deferred(=0)
* @param inlineMode - whether to send as an inline transaction (!=0) or deferred(=0)
*/
*/
void
transactionSend
(
TransactionHandle
trx
,
int
inlineMode
=
0
);
void
transactionSend
(
TransactionHandle
trx
,
int
mode
=
SendDeferred
);
/**
/**
* @brief drop a pending transaction
* @brief drop a pending transaction
...
...
libraries/chain/include/eos/chain/exceptions.hpp
浏览文件 @
45ad2937
...
@@ -57,6 +57,8 @@ namespace eos { namespace chain {
...
@@ -57,6 +57,8 @@ namespace eos { namespace chain {
FC_DECLARE_DERIVED_EXCEPTION
(
tx_duplicate
,
eos
::
chain
::
transaction_exception
,
3030011
,
"duplicate transaction"
)
FC_DECLARE_DERIVED_EXCEPTION
(
tx_duplicate
,
eos
::
chain
::
transaction_exception
,
3030011
,
"duplicate transaction"
)
FC_DECLARE_DERIVED_EXCEPTION
(
unknown_transaction_exception
,
eos
::
chain
::
transaction_exception
,
3030012
,
"unknown transaction"
)
FC_DECLARE_DERIVED_EXCEPTION
(
unknown_transaction_exception
,
eos
::
chain
::
transaction_exception
,
3030012
,
"unknown transaction"
)
FC_DECLARE_DERIVED_EXCEPTION
(
tx_scheduling_exception
,
eos
::
chain
::
transaction_exception
,
3030013
,
"transaction failed during sheduling"
)
FC_DECLARE_DERIVED_EXCEPTION
(
tx_scheduling_exception
,
eos
::
chain
::
transaction_exception
,
3030013
,
"transaction failed during sheduling"
)
FC_DECLARE_DERIVED_EXCEPTION
(
tx_unknown_argument
,
eos
::
chain
::
transaction_exception
,
3030014
,
"transaction provided an unknown value to a system call"
)
FC_DECLARE_DERIVED_EXCEPTION
(
tx_resource_exhausted
,
eos
::
chain
::
transaction_exception
,
3030015
,
"transaction exhausted allowed resources"
)
FC_DECLARE_DERIVED_EXCEPTION
(
invalid_pts_address
,
eos
::
chain
::
utility_exception
,
3060001
,
"invalid pts address"
)
FC_DECLARE_DERIVED_EXCEPTION
(
invalid_pts_address
,
eos
::
chain
::
utility_exception
,
3060001
,
"invalid pts address"
)
FC_DECLARE_DERIVED_EXCEPTION
(
insufficient_feeds
,
eos
::
chain
::
chain_exception
,
37006
,
"insufficient feeds"
)
FC_DECLARE_DERIVED_EXCEPTION
(
insufficient_feeds
,
eos
::
chain
::
chain_exception
,
37006
,
"insufficient feeds"
)
...
...
libraries/chain/include/eos/chain/message_handling_contexts.hpp
浏览文件 @
45ad2937
...
@@ -19,7 +19,8 @@ public:
...
@@ -19,7 +19,8 @@ public:
const
chain
::
Message
&
m
,
const
chain
::
Message
&
m
,
const
types
::
AccountName
&
code
)
const
types
::
AccountName
&
code
)
:
controller
(
con
),
db
(
db
),
trx
(
t
),
msg
(
m
),
code
(
code
),
mutable_controller
(
con
),
:
controller
(
con
),
db
(
db
),
trx
(
t
),
msg
(
m
),
code
(
code
),
mutable_controller
(
con
),
mutable_db
(
db
),
used_authorizations
(
msg
.
authorization
.
size
(),
false
){}
mutable_db
(
db
),
used_authorizations
(
msg
.
authorization
.
size
(),
false
),
next_pending_transaction_serial
(
0
){}
template
<
typename
ObjectType
>
template
<
typename
ObjectType
>
int32_t
store_record
(
Name
scope
,
Name
code
,
Name
table
,
typename
ObjectType
::
key_type
*
keys
,
char
*
value
,
uint32_t
valuelen
)
{
int32_t
store_record
(
Name
scope
,
Name
code
,
Name
table
,
typename
ObjectType
::
key_type
*
keys
,
char
*
value
,
uint32_t
valuelen
)
{
...
@@ -286,11 +287,49 @@ public:
...
@@ -286,11 +287,49 @@ public:
chainbase
::
database
&
mutable_db
;
chainbase
::
database
&
mutable_db
;
std
::
deque
<
AccountName
>
notified
;
std
::
deque
<
AccountName
>
notified
;
std
::
deque
<
ProcessedTransaction
>
sync_transactions
;
///< sync calls made
std
::
deque
<
Transaction
>
inline_transactions
;
///< queued inline txs
std
::
deque
<
GeneratedTransaction
>
async_transactions
;
///< async calls requested
std
::
deque
<
Transaction
>
deferred_transactions
;
///< deferred txs
///< Parallel to msg.authorization; tracks which permissions have been used while processing the message
///< Parallel to msg.authorization; tracks which permissions have been used while processing the message
vector
<
bool
>
used_authorizations
;
vector
<
bool
>
used_authorizations
;
///< pending transaction construction
typedef
uint32_t
pending_transaction_handle
;
struct
pending_transaction
{
typedef
uint32_t
handle_type
;
static
const
handle_type
Invalid_handle
=
0xFFFFFFFFUL
;
handle_type
handle
;
struct
message_dest
{
AccountName
code
;
FuncName
type
;
};
// state set that applies to pushed message data
optional
<
message_destination
>
current_destination
;
vector
<
types
::
AccountPermission
>
current_permissions
;
// state to apply when the transaction is pushed
vector
<
AccountName
>
scopes
;
vector
<
AccountName
>
read_scopes
;
vector
<
types
::
Message
>
messages
;
types
::
Transaction
as_transaction
()
const
;
void
check_size
()
const
;
void
reset_message
()
{
current_destination
=
decltype
(
current_destination
)();
current_permissions
.
clear
();
}
};
pending_transaction
::
handle_type
next_pending_transaction_serial
;
vector
<
pending_transaction
>
pending_transactions
;
pending_transaction
&
get_pending_transaction
(
pending_transaction
::
handle_type
handle
);
pending_transaction
&
create_pending_transaction
();
void
release_pending_transaction
(
pending_transaction
::
handle_type
handle
);
};
};
using
apply_handler
=
std
::
function
<
void
(
apply_context
&
)
>
;
using
apply_handler
=
std
::
function
<
void
(
apply_context
&
)
>
;
...
...
libraries/chain/message_handling_contexts.cpp
浏览文件 @
45ad2937
...
@@ -51,4 +51,49 @@ vector<types::AccountPermission> apply_context::unused_authorizations() const {
...
@@ -51,4 +51,49 @@ vector<types::AccountPermission> apply_context::unused_authorizations() const {
return
{
range
.
begin
(),
range
.
end
()};
return
{
range
.
begin
(),
range
.
end
()};
}
}
pending_transaction
&
apply_context
::
get_pending_transaction
(
pending_transaction
::
handle_type
handle
)
{
auto
itr
=
boost
::
find_if
(
pending_transactions
,
[
&
](
const
auto
&
trx
)
{
return
trx
.
handle
==
handle
;
});
EOS_ASSERT
(
itr
!=
pending_transactions
.
end
(),
tx_unknown_argument
,
"Transaction refers to non-existant/destroyed pending transaction"
);
return
*
itr
;
}
const
int
Max_pending_transactions
=
4
;
const
uint32_t
Max_pending_transaction_size
=
16
*
1024
;
const
auto
Pending_transaction_expiration
=
fc
::
seconds
(
21
*
3
);
pending_transaction
&
apply_context
::
create_pending_transaction
()
{
EOS_ASSERT
(
pending_transactions
.
size
()
<
Max_pending_transactions
,
tx_resource_exhausted
,
"Transaction is attempting to create too many pending transactions. The max is ${max}"
,
(
"max"
,
Max_pending_transactions
));)
pending_transaction
::
handle
handle
=
next_pending_transaction_serial
++
;
pending_transactions
.
push_back
({
handle
});
return
pending_transaction
.
back
();
}
void
apply_context
::
release_pending_transaction
(
pending_transaction
::
handle_type
handle
)
{
auto
itr
=
boost
::
find_if
(
pending_transactions
,
[
&
](
const
auto
&
trx
)
{
return
trx
.
handle
==
handle
;
});
EOS_ASSERT
(
itr
!=
pending_transactions
.
end
(),
tx_unknown_argument
,
"Transaction refers to non-existant/destroyed pending transaction"
);
auto
last
=
pending_transactions
.
end
()
-
1
;
if
(
itr
!=
last
)
{
std
::
swap
(
itr
,
last
);
}
pending_transactions
.
pop_back
();
}
types
::
Transaction
apply_context
::
pending_transaction
::
as_transaction
()
const
{
decltype
(
types
::
Transaction
::
refBlockNum
)
head_block_num
=
chain_controller
.
head_block_num
();
decltype
(
types
::
Transaction
::
refBlockRef
)
head_block_ref
=
fc
::
endian_reverse_u32
(
chain_controller
.
head_block_ref
().
_hash
[
0
]);
decltype
(
types
::
Transaction
::
expiration
)
expiration
=
chain_controller
.
head_block_time
()
+
Pending_transaction_expiration
;
return
types
::
Transaction
(
head_block_num
,
head_block_ref
,
expiration
,
scopes
,
read_scopes
,
messages
);
}
void
apply_context
::
pending_transaction
::
check_size
()
const
{
auto
trx
=
as_transaction
();
EOS_ASSERT
(
fc
::
raw
::
pack_size
(
trx
)
<=
Max_pending_transaction_size
,
tx_resource_exhausted
,
"Transaction is attempting to create a transaction which is too large. The max size is ${max} bytes"
,
(
"max"
,
Max_pending_transaction_size
));
}
}
}
// namespace eos::chain
}
}
// namespace eos::chain
libraries/chain/wasm_interface.cpp
浏览文件 @
45ad2937
...
@@ -241,39 +241,98 @@ DEFINE_INTRINSIC_FUNCTION3(env,memcpy,memcpy,i32,i32,dstp,i32,srcp,i32,len) {
...
@@ -241,39 +241,98 @@ DEFINE_INTRINSIC_FUNCTION3(env,memcpy,memcpy,i32,i32,dstp,i32,srcp,i32,len) {
}
}
DEFINE_INTRINSIC_FUNCTION2
(
env
,
send
,
send
,
i32
,
i32
,
trx_buffer
,
i32
,
trx_buffer_size
)
{
/**
* Transaction C API implementation
* @{
*/
static
const
uint32_t
InvalidTransactionHandle
=
0xFFFFFFFFUL
;
DEFINE_INTRINSIC_FUNCTION0
(
env
,
transactionCreate
,
transactionCreate
,
i32
)
{
auto
&
ptrx
=
wasm_interface
::
get
().
current_apply_context
->
create_pending_transaction
();
return
ptrx
.
handle
;
}
DEFINE_INTRINSIC_FUNCTION3
(
env
,
transactionAddScope
,
transactionAddScope
,
none
,
i32
,
handle
,
i64
,
scope
,
i32
,
readOnly
)
{
auto
&
ptrx
=
wasm_interface
::
get
().
current_apply_context
->
get_pending_transaction
(
handle
);
if
(
readOnly
==
0
)
{
ptrx
.
scopes
.
emplace_back
(
scope
);
}
else
{
ptrx
.
read_scopes
.
emplace_back
(
scope
);
}
ptrx
.
check_size
();
}
DEFINE_INTRINSIC_FUNCTION3
(
env
,
transactionSetMessageDestination
,
transactionSetMessageDestination
,
none
,
i32
,
handle
,
i64
,
code
,
i64
,
type
)
{
auto
&
ptrx
=
wasm_interface
::
get
().
current_apply_context
->
get_pending_transaction
(
handle
);
ptrx
.
current_destination
=
decltype
(
ptrx
.
current_destination
)({
Name
(
code
),
Name
(
type
)});
}
DEFINE_INTRINSIC_FUNCTION3
(
env
,
transactionAddMessagePermission
,
transactionAddMessagePermission
,
none
,
i32
,
handle
,
i64
,
account
,
i64
,
permission
)
{
wasm_interface
::
get
().
current_apply_context
->
require_authorization
(
Name
(
account
),
Name
(
permission
));
auto
&
ptrx
=
wasm_interface
::
get
().
current_apply_context
->
get_pending_transaction
(
handle
);
ptrx
.
current_permissions
.
emplace_back
(
Name
(
account
),
Name
(
permission
));
}
DEFINE_INTRINSIC_FUNCTION3
(
env
,
transactionPushMessage
,
transactionPushMessage
,
none
,
i32
,
handle
,
i32
,
msg_buffer
,
i32
,
msg_size
)
{
auto
&
wasm
=
wasm_interface
::
get
();
auto
&
wasm
=
wasm_interface
::
get
();
auto
mem
=
wasm
.
current_memory
;
auto
mem
=
wasm
.
current_memory
;
const
char
*
buffer
=
&
memoryRef
<
const
char
>
(
mem
,
trx_buffer
);
FC_ASSERT
(
trx_buffer_size
>
0
);
EOS_ASSERT
(
msg_size
>
0
,
tx_unknown_argument
FC_ASSERT
(
wasm
.
current_apply_context
,
"not in apply context
"
);
"Attempting to push an empty message
"
);
fc
::
datastream
<
const
char
*>
ds
(
buffer
,
trx_buffer_size
);
const
char
*
buffer
=
nullptr
;
eos
::
chain
::
GeneratedTransaction
gtrx
;
try
{
eos
::
chain
::
Transaction
&
trx
=
gtrx
;
// memoryArrayPtr checks that the entire array of bytes is valid and
fc
::
raw
::
unpack
(
ds
,
trx
);
// within the bounds of the memory segment so that transactions cannot pass
// bad values in attempts to read improper memory
buffer
=
memoryArrayPtr
<
const
char
>
(
mem
,
msg_buffer
,
msg_size
);
}
catch
(
const
Runtime
::
Exception
&
e
)
{
FC_THROW_EXCEPTION
(
tx_unknown_argument
,
"Message data is not valid"
);
}
/**
auto
&
ptrx
=
wasm
.
current_apply_context
->
get_pending_transaction
(
handle
);
* The code below this section provides sanity checks that the generated message is well formed
EOS_ASSERT
(
ptrx
.
destination
.
valid
(),
tx_unknown_argument
* before being accepted. These checks do not need to be applied during reindex.
"Attempting to push a message without setting a destination"
);
*/
#warning TODO: reserve per-thread static memory for MAX TRX SIZE
auto
&
dest
=
*
ptrx
.
destination
;
/** make sure that packing what we just unpacked produces expected output */
ptrx
.
messages
.
emplace_back
(
dest
.
code
,
dest
.
type
,
ptrx
.
current_permissions
,
Bytes
(
buffer
,
buffer
+
msg_size
));
auto
test
=
fc
::
raw
::
pack
(
trx
);
ptrx
.
reset_message
();
FC_ASSERT
(
0
==
memcmp
(
buffer
,
test
.
data
(),
test
.
size
()
)
);
ptrx
.
check_size
();
}
DEFINE_INTRINSIC_FUNCTION1
(
env
,
transactionResetMessage
,
transactionResetMessage
,
none
,
i32
,
handle
)
{
auto
&
ptrx
=
wasm_interface
::
get
().
current_apply_context
->
get_pending_transaction
(
handle
);
ptrx
.
reset_message
();
}
/** TODO: make sure that we can call validate() on the message and it passes, this is thread safe and
DEFINE_INTRINSIC_FUNCTION2
(
env
,
transactionSend
,
transactionSend
,
none
,
i32
,
handle
,
i32
,
mode
)
{
* ensures the type is properly registered and can be deserialized... one issue is that this could
EOS_ASSERT
(
mode
==
0
||
mode
==
1
,
tx_unknown_argument
* construct a RECURSIVE virtual machine state which means the wasm_interface state needs to be a STACK vs
"Unknown delivery mode when sending transaction: ${mode}"
,
(
"mode"
:
mode
));
* a per-thread global.
**/
// wasm.current_apply_context->generated.emplace_back( std::move(gtrx) );
auto
apply_context
=
wasm_interface
::
get
().
current_apply_context
;
auto
&
ptrx
=
apply_context
->
get_pending_transaction
(
handle
);
return
0
;
EOS_ASSERT
(
ptrx
.
messages
.
size
()
>
0
,
,
tx_unknown_argument
"Attempting to send a transaction with no messages"
);
if
(
mode
==
0
)
{
apply_context
->
deferred_transactions
.
emplace_back
(
ptrx
.
as_transaction
());
}
else
{
apply_context
->
inline_transactions
.
emplace_back
(
ptrx
.
as_transaction
());
}
apply_context
->
release_pending_transaction
(
handle
);
}
}
DEFINE_INTRINSIC_FUNCTION1
(
env
,
transactionDrop
,
transactionDrop
,
none
,
i32
,
handle
)
{
wasm_interface
::
get
().
current_apply_context
->
release_pending_transaction
(
handle
);
}
/**
* @} Transaction C API implementation
*/
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录