Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
81248dfe
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,发现更多精彩内容 >>
提交
81248dfe
编写于
8月 10, 2017
作者:
B
Bart Wyatt
浏览文件
操作
浏览文件
下载
差异文件
merging changes to master @
73434fe2
上级
19d3500d
73434fe2
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
378 addition
and
91 deletion
+378
-91
libraries/chain/chain_controller.cpp
libraries/chain/chain_controller.cpp
+9
-2
libraries/chain/include/eos/chain/authority.hpp
libraries/chain/include/eos/chain/authority.hpp
+3
-50
libraries/chain/include/eos/chain/authority_checker.hpp
libraries/chain/include/eos/chain/authority_checker.hpp
+127
-0
libraries/chain/message_handling_contexts.cpp
libraries/chain/message_handling_contexts.cpp
+3
-12
libraries/fc/include/fc/scoped_exit.hpp
libraries/fc/include/fc/scoped_exit.hpp
+6
-2
libraries/types/include/eos/types/native.hpp
libraries/types/include/eos/types/native.hpp
+2
-3
libraries/utilities/include/eos/utilities/parallel_markers.hpp
...ries/utilities/include/eos/utilities/parallel_markers.hpp
+39
-0
tests/common/database_fixture.cpp
tests/common/database_fixture.cpp
+37
-0
tests/common/database_fixture.hpp
tests/common/database_fixture.hpp
+20
-0
tests/common/macro_support.hpp
tests/common/macro_support.hpp
+12
-12
tests/tests/misc_tests.cpp
tests/tests/misc_tests.cpp
+118
-10
tests/tests/native_contract_tests.cpp
tests/tests/native_contract_tests.cpp
+2
-0
未找到文件。
libraries/chain/chain_controller.cpp
浏览文件 @
81248dfe
...
...
@@ -33,6 +33,7 @@
#include <eos/chain/transaction_object.hpp>
#include <eos/chain/producer_object.hpp>
#include <eos/chain/permission_link_object.hpp>
#include <eos/chain/authority_checker.hpp>
#include <eos/chain/wasm_interface.hpp>
...
...
@@ -246,6 +247,7 @@ ProcessedTransaction chain_controller::_push_transaction(const SignedTransaction
_pending_tx_session
=
_db
.
start_undo_session
(
true
);
auto
temp_session
=
_db
.
start_undo_session
(
true
);
validate_referenced_accounts
(
trx
);
check_transaction_authorization
(
trx
);
auto
pt
=
_apply_transaction
(
trx
);
_pending_transactions
.
push_back
(
trx
);
...
...
@@ -345,6 +347,7 @@ signed_block chain_controller::_generate_block(
auto
temp_session
=
_db
.
start_undo_session
(
true
);
if
(
trx
.
contains
<
SignedTransaction
const
*>
())
{
auto
const
&
t
=
*
trx
.
get
<
SignedTransaction
const
*>
();
validate_referenced_accounts
(
t
);
check_transaction_authorization
(
t
);
auto
processed
=
_apply_transaction
(
t
);
block_thread
.
user_input
.
emplace_back
(
processed
);
...
...
@@ -481,8 +484,10 @@ void chain_controller::_apply_block(const signed_block& next_block)
for
(
const
auto
&
cycle
:
next_block
.
cycles
)
for
(
const
auto
&
thread
:
cycle
)
for
(
const
auto
&
trx
:
thread
.
user_input
)
for
(
const
auto
&
trx
:
thread
.
user_input
)
{
validate_referenced_accounts
(
trx
);
check_transaction_authorization
(
trx
);
}
/* We do not need to push the undo state for each transaction
* because they either all apply and are valid or the
...
...
@@ -546,6 +551,9 @@ void chain_controller::check_transaction_authorization(const SignedTransaction&
(
"auth"
,
declaredAuthority
));
}
}
EOS_ASSERT
(
checker
.
all_keys_used
(),
tx_irrelevant_sig
,
"Transaction bears irrelevant signatures from these keys: ${keys}"
,
(
"keys"
,
checker
.
unused_keys
()));
}
ProcessedTransaction
chain_controller
::
apply_transaction
(
const
SignedTransaction
&
trx
,
uint32_t
skip
)
...
...
@@ -561,7 +569,6 @@ try {
validate_expiration
(
trx
);
validate_uniqueness
(
trx
);
validate_tapos
(
trx
);
validate_referenced_accounts
(
trx
);
}
FC_CAPTURE_AND_RETHROW
(
(
trx
)
)
}
...
...
libraries/chain/include/eos/chain/authority.hpp
浏览文件 @
81248dfe
...
...
@@ -30,62 +30,15 @@ struct shared_authority {
shared_vector
<
types
::
KeyPermissionWeight
>
keys
;
};
/**
* @brief This class determines whether a set of signing keys are sufficient to satisfy an authority or not
*
* To determine whether an authority is satisfied or not, we first determine which keys have approved of a message, and
* then determine whether that list of keys is sufficient to satisfy the authority. This class takes a list of keys and
* provides the @ref satisfied method to determine whether that list of keys satisfies a provided authority.
*
* @tparam F A callable which takes a single argument of type @ref AccountPermission and returns the corresponding
* authority
*/
template
<
typename
F
>
class
AuthorityChecker
{
F
PermissionToAuthority
;
flat_set
<
public_key_type
>
signingKeys
;
public:
AuthorityChecker
(
F
PermissionToAuthority
,
const
flat_set
<
public_key_type
>&
signingKeys
)
:
PermissionToAuthority
(
PermissionToAuthority
),
signingKeys
(
signingKeys
)
{}
bool
satisfied
(
const
types
::
AccountPermission
&
permission
)
const
{
return
satisfied
(
PermissionToAuthority
(
permission
));
}
template
<
typename
AuthorityType
>
bool
satisfied
(
const
AuthorityType
&
authority
)
const
{
UInt32
weight
=
0
;
for
(
const
auto
&
kpw
:
authority
.
keys
)
{
if
(
signingKeys
.
count
(
kpw
.
key
))
{
weight
+=
kpw
.
weight
;
if
(
weight
>=
authority
.
threshold
)
return
true
;
}
}
for
(
const
auto
&
apw
:
authority
.
accounts
)
//#warning TODO: Recursion limit? Yes: implement as producer-configurable parameter
if
(
satisfied
(
apw
.
permission
))
{
weight
+=
apw
.
weight
;
if
(
weight
>=
authority
.
threshold
)
return
true
;
}
return
false
;
}
};
inline
bool
operator
<
(
const
types
::
AccountPermission
&
a
,
const
types
::
AccountPermission
&
b
)
{
return
std
::
tie
(
a
.
account
,
a
.
permission
)
<
std
::
tie
(
b
.
account
,
b
.
permission
);
}
template
<
typename
F
>
AuthorityChecker
<
F
>
MakeAuthorityChecker
(
F
&&
pta
,
const
flat_set
<
public_key_type
>&
signingKeys
)
{
return
AuthorityChecker
<
F
>
(
std
::
forward
<
F
>
(
pta
),
signingKeys
);
inline
bool
operator
<
(
const
types
::
AccountPermission
&
a
,
const
types
::
AccountPermission
&
b
)
{
return
std
::
tie
(
a
.
account
,
a
.
permission
)
<
std
::
tie
(
b
.
account
,
b
.
permission
);
}
/**
* Makes sure all keys are unique and sorted and all account permissions are unique and sorted and that authority can
* be satisfied
*/
inline
bool
validate
(
types
::
Authority
&
auth
)
{
inline
bool
validate
(
const
types
::
Authority
&
auth
)
{
const
types
::
KeyPermissionWeight
*
prev
=
nullptr
;
decltype
(
auth
.
threshold
)
totalWeight
=
0
;
...
...
libraries/chain/include/eos/chain/authority_checker.hpp
0 → 100644
浏览文件 @
81248dfe
#pragma once
#include <eos/chain/types.hpp>
#include <eos/types/generated.hpp>
#include <eos/utilities/parallel_markers.hpp>
#include <fc/scoped_exit.hpp>
#include <boost/range/algorithm/find.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>
namespace
eos
{
namespace
chain
{
namespace
detail
{
using
MetaPermission
=
static_variant
<
types
::
KeyPermissionWeight
,
types
::
AccountPermissionWeight
>
;
struct
GetWeightVisitor
{
using
result_type
=
UInt32
;
template
<
typename
Permission
>
UInt32
operator
()(
const
Permission
&
permission
)
{
return
permission
.
weight
;
}
};
// Orders permissions descending by weight, and breaks ties with Key permissions being less than Account permissions
struct
MetaPermissionComparator
{
bool
operator
()(
const
MetaPermission
&
a
,
const
MetaPermission
&
b
)
const
{
GetWeightVisitor
scale
;
if
(
a
.
visit
(
scale
)
>
b
.
visit
(
scale
))
return
true
;
return
a
.
contains
<
types
::
KeyPermissionWeight
>
()
&&
!
b
.
contains
<
types
::
KeyPermissionWeight
>
();
}
};
using
MetaPermissionSet
=
boost
::
container
::
flat_multiset
<
MetaPermission
,
MetaPermissionComparator
>
;
}
/**
* @brief This class determines whether a set of signing keys are sufficient to satisfy an authority or not
*
* To determine whether an authority is satisfied or not, we first determine which keys have approved of a message, and
* then determine whether that list of keys is sufficient to satisfy the authority. This class takes a list of keys and
* provides the @ref satisfied method to determine whether that list of keys satisfies a provided authority.
*
* @tparam F A callable which takes a single argument of type @ref AccountPermission and returns the corresponding
* authority
*/
template
<
typename
F
>
class
AuthorityChecker
{
F
PermissionToAuthority
;
vector
<
public_key_type
>
signingKeys
;
vector
<
bool
>
usedKeys
;
struct
WeightTallyVisitor
{
using
result_type
=
UInt32
;
AuthorityChecker
&
checker
;
UInt32
totalWeight
=
0
;
WeightTallyVisitor
(
AuthorityChecker
&
checker
)
:
checker
(
checker
)
{}
UInt32
operator
()(
const
types
::
KeyPermissionWeight
&
permission
)
{
auto
itr
=
boost
::
find
(
checker
.
signingKeys
,
permission
.
key
);
if
(
itr
!=
checker
.
signingKeys
.
end
())
{
checker
.
usedKeys
[
itr
-
checker
.
signingKeys
.
begin
()]
=
true
;
totalWeight
+=
permission
.
weight
;
}
return
totalWeight
;
}
UInt32
operator
()(
const
types
::
AccountPermissionWeight
&
permission
)
{
//TODO: Recursion limit? Yes: implement as producer-configurable parameter
if
(
checker
.
satisfied
(
permission
.
permission
))
totalWeight
+=
permission
.
weight
;
return
totalWeight
;
}
};
public:
AuthorityChecker
(
F
PermissionToAuthority
,
const
flat_set
<
public_key_type
>&
signingKeys
)
:
PermissionToAuthority
(
PermissionToAuthority
),
signingKeys
(
signingKeys
.
begin
(),
signingKeys
.
end
()),
usedKeys
(
signingKeys
.
size
(),
false
)
{}
bool
satisfied
(
const
types
::
AccountPermission
&
permission
)
{
return
satisfied
(
PermissionToAuthority
(
permission
));
}
template
<
typename
AuthorityType
>
bool
satisfied
(
const
AuthorityType
&
authority
)
{
// Save the current used keys; if we do not satisfy this authority, the newly used keys aren't actually used
auto
KeyReverter
=
fc
::
make_scoped_exit
([
this
,
keys
=
usedKeys
]
()
mutable
{
usedKeys
=
keys
;
});
// Sort key permissions and account permissions together into a single set of MetaPermissions
detail
::
MetaPermissionSet
permissions
;
permissions
.
insert
(
authority
.
keys
.
begin
(),
authority
.
keys
.
end
());
permissions
.
insert
(
authority
.
accounts
.
begin
(),
authority
.
accounts
.
end
());
// Check all permissions, from highest weight to lowest, seeing if signingKeys satisfies them or not
WeightTallyVisitor
visitor
(
*
this
);
for
(
const
auto
&
permission
:
permissions
)
// If we've got enough weight, to satisfy the authority, return!
if
(
permission
.
visit
(
visitor
)
>=
authority
.
threshold
)
{
KeyReverter
.
cancel
();
return
true
;
}
return
false
;
}
bool
all_keys_used
()
const
{
return
boost
::
algorithm
::
all_of_equal
(
usedKeys
,
true
);
}
flat_set
<
public_key_type
>
used_keys
()
const
{
auto
range
=
utilities
::
FilterDataByMarker
(
signingKeys
,
usedKeys
,
true
);
return
{
range
.
begin
(),
range
.
end
()};
}
flat_set
<
public_key_type
>
unused_keys
()
const
{
auto
range
=
utilities
::
FilterDataByMarker
(
signingKeys
,
usedKeys
,
false
);
return
{
range
.
begin
(),
range
.
end
()};
}
};
template
<
typename
F
>
AuthorityChecker
<
F
>
MakeAuthorityChecker
(
F
&&
pta
,
const
flat_set
<
public_key_type
>&
signingKeys
)
{
return
AuthorityChecker
<
F
>
(
std
::
forward
<
F
>
(
pta
),
signingKeys
);
}
}}
// namespace eos::chain
libraries/chain/message_handling_contexts.cpp
浏览文件 @
81248dfe
...
...
@@ -4,11 +4,10 @@
#include <eos/chain/key_value_object.hpp>
#include <eos/chain/chain_controller.hpp>
#include <eos/utilities/parallel_markers.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <boost/range/combine.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
namespace
eos
{
namespace
chain
{
...
...
@@ -48,15 +47,7 @@ bool apply_context::all_authorizations_used() const {
}
vector
<
types
::
AccountPermission
>
apply_context
::
unused_authorizations
()
const
{
auto
RemoveUsed
=
boost
::
adaptors
::
filtered
([](
const
auto
&
tuple
)
{
return
!
boost
::
get
<
0
>
(
tuple
);
});
auto
ToPermission
=
boost
::
adaptors
::
transformed
([](
const
auto
&
tuple
)
{
return
boost
::
get
<
1
>
(
tuple
);
});
// zip the parallel arrays, filter out the used authorizations, and return just the permissions that are left
auto
range
=
boost
::
combine
(
used_authorizations
,
msg
.
authorization
)
|
RemoveUsed
|
ToPermission
;
auto
range
=
utilities
::
FilterDataByMarker
(
msg
.
authorization
,
used_authorizations
,
false
);
return
{
range
.
begin
(),
range
.
end
()};
}
...
...
libraries/fc/include/fc/scoped_exit.hpp
浏览文件 @
81248dfe
...
...
@@ -9,12 +9,15 @@ namespace fc {
scoped_exit
(
C
&&
c
)
:
callback
(
std
::
forward
<
C
>
(
c
)
){}
scoped_exit
(
scoped_exit
&&
mv
)
:
callback
(
std
::
move
(
mv
.
callback
)
){}
void
cancel
()
{
canceled
=
true
;
}
~
scoped_exit
()
{
try
{
callback
();
}
catch
(
...
)
{}
if
(
!
canceled
)
try
{
callback
();
}
catch
(
...
)
{}
}
scoped_exit
&
operator
=
(
scoped_exit
&&
mv
)
{
callback
=
std
::
move
(
mv
);
callback
=
std
::
move
(
mv
.
callback
);
return
*
this
;
}
private:
...
...
@@ -22,6 +25,7 @@ namespace fc {
scoped_exit
&
operator
=
(
const
scoped_exit
&
);
Callback
callback
;
bool
canceled
=
false
;
};
template
<
typename
Callback
>
...
...
libraries/types/include/eos/types/native.hpp
浏览文件 @
81248dfe
...
...
@@ -105,11 +105,10 @@ namespace eos { namespace types {
const
auto
len
=
strnlen
(
str
,
14
);
FC_ASSERT
(
len
<=
13
);
value
=
string_to_name
(
str
);
FC_ASSERT
(
toString
()
==
String
(
str
),
"name not properly normalized"
,
(
"name"
,
String
(
str
))(
"normalized"
,
toString
())
);
}
FC_CAPTURE_AND_RETHROW
(
(
str
)
)
}
Name
(
uint64_t
v
=
0
)
:
value
(
v
){
// FC_ASSERT( !(v>>(5*12)), "invalid name id" );
}
Name
(
uint64_t
v
=
0
)
:
value
(
v
){}
explicit
operator
String
()
const
{
static
const
char
*
charmap
=
".abcdefghijklmnopqrstuvwxyz12345"
;
...
...
libraries/utilities/include/eos/utilities/parallel_markers.hpp
0 → 100644
浏览文件 @
81248dfe
#pragma once
#include <boost/range/combine.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
namespace
eos
{
namespace
utilities
{
/**
* @brief Return values in DataRange corresponding to matching Markers
*
* Takes two parallel ranges, a Data range containing data values, and a Marker range containing markers on the
* corresponding data values. Returns a new Data range containing only the values corresponding to markers which match
* markerValue
*
* For example:
* @code{.cpp}
* vector<char> data = {'A', 'B', 'C'};
* vector<bool> markers = {true, false, true};
* auto markedData = FilterDataByMarker(data, markers, true);
* // markedData contains {'A', 'C'}
* @endcode
*/
template
<
typename
DataRange
,
typename
MarkerRange
,
typename
Marker
>
DataRange
FilterDataByMarker
(
DataRange
data
,
MarkerRange
markers
,
const
Marker
&
markerValue
)
{
auto
RemoveMismatchedMarkers
=
boost
::
adaptors
::
filtered
([
&
markerValue
](
const
auto
&
tuple
)
{
return
boost
::
get
<
0
>
(
tuple
)
==
markerValue
;
});
auto
ToData
=
boost
::
adaptors
::
transformed
([](
const
auto
&
tuple
)
{
return
boost
::
get
<
1
>
(
tuple
);
});
// Zip the ranges together, filter out data with markers that don't match, and return the data without the markers
auto
range
=
boost
::
combine
(
markers
,
data
)
|
RemoveMismatchedMarkers
|
ToData
;
return
{
range
.
begin
(),
range
.
end
()};
}
}}
// namespace eos::utilities
tests/common/database_fixture.cpp
浏览文件 @
81248dfe
...
...
@@ -27,6 +27,7 @@
#include <eos/chain/account_object.hpp>
#include <eos/chain/producer_object.hpp>
#include <eos/chain/authority_checker.hpp>
#include <eos/utilities/tempdir.hpp>
...
...
@@ -37,6 +38,8 @@
#include <fc/crypto/digest.hpp>
#include <fc/smart_ref_impl.hpp>
#include <boost/range/adaptor/map.hpp>
#include <iostream>
#include <iomanip>
#include <sstream>
...
...
@@ -94,9 +97,15 @@ private_key_type testing_fixture::get_private_key(const public_key_type& public_
return
itr
->
second
;
}
flat_set
<
public_key_type
>
testing_fixture
::
available_keys
()
const
{
auto
range
=
key_ring
|
boost
::
adaptors
::
map_keys
;
return
{
range
.
begin
(),
range
.
end
()};
}
testing_blockchain
::
testing_blockchain
(
chainbase
::
database
&
db
,
fork_database
&
fork_db
,
block_log
&
blocklog
,
chain_initializer_interface
&
initializer
,
testing_fixture
&
fixture
)
:
chain_controller
(
db
,
fork_db
,
blocklog
,
initializer
,
native_contract
::
make_administrator
()),
db
(
db
),
fixture
(
fixture
)
{}
void
testing_blockchain
::
produce_blocks
(
uint32_t
count
,
uint32_t
blocks_to_miss
)
{
...
...
@@ -157,6 +166,34 @@ types::PublicKey testing_blockchain::get_block_signing_key(const types::AccountN
return
get_database
().
get
<
producer_object
,
by_owner
>
(
producerName
).
signing_key
;
}
void
testing_blockchain
::
sign_transaction
(
SignedTransaction
&
trx
)
{
auto
GetAuthority
=
[
this
](
const
types
::
AccountPermission
&
permission
)
{
auto
key
=
boost
::
make_tuple
(
permission
.
account
,
permission
.
permission
);
return
db
.
get
<
permission_object
,
by_owner
>
(
key
).
auth
;
};
auto
checker
=
MakeAuthorityChecker
(
GetAuthority
,
fixture
.
available_keys
());
for
(
const
auto
&
message
:
trx
.
messages
)
for
(
const
auto
&
authorization
:
message
.
authorization
)
if
(
!
checker
.
satisfied
(
authorization
))
elog
(
"Attempting to automatically sign transaction, but testing_fixture doesn't have the keys!"
);
for
(
const
auto
&
key
:
checker
.
used_keys
())
// TODO: Use a real chain_id here
trx
.
sign
(
fixture
.
get_private_key
(
key
),
chain_id_type
{});
}
ProcessedTransaction
testing_blockchain
::
push_transaction
(
SignedTransaction
trx
,
uint32_t
skip_flags
)
{
if
(
skip_trx_sigs
)
skip_flags
|=
chain_controller
::
skip_transaction_signatures
;
if
(
auto_sign_trxs
)
{
sign_transaction
(
trx
);
}
return
chain_controller
::
push_transaction
(
trx
,
skip_flags
);
}
void
testing_network
::
connect_blockchain
(
testing_blockchain
&
new_database
)
{
if
(
blockchains
.
count
(
&
new_database
))
return
;
...
...
tests/common/database_fixture.hpp
浏览文件 @
81248dfe
...
...
@@ -119,6 +119,7 @@ public:
void
store_private_key
(
const
private_key_type
&
key
);
private_key_type
get_private_key
(
const
public_key_type
&
public_key
)
const
;
flat_set
<
public_key_type
>
available_keys
()
const
;
protected:
std
::
vector
<
fc
::
temp_directory
>
anonymous_temp_dirs
;
...
...
@@ -178,8 +179,27 @@ public:
/// @brief Get the specified block producer's signing key
PublicKey
get_block_signing_key
(
const
AccountName
&
producerName
);
/// @brief Attempt to sign the provided transaction using the keys available to the testing_fixture
void
sign_transaction
(
SignedTransaction
&
trx
);
/// @brief Override push_transaction to apply testing policies
ProcessedTransaction
push_transaction
(
SignedTransaction
trx
,
uint32_t
skip_flags
=
0
);
/// @brief Set whether testing_blockchain::push_transaction checks signatures by default
/// @param skip_sigs If true, push_transaction will skip signature checks; otherwise, no changes will be made
void
set_skip_transaction_signature_checking
(
bool
skip_sigs
)
{
skip_trx_sigs
=
skip_sigs
;
}
/// @brief Set whether testing_blockchain::push_transaction attempts to sign transactions or not
void
set_auto_sign_transactions
(
bool
auto_sign
)
{
auto_sign_trxs
=
auto_sign
;
}
protected:
chainbase
::
database
&
db
;
testing_fixture
&
fixture
;
bool
skip_trx_sigs
=
true
;
bool
auto_sign_trxs
=
false
;
};
using
boost
::
signals2
::
scoped_connection
;
...
...
tests/common/macro_support.hpp
浏览文件 @
81248dfe
...
...
@@ -51,7 +51,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"newaccount", types::newaccount{#creator, #name, owner, active, recovery, deposit}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Created account " << #name); \
}
#define MKACCT2(chain, name) \
...
...
@@ -83,7 +83,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"updateauth", types::updateauth{#account, authname, parentname, auth}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Set " << #account << "'s " << authname << " authority."); \
}
...
...
@@ -96,7 +96,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"deleteauth", types::deleteauth{#account, authname}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Deleted " << #account << "'s " << authname << " authority."); \
}
...
...
@@ -109,7 +109,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"linkauth", types::linkauth{#account, #codeacct, messagetype, authname}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Link " << #codeacct << "::" << messagetype << " to " << #account \
<< "'s " << authname << " authority."); \
}
...
...
@@ -124,7 +124,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"unlinkauth", types::unlinkauth{#account, #codeacct, messagetype}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Unlink " << #codeacct << "::" << messagetype << " from " << #account); \
}
#define LINKAUTH3(chain, account, codeacct) LINKAUTH5(chain, account, codeacct, "")
...
...
@@ -138,7 +138,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"transfer", types::transfer{#sender, #recipient, Amount.amount}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Transfered " << Amount << " from " << #sender << " to " << #recipient); \
}
#define XFER4(chain, sender, recipient, amount) XFER5(chain, sender, recipient, amount, "")
...
...
@@ -151,7 +151,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"lock", types::lock{#sender, #recipient, amount}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Staked " << amount << " to " << #recipient); \
}
#define STAKE3(chain, account, amount) STAKE4(chain, account, account, amount)
...
...
@@ -165,7 +165,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"unlock", types::unlock{#account, amount}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Begin unstake " << amount << " to " << #account); \
}
...
...
@@ -177,7 +177,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"claim", types::claim{#account, amount}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Finish unstake " << amount << " to " << #account); \
}
...
...
@@ -190,7 +190,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"setproducer", types::setproducer{#owner, key, cfg}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Create producer " << #owner); \
}
#define MKPDCR3(chain, owner, key) MKPDCR4(chain, owner, key, BlockchainConfiguration{});
...
...
@@ -207,7 +207,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"okproducer", types::okproducer{#voter, #producer, approved? 1 : 0}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Set producer approval from " << #voter << " for " << #producer << " to " << approved); \
}
...
...
@@ -220,7 +220,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"setproducer", types::setproducer{owner, key, cfg}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx
, chain_controller::skip_transaction_signatures
); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Update producer " << owner); \
}
#define UPPDCR3(chain, owner, key) UPPDCR4(chain, owner, key, chain.get_producer(owner).configuration)
tests/tests/misc_tests.cpp
浏览文件 @
81248dfe
#include <eos/chain/BlockchainConfiguration.hpp>
#include <eos/chain/authority.hpp>
#include <eos/chain/authority
_checker
.hpp>
#include <eos/utilities/key_conversion.hpp>
#include <eos/utilities/rand.hpp>
...
...
@@ -88,13 +88,39 @@ BOOST_AUTO_TEST_CASE(authority_checker)
Make_Key
(
c
);
auto
&
c
=
c_public_key
;
auto
GetNullAuthority
=
[](
auto
){
return
Authority
();};
auto
GetNullAuthority
=
[](
auto
){
abort
();
return
Authority
();};
auto
A
=
Complex_Authority
(
2
,
((
a
,
1
))((
b
,
1
)),);
BOOST_CHECK
(
MakeAuthorityChecker
(
GetNullAuthority
,
{
a
,
b
}).
satisfied
(
A
));
BOOST_CHECK
(
MakeAuthorityChecker
(
GetNullAuthority
,
{
a
,
b
,
c
}).
satisfied
(
A
));
BOOST_CHECK
(
!
MakeAuthorityChecker
(
GetNullAuthority
,
{
a
,
c
}).
satisfied
(
A
));
BOOST_CHECK
(
!
MakeAuthorityChecker
(
GetNullAuthority
,
{
b
,
c
}).
satisfied
(
A
));
{
auto
checker
=
MakeAuthorityChecker
(
GetNullAuthority
,
{
a
,
b
});
BOOST_CHECK
(
checker
.
satisfied
(
A
));
BOOST_CHECK
(
checker
.
all_keys_used
());
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
2
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
0
);
}
{
auto
checker
=
MakeAuthorityChecker
(
GetNullAuthority
,
{
a
,
c
});
BOOST_CHECK
(
!
checker
.
satisfied
(
A
));
BOOST_CHECK
(
!
checker
.
all_keys_used
());
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
0
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
2
);
}
{
auto
checker
=
MakeAuthorityChecker
(
GetNullAuthority
,
{
a
,
b
,
c
});
BOOST_CHECK
(
checker
.
satisfied
(
A
));
BOOST_CHECK
(
!
checker
.
all_keys_used
());
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
2
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
a
),
1
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
b
),
1
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
1
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
count
(
c
),
1
);
}
{
auto
checker
=
MakeAuthorityChecker
(
GetNullAuthority
,
{
b
,
c
});
BOOST_CHECK
(
!
checker
.
satisfied
(
A
));
BOOST_CHECK
(
!
checker
.
all_keys_used
());
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
0
);
}
A
=
Complex_Authority
(
3
,
((
a
,
1
))((
b
,
1
))((
c
,
1
)),);
BOOST_CHECK
(
MakeAuthorityChecker
(
GetNullAuthority
,
{
c
,
b
,
a
}).
satisfied
(
A
));
...
...
@@ -115,10 +141,44 @@ BOOST_AUTO_TEST_CASE(authority_checker)
auto
GetCAuthority
=
[
c_public_key
](
auto
){
return
Complex_Authority
(
1
,
((
c
,
1
)),);};
A
=
Complex_Authority
(
2
,
((
a
,
2
))((
b
,
1
)),
((
"hello"
,
"world"
,
1
)));
BOOST_CHECK
(
MakeAuthorityChecker
(
GetCAuthority
,
{
a
}).
satisfied
(
A
));
BOOST_CHECK
(
!
MakeAuthorityChecker
(
GetCAuthority
,
{
b
}).
satisfied
(
A
));
BOOST_CHECK
(
!
MakeAuthorityChecker
(
GetCAuthority
,
{
c
}).
satisfied
(
A
));
BOOST_CHECK
(
MakeAuthorityChecker
(
GetCAuthority
,
{
b
,
c
}).
satisfied
(
A
));
{
auto
checker
=
MakeAuthorityChecker
(
GetCAuthority
,
{
a
});
BOOST_CHECK
(
checker
.
satisfied
(
A
));
BOOST_CHECK
(
checker
.
all_keys_used
());
}
{
auto
checker
=
MakeAuthorityChecker
(
GetCAuthority
,
{
b
});
BOOST_CHECK
(
!
checker
.
satisfied
(
A
));
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
0
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
1
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
count
(
b
),
1
);
}
{
auto
checker
=
MakeAuthorityChecker
(
GetCAuthority
,
{
c
});
BOOST_CHECK
(
!
checker
.
satisfied
(
A
));
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
0
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
1
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
count
(
c
),
1
);
}
{
auto
checker
=
MakeAuthorityChecker
(
GetCAuthority
,
{
b
,
c
});
BOOST_CHECK
(
checker
.
satisfied
(
A
));
BOOST_CHECK
(
checker
.
all_keys_used
());
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
2
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
0
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
b
),
1
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
c
),
1
);
}
{
auto
checker
=
MakeAuthorityChecker
(
GetCAuthority
,
{
b
,
c
,
a
});
BOOST_CHECK
(
checker
.
satisfied
(
A
));
BOOST_CHECK
(
!
checker
.
all_keys_used
());
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
1
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
a
),
1
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
2
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
count
(
b
),
1
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
count
(
c
),
1
);
}
A
=
Complex_Authority
(
2
,
((
a
,
1
))((
b
,
1
)),
((
"hello"
,
"world"
,
1
)));
BOOST_CHECK
(
!
MakeAuthorityChecker
(
GetCAuthority
,
{
a
}).
satisfied
(
A
));
...
...
@@ -127,12 +187,60 @@ BOOST_AUTO_TEST_CASE(authority_checker)
BOOST_CHECK
(
MakeAuthorityChecker
(
GetCAuthority
,
{
a
,
b
}).
satisfied
(
A
));
BOOST_CHECK
(
MakeAuthorityChecker
(
GetCAuthority
,
{
b
,
c
}).
satisfied
(
A
));
BOOST_CHECK
(
MakeAuthorityChecker
(
GetCAuthority
,
{
a
,
c
}).
satisfied
(
A
));
{
auto
checker
=
MakeAuthorityChecker
(
GetCAuthority
,
{
a
,
b
,
c
});
BOOST_CHECK
(
checker
.
satisfied
(
A
));
BOOST_CHECK
(
!
checker
.
all_keys_used
());
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
2
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
1
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
count
(
c
),
1
);
}
A
=
Complex_Authority
(
2
,
((
a
,
1
))((
b
,
1
)),
((
"hello"
,
"world"
,
2
)));
BOOST_CHECK
(
MakeAuthorityChecker
(
GetCAuthority
,
{
a
,
b
}).
satisfied
(
A
));
BOOST_CHECK
(
MakeAuthorityChecker
(
GetCAuthority
,
{
c
}).
satisfied
(
A
));
BOOST_CHECK
(
!
MakeAuthorityChecker
(
GetCAuthority
,
{
a
}).
satisfied
(
A
));
BOOST_CHECK
(
!
MakeAuthorityChecker
(
GetCAuthority
,
{
b
}).
satisfied
(
A
));
{
auto
checker
=
MakeAuthorityChecker
(
GetCAuthority
,
{
a
,
b
,
c
});
BOOST_CHECK
(
checker
.
satisfied
(
A
));
BOOST_CHECK
(
!
checker
.
all_keys_used
());
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
1
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
2
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
c
),
1
);
}
Make_Key
(
d
);
auto
&
d
=
d_public_key
;
Make_Key
(
e
);
auto
&
e
=
e_public_key
;
auto
GetAuthority
=
[
d_public_key
,
e
]
(
const
types
::
AccountPermission
&
perm
)
{
if
(
perm
.
account
==
"top"
)
return
Complex_Authority
(
2
,
((
d
,
1
)),
((
"bottom"
,
"bottom"
,
1
)));
return
Key_Authority
(
e
);
};
A
=
Complex_Authority
(
5
,
((
a
,
2
))((
b
,
2
))((
c
,
2
)),
((
"top"
,
"top"
,
5
)));
{
auto
checker
=
MakeAuthorityChecker
(
GetAuthority
,
{
a
,
b
,
c
,
d
,
e
});
BOOST_CHECK
(
checker
.
satisfied
(
A
));
BOOST_CHECK
(
!
checker
.
all_keys_used
());
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
2
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
3
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
d
),
1
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
e
),
1
);
}
{
auto
checker
=
MakeAuthorityChecker
(
GetAuthority
,
{
a
,
b
,
c
,
e
});
BOOST_CHECK
(
checker
.
satisfied
(
A
));
BOOST_CHECK
(
!
checker
.
all_keys_used
());
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
size
(),
3
);
BOOST_CHECK_EQUAL
(
checker
.
unused_keys
().
size
(),
1
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
a
),
1
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
b
),
1
);
BOOST_CHECK_EQUAL
(
checker
.
used_keys
().
count
(
c
),
1
);
}
}
FC_LOG_AND_RETHROW
()
}
/// Test creating the wallet
...
...
tests/tests/native_contract_tests.cpp
浏览文件 @
81248dfe
...
...
@@ -5,6 +5,7 @@
#include <eos/chain/permission_object.hpp>
#include <eos/chain/permission_link_object.hpp>
#include <eos/chain/key_value_object.hpp>
#include <eos/chain/authority_checker.hpp>
#include <eos/native_contract/producer_objects.hpp>
...
...
@@ -33,6 +34,7 @@ BOOST_FIXTURE_TEST_CASE(create_account, testing_fixture)
BOOST_CHECK_EQUAL
(
chain
.
get_liquid_balance
(
"inita"
),
Asset
(
100000
));
Make_Account
(
chain
,
joe
,
inita
,
Asset
(
1000
));
chain
.
produce_blocks
();
Transfer_Asset
(
chain
,
inita
,
joe
,
Asset
(
1000
));
{
// test in the pending state
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录