Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
898947fc
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,发现更多精彩内容 >>
提交
898947fc
编写于
7月 06, 2017
作者:
D
Daniel Larimer
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of github.com:EOSIO/eos
上级
5c4f1e9e
17528b21
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
204 addition
and
153 deletion
+204
-153
libraries/chain/CMakeLists.txt
libraries/chain/CMakeLists.txt
+1
-0
libraries/chain/chain_controller.cpp
libraries/chain/chain_controller.cpp
+30
-34
libraries/chain/include/eos/chain/authority.hpp
libraries/chain/include/eos/chain/authority.hpp
+1
-1
libraries/chain/include/eos/chain/message.hpp
libraries/chain/include/eos/chain/message.hpp
+14
-11
libraries/chain/include/eos/chain/message_handling_contexts.hpp
...ies/chain/include/eos/chain/message_handling_contexts.hpp
+17
-3
libraries/chain/message_handling_contexts.cpp
libraries/chain/message_handling_contexts.cpp
+24
-0
libraries/chain/wasm_interface.cpp
libraries/chain/wasm_interface.cpp
+27
-27
libraries/native_contract/include/eos/native_contract/staked_balance_contract.hpp
...t/include/eos/native_contract/staked_balance_contract.hpp
+1
-1
libraries/native_contract/native_contract_chain_initializer.cpp
...ies/native_contract/native_contract_chain_initializer.cpp
+11
-8
libraries/native_contract/staked_balance_contract.cpp
libraries/native_contract/staked_balance_contract.cpp
+35
-29
libraries/types/types.eos
libraries/types/types.eos
+6
-6
tests/common/database_fixture.hpp
tests/common/database_fixture.hpp
+6
-5
tests/common/macro_support.hpp
tests/common/macro_support.hpp
+24
-19
tests/slow_tests/slow_tests.cpp
tests/slow_tests/slow_tests.cpp
+5
-6
tests/tests/native_contract_tests.cpp
tests/tests/native_contract_tests.cpp
+2
-3
未找到文件。
libraries/chain/CMakeLists.txt
浏览文件 @
898947fc
...
...
@@ -17,6 +17,7 @@ add_library( eos_chain
types.cpp
chain_administration_interface.cpp
message_handling_contexts.cpp
${
HEADERS
}
)
...
...
libraries/chain/chain_controller.cpp
浏览文件 @
898947fc
...
...
@@ -552,21 +552,18 @@ void chain_controller::validate_referenced_accounts(const SignedTransaction& trx
require_account
(
auth
.
account
);
}
for
(
const
auto
&
msg
:
trx
.
messages
)
{
require_account
(
msg
.
sender
);
require_account
(
msg
.
recipient
);
const
AccountName
*
previous_notify_account
=
nullptr
;
for
(
const
auto
&
current_notify_account
:
msg
.
notify
)
{
require_account
(
current_notify_account
);
if
(
previous_notify_account
)
{
EOS_ASSERT
(
current_notify_account
<
*
previous_notify_account
,
message_validate_exception
,
require_account
(
msg
.
code
);
const
AccountName
*
previous_recipient
=
nullptr
;
for
(
const
auto
&
current_recipient
:
msg
.
recipients
)
{
require_account
(
current_recipient
);
if
(
previous_recipient
)
{
EOS_ASSERT
(
current_recipient
<
*
previous_recipient
,
message_validate_exception
,
"Message notify accounts out of order. Possibly a bug in the wallet?"
);
}
EOS_ASSERT
(
current_notify_account
!=
msg
.
sender
,
message_validate_exception
,
"Message sender is listed in accounts to notify. Possibly a bug in the wallet?"
);
EOS_ASSERT
(
current_notify_account
!=
msg
.
recipient
,
message_validate_exception
,
"Message recipient is listed in accounts to notify. Possibly a bug in the wallet?"
);
previous_notify_account
=
&
current_notify_account
;
EOS_ASSERT
(
current_recipient
!=
msg
.
code
,
message_validate_exception
,
"Code account is listed among recipients. Possibly a bug in the wallet?"
);
previous_recipient
=
&
current_recipient
;
}
}
}
...
...
@@ -588,22 +585,22 @@ void chain_controller::validate_expiration(const SignedTransaction& trx) const
void
chain_controller
::
validate_message_precondition
(
precondition_validate_context
&
context
)
const
{
try
{
const
auto
&
m
=
context
.
msg
;
auto
contract_handlers_itr
=
precondition_validate_handlers
.
find
(
context
.
scope
);
if
(
contract_handlers_itr
!=
precondition_validate_handlers
.
end
()
)
{
auto
message_handler_itr
=
contract_handlers_itr
->
second
.
find
(
{
m
.
recipient
,
m
.
type
}
);
if
(
message_handler_itr
!=
contract_handlers_itr
->
second
.
end
()
)
{
auto
contract_handlers_itr
=
precondition_validate_handlers
.
find
(
context
.
scope
);
if
(
contract_handlers_itr
!=
precondition_validate_handlers
.
end
()
)
{
auto
message_handler_itr
=
contract_handlers_itr
->
second
.
find
(
{
m
.
code
,
m
.
type
}
);
if
(
message_handler_itr
!=
contract_handlers_itr
->
second
.
end
()
)
{
message_handler_itr
->
second
(
context
);
return
;
}
}
const
auto
&
recipient
=
_db
.
get
<
account_object
,
by_name
>
(
context
.
scope
);
if
(
recipient
.
code
.
size
()
)
{
wasm_interface
::
get
().
precondition
(
context
);
const
auto
&
recipient
=
_db
.
get
<
account_object
,
by_name
>
(
context
.
scope
);
if
(
recipient
.
code
.
size
()
)
{
wasm_interface
::
get
().
precondition
(
context
);
}
}
FC_CAPTURE_AND_RETHROW
()
}
void
chain_controller
::
process_message
(
Message
message
)
{
apply_context
apply_ctx
(
_db
,
message
,
message
.
recipient
);
apply_context
apply_ctx
(
_db
,
message
,
message
.
code
);
/** TODO: pre condition validation and application can occur in parallel */
/** TODO: verify that message is fully authorized
...
...
@@ -611,30 +608,29 @@ void chain_controller::process_message(Message message) {
validate_message_precondition
(
apply_ctx
);
apply_message
(
apply_ctx
);
for
(
const
auto
&
notify_account
:
message
.
notify
)
{
for
(
const
auto
&
recipient
:
message
.
recipients
)
{
try
{
apply_context
notify_ctx
(
_db
,
message
,
notify_accou
nt
);
validate_message_precondition
(
notify
_ctx
);
apply_message
(
notify
_ctx
);
}
FC_CAPTURE_AND_RETHROW
((
notify_accou
nt
)(
message
))
apply_context
recipient_ctx
(
_db
,
message
,
recipie
nt
);
validate_message_precondition
(
recipient
_ctx
);
apply_message
(
recipient
_ctx
);
}
FC_CAPTURE_AND_RETHROW
((
recipie
nt
)(
message
))
}
}
void
chain_controller
::
apply_message
(
apply_context
&
context
)
void
chain_controller
::
apply_message
(
apply_context
&
context
)
{
try
{
const
auto
&
m
=
context
.
msg
;
auto
contract_handlers_itr
=
apply_handlers
.
find
(
context
.
scope
);
if
(
contract_handlers_itr
!=
apply_handlers
.
end
()
)
{
auto
message_handler_itr
=
contract_handlers_itr
->
second
.
find
(
{
m
.
recipient
,
m
.
type
}
);
if
(
message_handler_itr
!=
contract_handlers_itr
->
second
.
end
()
)
{
auto
contract_handlers_itr
=
apply_handlers
.
find
(
context
.
scope
);
if
(
contract_handlers_itr
!=
apply_handlers
.
end
()
)
{
auto
message_handler_itr
=
contract_handlers_itr
->
second
.
find
(
{
m
.
code
,
m
.
type
}
);
if
(
message_handler_itr
!=
contract_handlers_itr
->
second
.
end
()
)
{
message_handler_itr
->
second
(
context
);
return
;
}
}
//ilog( "no native handler found" );
const
auto
&
recipient
=
_db
.
get
<
account_object
,
by_name
>
(
context
.
scope
);
if
(
recipient
.
code
.
size
()
)
{
wasm_interface
::
get
().
apply
(
context
);
const
auto
&
recipient
=
_db
.
get
<
account_object
,
by_name
>
(
context
.
scope
);
if
(
recipient
.
code
.
size
())
{
wasm_interface
::
get
().
apply
(
context
);
}
}
FC_CAPTURE_AND_RETHROW
((
context
.
msg
))
}
...
...
libraries/chain/include/eos/chain/authority.hpp
浏览文件 @
898947fc
...
...
@@ -62,7 +62,7 @@ public:
return
true
;
}
for
(
const
auto
&
apw
:
authority
.
accounts
)
#warning TODO: Recursion limit?
#warning TODO: Recursion limit?
Yes: implement as producer-configurable parameter
if
(
satisfied
(
apw
.
permission
))
{
weight
+=
apw
.
weight
;
if
(
weight
>=
authority
.
threshold
)
...
...
libraries/chain/include/eos/chain/message.hpp
浏览文件 @
898947fc
...
...
@@ -20,12 +20,10 @@ namespace eos { namespace chain {
*/
struct
Message
:
public
types
::
Message
{
Message
()
=
default
;
Message
(
const
AccountName
&
sender
,
const
AccountName
&
recipient
,
const
vector
<
AccountName
>&
notify
)
:
types
::
Message
(
sender
,
recipient
,
notify
,
""
,
{})
{}
template
<
typename
T
>
Message
(
const
AccountName
&
sender
,
const
AccountName
&
recipient
,
const
vector
<
AccountName
>&
notify
,
const
TypeName
&
type
,
T
&&
value
)
:
Message
(
sender
,
recipient
,
notify
)
{
Message
(
const
AccountName
&
code
,
const
vector
<
types
::
AccountName
>&
recipients
,
const
vector
<
types
::
AccountPermission
>&
authorization
,
const
TypeName
&
type
,
T
&&
value
)
:
types
::
Message
(
code
,
recipients
,
authorization
,
{},
{}
)
{
set
<
T
>
(
type
,
std
::
forward
<
T
>
(
value
));
}
Message
(
const
types
::
Message
&
m
)
:
types
::
Message
(
m
)
{}
...
...
@@ -40,17 +38,22 @@ struct Message : public types::Message {
return
fc
::
raw
::
unpack
<
T
>
(
data
);
}
bool
has_notify
(
const
AccountName
&
n
)
const
{
for
(
const
auto
&
no
:
notify
)
for
(
const
auto
&
no
:
recipients
)
if
(
no
==
n
)
return
true
;
return
false
;
}
template
<
typename
Lambda
>
void
for_each_handler
(
Lambda
&&
l
)
const
{
l
(
sender
);
l
(
recipient
);
for
(
const
auto
&
notice
:
notify
)
l
(
notice
);
void
for_each_handler
(
Lambda
&&
l
)
const
{
l
(
code
);
for
(
const
auto
&
recipient
:
recipients
)
l
(
recipient
);
}
types
::
AccountName
recipient
(
UInt8
index
)
const
{
FC_ASSERT
(
index
<
recipients
.
size
(),
"Invalid recipient index: ${index}/${size}"
,
(
"index"
,
index
)(
"size"
,
recipients
.
size
()));
return
recipients
.
at
(
int
(
index
));
}
};
...
...
libraries/chain/include/eos/chain/message_handling_contexts.hpp
浏览文件 @
898947fc
...
...
@@ -11,11 +11,25 @@ namespace eos { namespace chain {
class
message_validate_context
{
public:
explicit
message_validate_context
(
const
chainbase
::
database
&
d
,
const
chain
::
Message
&
m
,
types
::
AccountName
s
)
:
msg
(
m
),
db
(
d
),
scope
(
s
){}
:
msg
(
m
),
db
(
d
),
scope
(
s
),
used_authorizations
(
msg
.
authorization
.
size
(),
false
){}
/**
* @brief Require @ref account to have approved of this message
* @param account The account whose approval is required
*
* This method will check that @ref account is listed in the message's declared authorizations, and marks the
* authorization as used. Note that all authorizations on a message must be used, or the message is invalid.
*
* @throws tx_missing_auth If no sufficient permission was found
*/
void
require_authorization
(
const
types
::
AccountName
&
account
);
bool
all_authorizations_used
()
const
;
const
chain
::
Message
&
msg
;
const
chainbase
::
database
&
db
;
/// required only for loading the contract code
types
::
AccountName
scope
;
/// the contract that is being called
const
chainbase
::
database
&
db
;
types
::
AccountName
scope
;
///< Parallel to msg.authorization; tracks which permissions have been used while processing the message
vector
<
bool
>
used_authorizations
;
};
class
precondition_validate_context
:
public
message_validate_context
{
...
...
libraries/chain/message_handling_contexts.cpp
0 → 100644
浏览文件 @
898947fc
#include <eos/chain/message_handling_contexts.hpp>
#include <eos/chain/permission_object.hpp>
#include <eos/chain/exceptions.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>
#include <boost/range/algorithm/find_if.hpp>
namespace
eos
{
namespace
chain
{
void
message_validate_context
::
require_authorization
(
const
types
::
AccountName
&
account
)
{
auto
itr
=
boost
::
find_if
(
msg
.
authorization
,
[
&
account
](
const
types
::
AccountPermission
&
ap
)
{
return
ap
.
account
==
account
;
});
EOS_ASSERT
(
itr
!=
msg
.
authorization
.
end
(),
tx_missing_auth
,
"Required authorization ${auth} not found"
,
(
"auth"
,
account
));
used_authorizations
[
itr
-
msg
.
authorization
.
begin
()]
=
true
;
}
bool
message_validate_context
::
all_authorizations_used
()
const
{
return
boost
::
algorithm
::
all_of_equal
(
used_authorizations
,
true
);
}
}
}
// namespace eos::chain
libraries/chain/wasm_interface.cpp
浏览文件 @
898947fc
...
...
@@ -71,7 +71,7 @@ DEFINE_INTRINSIC_FUNCTION2(env,remove,remove,i32,i32,keyptr,i32,keylen) {
const
auto
*
obj
=
db
.
find
<
key_value_object
,
by_scope_key
>
(
boost
::
make_tuple
(
scope
,
keystr
)
);
if
(
obj
)
{
db
.
remove
(
*
obj
);
db
.
remove
(
*
obj
);
return
true
;
}
return
false
;
...
...
@@ -88,9 +88,9 @@ DEFINE_INTRINSIC_FUNCTION3(env,memcpy,memcpy,i32,i32,dstp,i32,srcp,i32,len) {
#warning TODO: wasm memcpy has undefined behavior if memory ranges overlap
/*
if( dst > src )
FC_ASSERT( dst < src_end && src < dst_end, "overlap of memory range is undefined", ("d",dstp)("s",srcp)("l",len) );
FC_ASSERT( dst < src_end && src < dst_end, "overlap of memory range is undefined", ("d",dstp)("s",srcp)("l",len) );
else
FC_ASSERT( src < dst_end && dst < src_end, "overlap of memory range is undefined", ("d",dstp)("s",srcp)("l",len) );
FC_ASSERT( src < dst_end && dst < src_end, "overlap of memory range is undefined", ("d",dstp)("s",srcp)("l",len) );
*/
memcpy
(
dst
,
src
,
uint32_t
(
len
)
);
return
dstp
;
...
...
@@ -254,7 +254,7 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
if
(
!
wasm
)
{
wlog
(
"Runtime::init"
);
Runtime
::
init
();
Runtime
::
init
();
wasm
=
new
wasm_interface
();
}
return
*
wasm
;
...
...
@@ -277,10 +277,10 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
char
*
wasm_interface
::
vm_allocate
(
int
bytes
)
{
FunctionInstance
*
alloc_function
=
asFunctionNullable
(
getInstanceExport
(
current_module
,
"alloc"
));
const
FunctionType
*
functionType
=
getFunctionType
(
alloc_function
);
FunctionInstance
*
alloc_function
=
asFunctionNullable
(
getInstanceExport
(
current_module
,
"alloc"
));
const
FunctionType
*
functionType
=
getFunctionType
(
alloc_function
);
FC_ASSERT
(
functionType
->
parameters
.
size
()
==
1
);
std
::
vector
<
Value
>
invokeArgs
(
1
);
std
::
vector
<
Value
>
invokeArgs
(
1
);
invokeArgs
[
0
]
=
U32
(
bytes
);
auto
result
=
Runtime
::
invokeFunction
(
alloc_function
,
invokeArgs
);
...
...
@@ -295,28 +295,28 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
void
wasm_interface
::
vm_call
(
std
::
string
name
)
{
try
{
try
{
name
+=
"_"
+
std
::
string
(
current_validate_context
->
msg
.
recipient
)
+
"_"
;
name
+=
"_"
+
std
::
string
(
current_validate_context
->
msg
.
code
)
+
"_"
;
name
+=
std
::
string
(
current_validate_context
->
msg
.
type
);
FunctionInstance
*
apply
=
asFunctionNullable
(
getInstanceExport
(
current_module
,
name
.
c_str
()));
if
(
!
apply
)
{
FunctionInstance
*
apply
=
asFunctionNullable
(
getInstanceExport
(
current_module
,
name
.
c_str
()));
if
(
!
apply
)
{
return
;
/// if not found then it is a no-op
}
const
FunctionType
*
functionType
=
getFunctionType
(
apply
);
FC_ASSERT
(
functionType
->
parameters
.
size
()
==
0
);
std
::
vector
<
Value
>
args
(
0
);
const
FunctionType
*
functionType
=
getFunctionType
(
apply
);
FC_ASSERT
(
functionType
->
parameters
.
size
()
==
0
);
std
::
vector
<
Value
>
args
(
0
);
auto
&
state
=
*
current_state
;
char
*
memstart
=
&
memoryRef
<
char
>
(
current_memory
,
0
);
memset
(
memstart
+
state
.
mem_end
,
0
,
((
1
<<
16
)
-
state
.
mem_end
)
);
memcpy
(
memstart
,
state
.
init_memory
.
data
(),
state
.
mem_end
);
Runtime
::
invokeFunction
(
apply
,
args
);
Runtime
::
invokeFunction
(
apply
,
args
);
}
catch
(
const
Runtime
::
Exception
&
e
)
{
edump
((
std
::
string
(
describeExceptionCause
(
e
.
cause
))));
edump
((
e
.
callStack
));
throw
;
edump
((
e
.
callStack
));
throw
;
}
}
FC_CAPTURE_AND_RETHROW
(
(
name
)(
current_validate_context
->
msg
.
type
)
)
}
...
...
@@ -328,22 +328,22 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
{
try
{
try
{
// wlog( "on_init" );
FunctionInstance
*
apply
=
asFunctionNullable
(
getInstanceExport
(
current_module
,
"init"
));
if
(
!
apply
)
{
wlog
(
"no onInit method found"
);
return
;
/// if not found then it is a no-op
FunctionInstance
*
apply
=
asFunctionNullable
(
getInstanceExport
(
current_module
,
"init"
));
if
(
!
apply
)
{
wlog
(
"no onInit method found"
);
return
;
/// if not found then it is a no-op
}
const
FunctionType
*
functionType
=
getFunctionType
(
apply
);
FC_ASSERT
(
functionType
->
parameters
.
size
()
==
0
);
const
FunctionType
*
functionType
=
getFunctionType
(
apply
);
FC_ASSERT
(
functionType
->
parameters
.
size
()
==
0
);
std
::
vector
<
Value
>
args
(
0
);
std
::
vector
<
Value
>
args
(
0
);
Runtime
::
invokeFunction
(
apply
,
args
);
Runtime
::
invokeFunction
(
apply
,
args
);
}
catch
(
const
Runtime
::
Exception
&
e
)
{
edump
((
std
::
string
(
describeExceptionCause
(
e
.
cause
))));
edump
((
e
.
callStack
));
throw
;
edump
((
e
.
callStack
));
throw
;
}
}
FC_CAPTURE_AND_RETHROW
()
}
...
...
@@ -425,7 +425,7 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
for
(
uint32_t
i
=
0
;
i
<
10000
;
++
i
)
if
(
memstart
[
i
]
)
{
state
.
mem_end
=
i
;
//
std::cerr << (char)memstart[i];
//
std::cerr << (char)memstart[i];
}
state
.
init_memory
.
resize
(
state
.
mem_end
);
...
...
libraries/native_contract/include/eos/native_contract/staked_balance_contract.hpp
浏览文件 @
898947fc
...
...
@@ -47,7 +47,7 @@ void validate_staked_okproducer(chain::message_validate_context& context);
void
precondition_staked_okproducer
(
chain
::
precondition_validate_context
&
context
);
void
apply_staked_okproducer
(
chain
::
apply_context
&
context
);
//void validate_staked_setproxy(chain::message_validate_context&) {}
void
validate_staked_setproxy
(
chain
::
message_validate_context
&
context
);
void
precondition_staked_setproxy
(
chain
::
precondition_validate_context
&
context
);
void
apply_staked_setproxy
(
chain
::
apply_context
&
context
);
///@}
...
...
libraries/native_contract/native_contract_chain_initializer.cpp
浏览文件 @
898947fc
...
...
@@ -117,16 +117,18 @@ std::vector<chain::Message> native_contract_chain_initializer::prepare_database(
return
types
::
Authority
(
1
,
{{
k
,
1
}},
{});
};
for
(
const
auto
&
acct
:
genesis
.
initial_accounts
)
{
chain
::
Message
message
(
config
::
SystemContractName
,
config
::
SystemContractName
,
{
config
::
EosContractName
,
config
::
StakedBalanceContractName
},
chain
::
Message
message
(
config
::
SystemContractName
,
vector
<
AccountName
>
{
config
::
EosContractName
,
config
::
StakedBalanceContractName
},
vector
<
types
::
AccountPermission
>
{},
"newaccount"
,
types
::
newaccount
(
config
::
SystemContractName
,
acct
.
name
,
KeyAuthority
(
acct
.
owner_key
),
KeyAuthority
(
acct
.
active_key
),
KeyAuthority
(
acct
.
owner_key
),
acct
.
staking_balance
));
KeyAuthority
(
acct
.
owner_key
),
KeyAuthority
(
acct
.
active_key
),
KeyAuthority
(
acct
.
owner_key
),
acct
.
staking_balance
));
messages_to_process
.
emplace_back
(
std
::
move
(
message
));
if
(
acct
.
liquid_balance
>
0
)
{
message
=
chain
::
Message
(
config
::
SystemContractName
,
config
::
EosContractName
,
{},
message
=
chain
::
Message
(
config
::
SystemContractName
,
vector
<
AccountName
>
{
config
::
EosContractName
},
vector
<
types
::
AccountPermission
>
{},
"transfer"
,
types
::
transfer
(
config
::
SystemContractName
,
acct
.
name
,
acct
.
liquid_balance
,
"Genesis Allocation"
));
messages_to_process
.
emplace_back
(
std
::
move
(
message
));
...
...
@@ -135,7 +137,8 @@ std::vector<chain::Message> native_contract_chain_initializer::prepare_database(
// Create initial producers
auto
CreateProducer
=
boost
::
adaptors
::
transformed
([
config
=
genesis
.
initial_configuration
](
const
auto
&
p
)
{
return
chain
::
Message
(
config
::
SystemContractName
,
config
::
StakedBalanceContractName
,
vector
<
AccountName
>
{},
return
chain
::
Message
(
config
::
SystemContractName
,
{
config
::
StakedBalanceContractName
},
vector
<
types
::
AccountPermission
>
{},
"setproducer"
,
types
::
setproducer
(
p
.
owner_name
,
p
.
block_signing_key
,
config
));
});
boost
::
copy
(
genesis
.
initial_producers
|
CreateProducer
,
std
::
back_inserter
(
messages_to_process
));
...
...
libraries/native_contract/staked_balance_contract.cpp
浏览文件 @
898947fc
...
...
@@ -122,20 +122,20 @@ void validate_staked_okproducer(message_validate_context& context) {
auto
approve
=
context
.
msg
.
as
<
types
::
okproducer
>
();
EOS_ASSERT
(
approve
.
approve
==
0
||
approve
.
approve
==
1
,
message_validate_exception
,
"Unknown approval value: ${val}; must be either 0 or 1"
,
(
"val"
,
approve
.
approve
));
EOS_ASSERT
(
approve
.
producer
.
good
(),
message_validate_exception
,
"Approved producer's name cannot be empty"
);
context
.
msg
.
recipient
(
approve
.
voter
);
context
.
msg
.
recipient
(
approve
.
producer
);
}
void
precondition_staked_okproducer
(
precondition_validate_context
&
context
)
{
const
auto
&
db
=
context
.
db
;
auto
approve
=
context
.
msg
.
as
<
types
::
okproducer
>
();
auto
producer
=
db
.
find
<
ProducerVotesObject
,
byOwnerName
>
(
approve
.
producer
);
auto
voter
=
db
.
find
<
StakedBalanceObject
,
byOwnerName
>
(
context
.
msg
.
sender
);
auto
producer
=
db
.
find
<
ProducerVotesObject
,
byOwnerName
>
(
context
.
msg
.
recipient
(
approve
.
producer
)
);
auto
voter
=
db
.
find
<
StakedBalanceObject
,
byOwnerName
>
(
context
.
msg
.
recipient
(
approve
.
voter
)
);
EOS_ASSERT
(
producer
!=
nullptr
,
message_precondition_exception
,
"Could not approve producer '${name}'; no such producer found"
,
(
"name"
,
approve
.
producer
));
"Could not approve producer '${name}'; no such producer found"
,
(
"name"
,
producer
->
ownerName
));
EOS_ASSERT
(
voter
!=
nullptr
,
message_precondition_exception
,
"Could not find balance for '${name}'"
,
(
"name"
,
context
.
msg
.
sender
));
"Could not find balance for '${name}'"
,
(
"name"
,
voter
->
ownerName
));
EOS_ASSERT
(
voter
->
producerVotes
.
contains
<
ProducerSlate
>
(),
message_precondition_exception
,
"Cannot approve producer; approving account '${name}' proxies its votes to '${proxy}'"
,
(
"name"
,
voter
->
ownerName
)(
"proxy"
,
voter
->
producerVotes
.
get
<
AccountName
>
()));
...
...
@@ -145,20 +145,20 @@ void precondition_staked_okproducer(precondition_validate_context& context) {
EOS_ASSERT
(
slate
.
size
<
config
::
MaxProducerVotes
,
message_precondition_exception
,
"Cannot approve producer; approved producer count is already at maximum"
);
if
(
approve
.
approve
)
EOS_ASSERT
(
!
slate
.
contains
(
approve
.
producer
),
message_precondition_exception
,
EOS_ASSERT
(
!
slate
.
contains
(
producer
->
ownerName
),
message_precondition_exception
,
"Cannot add approval to producer '${name}'; producer is already approved"
,
(
"name"
,
approve
.
producer
));
(
"name"
,
producer
->
ownerName
));
else
EOS_ASSERT
(
slate
.
contains
(
approve
.
producer
),
message_precondition_exception
,
EOS_ASSERT
(
slate
.
contains
(
producer
->
ownerName
),
message_precondition_exception
,
"Cannot remove approval from producer '${name}'; producer is not approved"
,
(
"name"
,
approve
.
producer
));
(
"name"
,
producer
->
ownerName
));
}
void
apply_staked_okproducer
(
apply_context
&
context
)
{
auto
&
db
=
context
.
mutable_db
;
auto
approve
=
context
.
msg
.
as
<
types
::
okproducer
>
();
const
auto
&
producer
=
db
.
get
<
ProducerVotesObject
,
byOwnerName
>
(
approve
.
producer
);
const
auto
&
voter
=
db
.
get
<
StakedBalanceObject
,
byOwnerName
>
(
context
.
msg
.
sender
);
const
auto
&
producer
=
db
.
get
<
ProducerVotesObject
,
byOwnerName
>
(
context
.
msg
.
recipient
(
approve
.
producer
)
);
const
auto
&
voter
=
db
.
get
<
StakedBalanceObject
,
byOwnerName
>
(
context
.
msg
.
recipient
(
approve
.
voter
)
);
auto
raceTime
=
ProducerScheduleObject
::
get
(
db
).
currentRaceTime
;
auto
totalVotingStake
=
voter
.
stakedBalance
;
...
...
@@ -174,51 +174,57 @@ void apply_staked_okproducer(apply_context& context) {
pvo
.
updateVotes
(
-
totalVotingStake
,
raceTime
);
});
// Add/remove producer from voter's approved producer list
db
.
modify
(
voter
,
[
&
approve
](
StakedBalanceObject
&
sbo
)
{
db
.
modify
(
voter
,
[
&
approve
,
producer
=
producer
.
ownerName
](
StakedBalanceObject
&
sbo
)
{
auto
&
slate
=
sbo
.
producerVotes
.
get
<
ProducerSlate
>
();
if
(
approve
.
approve
)
slate
.
add
(
approve
.
producer
);
slate
.
add
(
producer
);
else
slate
.
remove
(
approve
.
producer
);
slate
.
remove
(
producer
);
});
}
void
validate_staked_setproxy
(
message_validate_context
&
context
)
{
auto
svp
=
context
.
msg
.
as
<
types
::
setproxy
>
();
context
.
msg
.
recipient
(
svp
.
stakeholder
);
context
.
msg
.
recipient
(
svp
.
proxy
);
}
void
precondition_staked_setproxy
(
precondition_validate_context
&
context
)
{
auto
svp
=
context
.
msg
.
as
<
types
::
setproxy
>
();
const
auto
&
db
=
context
.
db
;
auto
proxy
=
db
.
find
<
ProxyVoteObject
,
byTargetName
>
(
context
.
msg
.
sender
);
auto
proxy
=
db
.
find
<
ProxyVoteObject
,
byTargetName
>
(
context
.
msg
.
recipient
(
svp
.
proxy
)
);
EOS_ASSERT
(
proxy
==
nullptr
,
message_precondition_exception
,
"Account '${src}' cannot proxy its votes, since it allows other accounts to proxy to it"
,
(
"src"
,
context
.
msg
.
sender
));
(
"src"
,
context
.
msg
.
recipient
(
svp
.
stakeholder
)
));
if
(
svp
.
proxy
!=
context
.
msg
.
sen
der
)
{
// We are trying to enable proxying to svp.proxy
auto
proxy
=
db
.
find
<
ProxyVoteObject
,
byTargetName
>
(
svp
.
proxy
);
if
(
svp
.
proxy
!=
svp
.
stakehol
der
)
{
// We are trying to enable proxying
from svp.stakeholder
to svp.proxy
auto
proxy
=
db
.
find
<
ProxyVoteObject
,
byTargetName
>
(
context
.
msg
.
recipient
(
svp
.
proxy
)
);
EOS_ASSERT
(
proxy
!=
nullptr
,
message_precondition_exception
,
"Proxy target '${target}' does not allow votes to be proxied to it"
,
(
"target"
,
svp
.
proxy
));
"Proxy target '${target}' does not allow votes to be proxied to it"
,
(
"target"
,
proxy
->
proxyTarget
));
}
else
{
// We are trying to disable proxying to sender.producerVotes.get<AccountName>()
const
auto
&
sender
=
db
.
get
<
StakedBalanceObject
,
byOwnerName
>
(
context
.
msg
.
sender
);
const
auto
&
sender
=
db
.
get
<
StakedBalanceObject
,
byOwnerName
>
(
context
.
msg
.
recipient
(
svp
.
stakeholder
)
);
EOS_ASSERT
(
sender
.
producerVotes
.
contains
<
AccountName
>
(),
message_precondition_exception
,
"Account '${name}' does not currently proxy its votes to any account"
,
(
"name"
,
context
.
msg
.
sender
));
"Account '${name}' does not currently proxy its votes to any account"
,
(
"name"
,
context
.
msg
.
recipient
(
svp
.
stakeholder
)));
}
}
void
apply_staked_setproxy
(
apply_context
&
context
)
{
auto
svp
=
context
.
msg
.
as
<
types
::
setproxy
>
();
auto
&
db
=
context
.
mutable_db
;
const
auto
&
proxy
=
db
.
get
<
ProxyVoteObject
,
byTargetName
>
(
svp
.
proxy
);
const
auto
&
balance
=
db
.
get
<
StakedBalanceObject
,
byOwnerName
>
(
context
.
msg
.
sender
);
const
auto
&
proxy
=
db
.
get
<
ProxyVoteObject
,
byTargetName
>
(
context
.
msg
.
recipient
(
svp
.
proxy
)
);
const
auto
&
balance
=
db
.
get
<
StakedBalanceObject
,
byOwnerName
>
(
context
.
msg
.
recipient
(
svp
.
stakeholder
)
);
if
(
svp
.
proxy
!=
context
.
msg
.
sen
der
)
{
if
(
svp
.
proxy
!=
svp
.
stakehol
der
)
{
// We are enabling proxying to svp.proxy
proxy
.
addProxySource
(
context
.
msg
.
sender
,
balance
.
stakedBalance
,
db
);
db
.
modify
(
balance
,
[
target
=
svp
.
proxy
](
StakedBalanceObject
&
sbo
)
{
sbo
.
producerVotes
=
target
;
});
proxy
.
addProxySource
(
context
.
msg
.
recipient
(
svp
.
stakeholder
)
,
balance
.
stakedBalance
,
db
);
db
.
modify
(
balance
,
[
target
=
proxy
.
proxyTarget
](
StakedBalanceObject
&
sbo
)
{
sbo
.
producerVotes
=
target
;
});
}
else
{
// We are disabling proxying to balance.producerVotes.get<AccountName>()
proxy
.
removeProxySource
(
context
.
msg
.
sender
,
balance
.
stakedBalance
,
db
);
proxy
.
removeProxySource
(
context
.
msg
.
recipient
(
svp
.
stakeholder
)
,
balance
.
stakedBalance
,
db
);
db
.
modify
(
balance
,
[](
StakedBalanceObject
&
sbo
)
{
sbo
.
producerVotes
=
ProducerSlate
{};
});
}
}
...
...
libraries/types/types.eos
浏览文件 @
898947fc
...
...
@@ -3,6 +3,7 @@ typedef Name PermissionName
typedef Name FuncName
typedef FixedString32 MessageName
typedef FixedString32 TypeName
typedef UInt8 NameIndex # Index to an AccountName in Message::recipients
# import account type as localtype
...
...
@@ -91,14 +92,13 @@ struct setproducer
# implies message.sender account
struct okproducer
producer AccountName
approve Int8 # 0 or 1
voter NameIndex # The account casting a vote
producer NameIndex # The producer being voted on
approve Int8 # 1 to approve, or 0 to disapprove
# implies message.sender account
# implies message.sender account
struct setproxy
proxy AccountName
stakeholder NameIndex # The account with stake to be proxied
proxy NameIndex # The account to cast votes with stakeholder's stake weight
struct UpdatePermission
...
...
tests/common/database_fixture.hpp
浏览文件 @
898947fc
...
...
@@ -417,11 +417,12 @@ protected:
#define Set_Proxy(chain, stakeholder, proxy) \
{ \
eos::chain::SignedTransaction trx; \
vector<AccountName> notifies; \
if (std::string(#stakeholder) == std::string(#proxy)) \
notifies.emplace_back(#proxy); \
trx.emplaceMessage(#stakeholder, config::StakedBalanceContractName, notifies, "setproxy", \
types::setproxy{#proxy}); \
if (std::string(#stakeholder) != std::string(#proxy)) \
trx.emplaceMessage(config::StakedBalanceContractName, vector<AccountName>{#stakeholder, #proxy}, \
vector<types::AccountPermission>{}, "setproxy", types::setproxy{0, 1}); \
else \
trx.emplaceMessage(config::StakedBalanceContractName, vector<AccountName>{#stakeholder}, \
vector<types::AccountPermission>{}, "setproxy", types::setproxy{0, 0}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx); \
...
...
tests/common/macro_support.hpp
浏览文件 @
898947fc
...
...
@@ -26,10 +26,10 @@
#define MKACCT_IMPL(chain, name, creator, active, owner, recovery, deposit) \
{ \
eos::chain::SignedTransaction trx; \
trx.emplaceMessage(
#creator,
config::SystemContractName, \
vector<
types::AccountName>{config::StakedBalanceContractName
, \
config::EosContractName}, "newaccount"
, \
types::newaccount{#creator, #name, owner, active, recovery, deposit}); \
trx.emplaceMessage(config::SystemContractName, \
vector<
AccountName>{#creator, config::StakedBalanceContractName, config::EosContractName}
, \
vector<types::AccountPermission>{}
, \
"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); \
...
...
@@ -58,8 +58,9 @@
#define XFER5(chain, sender, recipient, amount, memo) \
{ \
eos::chain::SignedTransaction trx; \
trx.emplaceMessage(#sender, config::EosContractName, vector<AccountName>{#recipient}, "transfer", \
types::transfer{#sender, #recipient, amount, memo}); \
trx.emplaceMessage(config::EosContractName, vector<AccountName>{#sender, #recipient}, \
vector<types::AccountPermission>{}, \
"transfer", types::transfer{#sender, #recipient, amount, memo}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx); \
...
...
@@ -70,11 +71,11 @@
#define STAKE4(chain, sender, recipient, amount) \
{ \
eos::chain::SignedTransaction trx; \
trx.emplaceMessage(
#sender, config::EosContractName, vector<AccountName>{
config::StakedBalanceContractName}, \
"lock", types::lock{#sender, #recipient, amount}); \
trx.emplaceMessage(
config::EosContractName, vector<AccountName>{#sender,
config::StakedBalanceContractName}, \
vector<types::AccountPermission>{},
"lock", types::lock{#sender, #recipient, amount}); \
if (std::string(#sender) != std::string(#recipient)) { \
trx.messages.front().
notify
.emplace_back(#recipient); \
boost::sort(trx.messages.front().
notify
); \
trx.messages.front().
recipients
.emplace_back(#recipient); \
boost::sort(trx.messages.front().
recipients
); \
} \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
...
...
@@ -86,7 +87,8 @@
#define BEGIN_UNSTAKE3(chain, account, amount) \
{ \
eos::chain::SignedTransaction trx; \
trx.emplaceMessage(#account, config::StakedBalanceContractName, vector<AccountName>{}, \
trx.emplaceMessage(config::StakedBalanceContractName, vector<AccountName>{#account}, \
vector<types::AccountPermission>{}, \
"unlock", types::unlock{#account, amount}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
...
...
@@ -97,8 +99,8 @@
#define FINISH_UNSTAKE3(chain, account, amount) \
{ \
eos::chain::SignedTransaction trx; \
trx.emplaceMessage(
#account, config::StakedBalanceContractName, vector<AccountName>{
config::EosContractName}, \
"claim", types::claim{#account, amount}); \
trx.emplaceMessage(
config::StakedBalanceContractName, vector<AccountName>{#account,
config::EosContractName}, \
vector<types::AccountPermission>{},
"claim", types::claim{#account, amount}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx); \
...
...
@@ -108,8 +110,9 @@
#define MKPDCR4(chain, owner, key, cfg) \
{ \
eos::chain::SignedTransaction trx; \
trx.emplaceMessage(#owner, config::StakedBalanceContractName, vector<AccountName>{}, "setproducer", \
types::setproducer{#owner, key, cfg}); \
trx.emplaceMessage(config::StakedBalanceContractName, vector<AccountName>{#owner}, \
vector<types::AccountPermission>{}, \
"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); \
...
...
@@ -123,8 +126,9 @@
#define APPDCR4(chain, voter, producer, approved) \
{ \
eos::chain::SignedTransaction trx; \
trx.emplaceMessage(#voter, config::StakedBalanceContractName, vector<AccountName>{}, "okproducer", \
types::okproducer{#producer, approved? 1 : 0}); \
trx.emplaceMessage(config::StakedBalanceContractName, vector<AccountName>{#voter, #producer}, \
vector<types::AccountPermission>{}, \
"okproducer", types::okproducer{0, 1, approved? 1 : 0}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx); \
...
...
@@ -134,8 +138,9 @@
#define UPPDCR4(chain, owner, key, cfg) \
{ \
eos::chain::SignedTransaction trx; \
trx.emplaceMessage(owner, config::StakedBalanceContractName, vector<AccountName>{}, "setproducer", \
types::setproducer{owner, key, cfg}); \
trx.emplaceMessage(config::StakedBalanceContractName, vector<AccountName>{#owner}, \
vector<types::AccountPermission>{}, \
"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); \
...
...
tests/slow_tests/slow_tests.cpp
浏览文件 @
898947fc
...
...
@@ -177,8 +177,7 @@ BOOST_FIXTURE_TEST_CASE(create_script, testing_fixture)
{
eos
::
chain
::
SignedTransaction
trx
;
trx
.
messages
.
resize
(
1
);
trx
.
messages
[
0
].
sender
=
"simplecoin"
;
trx
.
messages
[
0
].
recipient
=
config
::
SystemContractName
;
trx
.
messages
[
0
].
recipients
=
{
"simplecoin"
,
config
::
SystemContractName
};
trx
.
setMessage
(
0
,
"setcode"
,
handler
);
trx
.
expiration
=
chain
.
head_block_time
()
+
100
;
trx
.
set_reference_block
(
chain
.
head_block_id
());
...
...
@@ -191,8 +190,9 @@ BOOST_FIXTURE_TEST_CASE(create_script, testing_fixture)
for
(
uint32_t
i
=
0
;
i
<
100000
;
++
i
)
{
eos
::
chain
::
SignedTransaction
trx
;
trx
.
emplaceMessage
(
"simplecoin"
,
"simplecoin"
,
vector
<
AccountName
>
{
"inita"
},
"transfer"
,
types
::
transfer
{
"simplecoin"
,
"inita"
,
1
+
i
,
"hello"
}
);
trx
.
emplaceMessage
(
"simplecoin"
,
vector
<
AccountName
>
{
"simplecoin"
,
"inita"
},
vector
<
types
::
AccountPermission
>
{},
"transfer"
,
types
::
transfer
{
"simplecoin"
,
"inita"
,
1
+
i
,
"hello"
});
trx
.
expiration
=
chain
.
head_block_time
()
+
100
;
trx
.
set_reference_block
(
chain
.
head_block_id
());
chain
.
push_transaction
(
trx
);
...
...
@@ -971,8 +971,7 @@ R"(
eos
::
chain
::
SignedTransaction
trx
;
trx
.
messages
.
resize
(
1
);
trx
.
messages
[
0
].
sender
=
"simplecoin"
;
trx
.
messages
[
0
].
recipient
=
config
::
SystemContractName
;
trx
.
messages
[
0
].
recipients
=
{
"simplecoin"
,
config
::
SystemContractName
};
trx
.
setMessage
(
0
,
"setcode"
,
handler
);
trx
.
expiration
=
chain
.
head_block_time
()
+
100
;
trx
.
set_reference_block
(
chain
.
head_block_id
());
...
...
tests/tests/native_contract_tests.cpp
浏览文件 @
898947fc
...
...
@@ -90,8 +90,7 @@ BOOST_FIXTURE_TEST_CASE(transfer, testing_fixture)
trx
.
messages
.
resize
(
1
);
trx
.
set_reference_block
(
chain
.
head_block_id
());
trx
.
expiration
=
chain
.
head_block_time
()
+
100
;
trx
.
messages
[
0
].
sender
=
"inita"
;
trx
.
messages
[
0
].
recipient
=
config
::
EosContractName
;
trx
.
messages
[
0
].
recipients
=
{
"inita"
,
config
::
EosContractName
};
types
::
transfer
trans
=
{
"inita"
,
"initb"
,
Asset
(
100
),
"transfer 100"
};
...
...
@@ -105,7 +104,7 @@ BOOST_FIXTURE_TEST_CASE(transfer, testing_fixture)
auto
unpack_trans
=
trx
.
messageAs
<
types
::
transfer
>
(
0
);
BOOST_REQUIRE_THROW
(
chain
.
push_transaction
(
trx
),
message_validate_exception
);
// "fail to notify receiver, initb"
trx
.
messages
[
0
].
notify
=
{
"initb"
};
trx
.
messages
[
0
].
recipients
=
{
"inita"
,
"initb"
};
trx
.
setMessage
(
0
,
"transfer"
,
trans
);
chain
.
push_transaction
(
trx
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录