Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
4f94246b
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,发现更多精彩内容 >>
提交
4f94246b
编写于
3月 07, 2018
作者:
M
Matias Romeo
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add permission api
上级
595e66d6
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
247 addition
and
0 deletion
+247
-0
contracts/eosiolib/datastream.hpp
contracts/eosiolib/datastream.hpp
+23
-0
contracts/eosiolib/permission.h
contracts/eosiolib/permission.h
+21
-0
contracts/test_api/test_api.cpp
contracts/test_api/test_api.cpp
+5
-0
contracts/test_api/test_api.hpp
contracts/test_api/test_api.hpp
+4
-0
contracts/test_api/test_permission.cpp
contracts/test_api/test_permission.cpp
+33
-0
libraries/chain/chain_controller.cpp
libraries/chain/chain_controller.cpp
+21
-0
libraries/chain/include/eosio/chain/chain_controller.hpp
libraries/chain/include/eosio/chain/chain_controller.hpp
+10
-0
libraries/chain/wasm_interface.cpp
libraries/chain/wasm_interface.cpp
+26
-0
tests/api_tests/api_tests.cpp
tests/api_tests/api_tests.cpp
+104
-0
未找到文件。
contracts/eosiolib/datastream.hpp
浏览文件 @
4f94246b
...
...
@@ -141,6 +141,29 @@ class datastream<size_t> {
size_t
_size
;
};
/**
* Serialize a public_key into a stream
* @brief Serialize a public_key
* @param ds stream to write
* @param pubkey value to serialize
*/
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
<<
(
datastream
<
Stream
>&
ds
,
const
public_key
pubkey
)
{
ds
.
write
(
(
const
char
*
)
&
pubkey
,
sizeof
(
pubkey
));
return
ds
;
}
/**
* Deserialize a public_key from a stream
* @brief Deserialize a public_key
* @param ds stream to read
* @param pubkey destination for deserialized value
*/
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
>>
(
datastream
<
Stream
>&
ds
,
public_key
&
pubkey
)
{
ds
.
read
((
char
*
)
&
pubkey
,
sizeof
(
pubkey
));
return
ds
;
}
/**
* Serialize a key256 into a stream
* @brief Serialize a key256
...
...
contracts/eosiolib/permission.h
0 → 100644
浏览文件 @
4f94246b
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#pragma once
#include <eosiolib/types.h>
extern
"C"
{
/**
* Checks if a set of public keys can authorize an account permission
* @brief Checks if a set of public keys can authorize an account permission
* @param account - the account owner of the permission
* @param permission - the permission name to check for authorization
* @param pubkeys - a pointer to an array of public keys (public_key)
* @param pubkeys_len - the lenght of the array of public keys
* @return 1 if the account permission can be authorized, 0 otherwise
*/
int32_t
check_authorization
(
account_name
account
,
permission_name
permission
,
char
*
pubkeys
,
uint32_t
pubkeys_len
);
}
contracts/test_api/test_api.cpp
浏览文件 @
4f94246b
...
...
@@ -16,6 +16,7 @@
#include "test_chain.cpp"
#include "test_transaction.cpp"
#include "test_checktime.cpp"
#include "test_permission.cpp"
extern
"C"
{
...
...
@@ -148,6 +149,7 @@ extern "C" {
// test checktime
WASM_TEST_HANDLER
(
test_checktime
,
checktime_pass
);
WASM_TEST_HANDLER
(
test_checktime
,
checktime_failure
);
/*
// test softfloat
WASM_TEST_HANDLER(test_softfloat, test_f32_add);
...
...
@@ -157,6 +159,9 @@ extern "C" {
WASM_TEST_HANDLER(test_softfloat, test_f32_min);
*/
// test permission
WASM_TEST_HANDLER
(
test_permission
,
check_authorization
);
//unhandled test call
eosio_assert
(
false
,
"Unknown Test"
);
...
...
contracts/test_api/test_api.hpp
浏览文件 @
4f94246b
...
...
@@ -277,3 +277,7 @@ struct test_softfloat {
static void test_f32_min();
};
*/
struct
test_permission
{
static
void
check_authorization
();
};
contracts/test_api/test_permission.cpp
0 → 100644
浏览文件 @
4f94246b
/**
* @file action_test.cpp
* @copyright defined in eos/LICENSE.txt
*/
#include <eosiolib/permission.h>
#include <eosiolib/db.h>
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/compiler_builtins.h>
#include <eosiolib/serialize.hpp>
#include <eosiolib/action.hpp>
#include "test_api.hpp"
using
namespace
eosio
;
struct
check_auth
{
account_name
account
;
permission_name
permission
;
vector
<
public_key
>
pubkeys
;
EOSLIB_SERIALIZE
(
check_auth
,
(
account
)(
permission
)(
pubkeys
)
)
};
void
test_permission
::
check_authorization
()
{
auto
params
=
unpack_action_data
<
check_auth
>
();
uint64_t
res64
=
(
uint64_t
)
::
check_authorization
(
params
.
account
,
params
.
permission
,
(
char
*
)
params
.
pubkeys
.
data
(),
params
.
pubkeys
.
size
()
*
sizeof
(
public_key
)
);
store_i64
(
current_receiver
(),
current_receiver
(),
current_receiver
(),
&
res64
,
sizeof
(
uint64_t
));
}
libraries/chain/chain_controller.cpp
浏览文件 @
4f94246b
...
...
@@ -842,6 +842,7 @@ flat_set<public_key_type> chain_controller::get_required_keys(const transaction&
return
checker
.
used_keys
();
}
class
permission_visitor
{
public:
permission_visitor
(
const
chain_controller
&
controller
)
:
_chain_controller
(
controller
)
{}
...
...
@@ -863,6 +864,7 @@ time_point chain_controller::check_authorization( const vector<action>& actions,
const
flat_set
<
public_key_type
>&
provided_keys
,
bool
allow_unused_signatures
,
flat_set
<
account_name
>
provided_accounts
)
const
{
auto
checker
=
make_auth_checker
(
[
&
](
const
permission_level
&
p
){
return
get_permission
(
p
).
auth
;
},
permission_visitor
(
*
this
),
...
...
@@ -963,6 +965,25 @@ time_point chain_controller::check_authorization( const vector<action>& actions,
return
max_delay
;
}
bool
chain_controller
::
check_authorization
(
account_name
account
,
permission_name
permission
,
flat_set
<
public_key_type
>
provided_keys
,
bool
allow_unused_signatures
)
const
{
auto
checker
=
make_auth_checker
(
[
&
](
const
permission_level
&
p
){
return
get_permission
(
p
).
auth
;
},
get_global_properties
().
configuration
.
max_authority_depth
,
provided_keys
);
auto
satisfied
=
checker
.
satisfied
({
account
,
permission
});
if
(
satisfied
&&
!
allow_unused_signatures
)
{
EOS_ASSERT
(
checker
.
all_keys_used
(),
tx_irrelevant_sig
,
"irrelevant signatures from these keys: ${keys}"
,
(
"keys"
,
checker
.
unused_keys
()));
}
return
satisfied
;
}
time_point
chain_controller
::
check_transaction_authorization
(
const
transaction
&
trx
,
const
vector
<
signature_type
>&
signatures
,
const
vector
<
bytes
>&
cfd
,
...
...
libraries/chain/include/eosio/chain/chain_controller.hpp
浏览文件 @
4f94246b
...
...
@@ -294,6 +294,16 @@ namespace eosio { namespace chain {
flat_set
<
account_name
>
provided_accounts
=
flat_set
<
account_name
>
()
)
const
;
/**
* @param account - the account owner of the permission
* @param permission - the permission name to check for authorization
* @param provided_keys - a set of public keys
*
* @return true if the provided keys are sufficient to authorize the account permission
*/
bool
check_authorization
(
account_name
account
,
permission_name
permission
,
flat_set
<
public_key_type
>
provided_keys
,
bool
allow_unused_signatures
)
const
;
private:
const
apply_handler
*
find_apply_handler
(
account_name
contract
,
scope_name
scope
,
action_name
act
)
const
;
...
...
libraries/chain/wasm_interface.cpp
浏览文件 @
4f94246b
...
...
@@ -752,6 +752,28 @@ class crypto_api : public context_aware_api {
}
};
class
permission_api
:
public
context_aware_api
{
public:
using
context_aware_api
::
context_aware_api
;
bool
check_authorization
(
account_name
account
,
permission_name
permission
,
array_ptr
<
char
>
packed_pubkeys
,
size_t
datalen
)
{
vector
<
public_key_type
>
pub_keys
;
datastream
<
const
char
*>
ds
(
packed_pubkeys
,
datalen
);
while
(
ds
.
remaining
())
{
public_key_type
pub
;
fc
::
raw
::
unpack
(
ds
,
pub
);
pub_keys
.
emplace_back
(
pub
);
}
return
context
.
controller
.
check_authorization
(
account
,
permission
,
{
pub_keys
.
begin
(),
pub_keys
.
end
()},
false
);
}
};
class
string_api
:
public
context_aware_api
{
public:
using
context_aware_api
::
context_aware_api
;
...
...
@@ -1501,6 +1523,10 @@ REGISTER_INTRINSICS(crypto_api,
(
ripemd160
,
void
(
int
,
int
,
int
)
)
);
REGISTER_INTRINSICS
(
permission_api
,
(
check_authorization
,
int
(
int64_t
,
int64_t
,
int
,
int
))
);
REGISTER_INTRINSICS
(
string_api
,
(
assert_is_utf8
,
void
(
int
,
int
,
int
)
)
);
...
...
tests/api_tests/api_tests.cpp
浏览文件 @
4f94246b
...
...
@@ -81,7 +81,13 @@ struct test_chain_action {
FC_REFLECT_TEMPLATE
((
uint64_t
T
),
test_chain_action
<
T
>
,
BOOST_PP_SEQ_NIL
);
struct
check_auth
{
account_name
account
;
permission_name
permission
;
vector
<
public_key_type
>
pubkeys
;
};
FC_REFLECT
(
check_auth
,
(
account
)(
permission
)(
pubkeys
)
);
bool
expect_assert_message
(
const
fc
::
exception
&
ex
,
string
expected
)
{
BOOST_TEST_MESSAGE
(
"LOG : "
<<
"expected: "
<<
expected
<<
", actual: "
<<
ex
.
get_log
().
at
(
0
).
get_message
());
...
...
@@ -1207,6 +1213,104 @@ BOOST_FIXTURE_TEST_CASE(types_tests, tester) { try {
CALL_TEST_FUNCTION
(
*
this
,
"test_types"
,
"name_class"
,
{});
}
FC_LOG_AND_RETHROW
()
}
/*************************************************************************************
* permission_tests test case
*************************************************************************************/
BOOST_FIXTURE_TEST_CASE
(
permission_tests
,
tester
)
{
try
{
produce_blocks
(
1
);
create_account
(
N
(
testapi
)
);
produce_blocks
(
1
);
set_code
(
N
(
testapi
),
test_api_wast
);
produce_blocks
(
1
);
auto
get_result_uint64
=
[
&
]()
->
uint64_t
{
const
auto
&
db
=
control
->
get_database
();
const
auto
*
t_id
=
db
.
find
<
table_id_object
,
by_code_scope_table
>
(
boost
::
make_tuple
(
N
(
testapi
),
N
(
testapi
),
N
(
testapi
)));
FC_ASSERT
(
t_id
!=
0
,
"Table id not found"
);
const
auto
&
idx
=
db
.
get_index
<
key_value_index
,
by_scope_primary
>
();
auto
itr
=
idx
.
lower_bound
(
boost
::
make_tuple
(
t_id
->
id
));
FC_ASSERT
(
itr
!=
idx
.
end
()
&&
itr
->
t_id
==
t_id
->
id
,
"lower_bound failed"
);
FC_ASSERT
(
0
==
itr
->
value
.
size
(),
"unexpected result size"
);
return
itr
->
primary_key
;
};
CALL_TEST_FUNCTION
(
*
this
,
"test_permission"
,
"check_authorization"
,
fc
::
raw
::
pack
(
check_auth
{
.
account
=
N
(
testapi
),
.
permission
=
N
(
active
),
.
pubkeys
=
{
get_public_key
(
N
(
testapi
),
"active"
)
}
})
);
BOOST_CHECK_EQUAL
(
uint64_t
(
1
),
get_result_uint64
()
);
CALL_TEST_FUNCTION
(
*
this
,
"test_permission"
,
"check_authorization"
,
fc
::
raw
::
pack
(
check_auth
{
.
account
=
N
(
testapi
),
.
permission
=
N
(
active
),
.
pubkeys
=
{
public_key_type
(
string
(
"EOS7GfRtyDWWgxV88a5TRaYY59XmHptyfjsFmHHfioGNJtPjpSmGX"
))
}
})
);
BOOST_CHECK_EQUAL
(
uint64_t
(
0
),
get_result_uint64
()
);
BOOST_CHECK_EXCEPTION
(
CALL_TEST_FUNCTION
(
*
this
,
"test_permission"
,
"check_authorization"
,
fc
::
raw
::
pack
(
check_auth
{
.
account
=
N
(
testapi
),
.
permission
=
N
(
active
),
.
pubkeys
=
{
get_public_key
(
N
(
testapi
),
"active"
),
public_key_type
(
string
(
"EOS7GfRtyDWWgxV88a5TRaYY59XmHptyfjsFmHHfioGNJtPjpSmGX"
))
}
})),
tx_irrelevant_sig
,
[](
const
tx_irrelevant_sig
&
e
)
{
return
expect_assert_message
(
e
,
"irrelevant signatures from these keys: [
\"
EOS7GfRtyDWWgxV88a5TRaYY59XmHptyfjsFmHHfioGNJtPjpSmGX
\"
]"
);
}
);
BOOST_CHECK_EXCEPTION
(
CALL_TEST_FUNCTION
(
*
this
,
"test_permission"
,
"check_authorization"
,
fc
::
raw
::
pack
(
check_auth
{
.
account
=
N
(
noname
),
.
permission
=
N
(
active
),
.
pubkeys
=
{
get_public_key
(
N
(
testapi
),
"active"
)
}
})),
fc
::
exception
,
[](
const
fc
::
exception
&
e
)
{
return
expect_assert_message
(
e
,
"unknown key"
);
}
);
CALL_TEST_FUNCTION
(
*
this
,
"test_permission"
,
"check_authorization"
,
fc
::
raw
::
pack
(
check_auth
{
.
account
=
N
(
testapi
),
.
permission
=
N
(
active
),
.
pubkeys
=
{}
})
);
BOOST_CHECK_EQUAL
(
uint64_t
(
0
),
get_result_uint64
()
);
BOOST_CHECK_EXCEPTION
(
CALL_TEST_FUNCTION
(
*
this
,
"test_permission"
,
"check_authorization"
,
fc
::
raw
::
pack
(
check_auth
{
.
account
=
N
(
testapi
),
.
permission
=
N
(
noname
),
.
pubkeys
=
{
get_public_key
(
N
(
testapi
),
"active"
)
}
})),
fc
::
exception
,
[](
const
fc
::
exception
&
e
)
{
return
expect_assert_message
(
e
,
"unknown key"
);
}
);
}
FC_LOG_AND_RETHROW
()
}
#if 0
/*************************************************************************************
* privileged_tests test case
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录