Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
4e10a2db
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,发现更多精彩内容 >>
提交
4e10a2db
编写于
4月 27, 2017
作者:
D
Daniel Larimer
浏览文件
操作
浏览文件
下载
差异文件
clean up system contract
上级
cbc7793a
20d9c9b8
变更
22
隐藏空白更改
内联
并排
Showing
22 changed file
with
423 addition
and
173 deletion
+423
-173
libraries/chain/CMakeLists.txt
libraries/chain/CMakeLists.txt
+0
-1
libraries/chain/database.cpp
libraries/chain/database.cpp
+39
-42
libraries/chain/include/eos/chain/database.hpp
libraries/chain/include/eos/chain/database.hpp
+2
-2
libraries/chain/include/eos/chain/exceptions.hpp
libraries/chain/include/eos/chain/exceptions.hpp
+10
-9
libraries/chain/include/eos/chain/sys_contract.hpp
libraries/chain/include/eos/chain/sys_contract.hpp
+0
-32
libraries/chain/sys_contract.cpp
libraries/chain/sys_contract.cpp
+0
-35
plugins/CMakeLists.txt
plugins/CMakeLists.txt
+1
-0
plugins/chain_api_plugin/chain_api_plugin.cpp
plugins/chain_api_plugin/chain_api_plugin.cpp
+21
-15
plugins/chain_plugin/chain_plugin.cpp
plugins/chain_plugin/chain_plugin.cpp
+29
-0
plugins/chain_plugin/include/eos/chain_plugin/chain_plugin.hpp
...ns/chain_plugin/include/eos/chain_plugin/chain_plugin.hpp
+56
-17
plugins/make_new_plugin.sh
plugins/make_new_plugin.sh
+21
-0
plugins/native_system_contract_plugin/CMakeLists.txt
plugins/native_system_contract_plugin/CMakeLists.txt
+16
-0
plugins/native_system_contract_plugin/include/eos/native_system_contract_plugin/native_system_contract_plugin.hpp
..._system_contract_plugin/native_system_contract_plugin.hpp
+58
-0
plugins/native_system_contract_plugin/native_system_contract_plugin.cpp
..._system_contract_plugin/native_system_contract_plugin.cpp
+68
-0
plugins/p2p_plugin/CMakeLists.txt
plugins/p2p_plugin/CMakeLists.txt
+1
-0
plugins/template_plugin/CMakeLists.txt
plugins/template_plugin/CMakeLists.txt
+16
-0
plugins/template_plugin/include/eos/template_plugin/template_plugin.hpp
...te_plugin/include/eos/template_plugin/template_plugin.hpp
+27
-0
plugins/template_plugin/template_plugin.cpp
plugins/template_plugin/template_plugin.cpp
+31
-0
tests/CMakeLists.txt
tests/CMakeLists.txt
+1
-1
tests/common/database_fixture.cpp
tests/common/database_fixture.cpp
+12
-7
tests/common/database_fixture.hpp
tests/common/database_fixture.hpp
+3
-2
tests/tests/block_tests.cpp
tests/tests/block_tests.cpp
+11
-10
未找到文件。
libraries/chain/CMakeLists.txt
浏览文件 @
4e10a2db
...
...
@@ -5,7 +5,6 @@ file(GLOB PROTOCOL_HEADERS "include/eos/chain/protocol/*.hpp")
## SORT .cpp by most likely to change / break compile
add_library
(
eos_chain
database.cpp
sys_contract.cpp
fork_database.cpp
protocol/types.cpp
...
...
libraries/chain/database.cpp
浏览文件 @
4e10a2db
...
...
@@ -32,8 +32,6 @@
#include <eos/chain/transaction_object.hpp>
#include <eos/chain/producer_object.hpp>
#include <eos/chain/sys_contract.hpp>
#include <fc/smart_ref_impl.hpp>
#include <fc/uint128.hpp>
#include <fc/crypto/digest.hpp>
...
...
@@ -128,11 +126,6 @@ std::vector<block_id_type> database::get_block_ids_on_fork(block_id_type head_of
*/
bool
database
::
push_block
(
const
signed_block
&
new_block
,
uint32_t
skip
)
{
try
{
/// TODO: the simulated network code will cause push_block to be called
/// recursively which in turn will cause the write lock to hang
if
(
new_block
.
block_num
()
==
head_block_num
()
&&
new_block
.
id
()
==
head_block_id
()
)
return
false
;
return
with_skip_flags
(
skip
,
[
&
](){
return
without_pending_transactions
(
[
&
]()
{
return
with_write_lock
(
[
&
]()
{
...
...
@@ -467,27 +460,32 @@ void database::apply_transaction(const signed_transaction& trx, uint32_t skip)
void
database
::
validate_tapos
(
const
signed_transaction
&
trx
)
const
{
try
{
if
(
!
check_tapos
()
)
return
;
if
(
!
should_
check_tapos
()
)
return
;
const
chain_parameters
&
chain_parameters
=
get_global_properties
().
parameters
;
const
auto
&
tapos_block_summary
=
get
<
block_summary_object
>
(
trx
.
ref_block_num
);
//Verify TaPoS block summary has correct ID prefix, and that this block's time is not past the expiration
FC_ASSERT
(
trx
.
ref_block_prefix
==
tapos_block_summary
.
block_id
.
_hash
[
1
]);
EOS_ASSERT
(
trx
.
ref_block_prefix
==
tapos_block_summary
.
block_id
.
_hash
[
1
],
transaction_exception
,
"Transaction's reference block did not match. Is this transaction from a different fork?"
);
fc
::
time_point_sec
now
=
head_block_time
();
FC_ASSERT
(
trx
.
expiration
<=
now
+
chain_parameters
.
maximum_time_until_expiration
,
""
,
(
"trx.expiration"
,
trx
.
expiration
)(
"now"
,
now
)(
"max_til_exp"
,
chain_parameters
.
maximum_time_until_expiration
));
FC_ASSERT
(
now
<=
trx
.
expiration
,
""
,
(
"now"
,
now
)(
"trx.exp"
,
trx
.
expiration
));
EOS_ASSERT
(
trx
.
expiration
<=
now
+
chain_parameters
.
maximum_time_until_expiration
,
transaction_exception
,
"Transaction expiration is too far in the future"
,
(
"trx.expiration"
,
trx
.
expiration
)(
"now"
,
now
)
(
"max_til_exp"
,
chain_parameters
.
maximum_time_until_expiration
));
EOS_ASSERT
(
now
<=
trx
.
expiration
,
transaction_exception
,
"Transaction is expired"
,
(
"now"
,
now
)(
"trx.exp"
,
trx
.
expiration
));
}
FC_CAPTURE_AND_RETHROW
(
(
trx
)
)
}
void
database
::
validate_uniqueness
(
const
signed_transaction
&
trx
)
const
{
if
(
!
check_for_duplicate_transactions
()
)
return
;
if
(
!
should_
check_for_duplicate_transactions
()
)
return
;
auto
trx_id
=
trx
.
id
();
auto
&
trx_idx
=
get_index
<
transaction_multi_index
>
();
FC_ASSERT
(
trx_idx
.
indices
().
get
<
by_trx_id
>
().
find
(
trx_id
)
==
trx_idx
.
indices
().
get
<
by_trx_id
>
().
end
());
EOS_ASSERT
(
trx_idx
.
indices
().
get
<
by_trx_id
>
().
find
(
trx_id
)
==
trx_idx
.
indices
().
get
<
by_trx_id
>
().
end
(),
transaction_exception
,
"Transaction is not unique"
);
}
void
database
::
validate_referenced_accounts
(
const
signed_transaction
&
trx
)
const
{
...
...
@@ -520,35 +518,35 @@ try {
void
database
::
validate_transaction
(
const
signed_transaction
&
trx
)
const
{
try
{
FC_ASSERT
(
trx
.
messages
.
size
()
>
0
,
"A transaction must have at least one message"
);
validate_uniqueness
(
trx
);
validate_tapos
(
trx
);
validate_referenced_accounts
(
trx
);
validate_message_types
(
trx
);
for
(
const
auto
&
m
:
trx
.
messages
)
{
/// TODO: this loop can be processed in parallel
message_validate_context
mvc
(
trx
,
m
);
auto
contract_handlers_itr
=
message_validate_handlers
.
find
(
m
.
recipient
);
if
(
contract_handlers_itr
!=
message_validate_handlers
.
end
()
)
{
auto
message_handelr_itr
=
contract_handlers_itr
->
second
.
find
(
{
m
.
recipient
,
m
.
type
}
);
if
(
message_handelr_itr
!=
contract_handlers_itr
->
second
.
end
()
)
{
message_handelr_itr
->
second
(
mvc
);
continue
;
}
}
/// TODO: dispatch to script if not handled above
}
EOS_ASSERT
(
trx
.
messages
.
size
()
>
0
,
transaction_exception
,
"A transaction must have at least one message"
);
validate_uniqueness
(
trx
);
validate_tapos
(
trx
);
validate_referenced_accounts
(
trx
);
validate_message_types
(
trx
);
for
(
const
auto
&
m
:
trx
.
messages
)
{
/// TODO: this loop can be processed in parallel
message_validate_context
mvc
(
trx
,
m
);
auto
contract_handlers_itr
=
message_validate_handlers
.
find
(
m
.
recipient
);
if
(
contract_handlers_itr
!=
message_validate_handlers
.
end
()
)
{
auto
message_handelr_itr
=
contract_handlers_itr
->
second
.
find
(
{
m
.
recipient
,
m
.
type
}
);
if
(
message_handelr_itr
!=
contract_handlers_itr
->
second
.
end
()
)
{
message_handelr_itr
->
second
(
mvc
);
continue
;
}
}
/// TODO: dispatch to script if not handled above
}
}
FC_CAPTURE_AND_RETHROW
(
(
trx
)
)
}
void
database
::
validate_message_precondition
(
precondition_validate_context
&
context
)
const
{
const
auto
&
m
=
context
.
msg
;
auto
contract_handlers_itr
=
precondition_validate_handlers
.
find
(
context
.
receiver
);
if
(
contract_handlers_itr
!=
precondition_validate_handlers
.
end
()
)
{
auto
message_hand
el
r_itr
=
contract_handlers_itr
->
second
.
find
(
{
m
.
recipient
,
m
.
type
}
);
if
(
message_hand
el
r_itr
!=
contract_handlers_itr
->
second
.
end
()
)
{
message_hand
el
r_itr
->
second
(
context
);
auto
message_hand
le
r_itr
=
contract_handlers_itr
->
second
.
find
(
{
m
.
recipient
,
m
.
type
}
);
if
(
message_hand
le
r_itr
!=
contract_handlers_itr
->
second
.
end
()
)
{
message_hand
le
r_itr
->
second
(
context
);
return
;
}
}
...
...
@@ -559,9 +557,9 @@ void database::apply_message( apply_context& context ) {
const
auto
&
m
=
context
.
msg
;
auto
contract_handlers_itr
=
apply_handlers
.
find
(
context
.
receiver
);
if
(
contract_handlers_itr
!=
apply_handlers
.
end
()
)
{
auto
message_hand
el
r_itr
=
contract_handlers_itr
->
second
.
find
(
{
m
.
recipient
,
m
.
type
}
);
if
(
message_hand
el
r_itr
!=
contract_handlers_itr
->
second
.
end
()
)
{
message_hand
el
r_itr
->
second
(
context
);
auto
message_hand
le
r_itr
=
contract_handlers_itr
->
second
.
find
(
{
m
.
recipient
,
m
.
type
}
);
if
(
message_hand
le
r_itr
!=
contract_handlers_itr
->
second
.
end
()
)
{
message_hand
le
r_itr
->
second
(
context
);
return
;
}
}
...
...
@@ -589,7 +587,7 @@ void database::_apply_transaction(const signed_transaction& trx)
}
//Insert transaction into unique transactions database.
if
(
check_for_duplicate_transactions
()
)
if
(
should_
check_for_duplicate_transactions
()
)
{
create
<
transaction_object
>
([
&
](
transaction_object
&
transaction
)
{
transaction
.
trx_id
=
trx
.
id
();
/// TODO: consider caching ID
...
...
@@ -729,7 +727,6 @@ void database::init_genesis(const genesis_state_type& genesis_state)
create
<
account_object
>
([
&
](
account_object
&
a
)
{
a
.
name
=
"sys"
;
});
init_sys_contract
();
// Create initial accounts
for
(
const
auto
&
acct
:
genesis_state
.
initial_accounts
)
{
...
...
libraries/chain/include/eos/chain/database.hpp
浏览文件 @
4e10a2db
...
...
@@ -336,8 +336,8 @@ namespace eos { namespace chain {
bool
check_for_duplicate_transactions
()
const
{
return
!
(
_skip_flags
&
skip_transaction_dupe_check
);
}
bool
check_tapos
()
const
{
return
!
(
_skip_flags
&
skip_tapos_check
);
}
bool
should_
check_for_duplicate_transactions
()
const
{
return
!
(
_skip_flags
&
skip_transaction_dupe_check
);
}
bool
should_
check_tapos
()
const
{
return
!
(
_skip_flags
&
skip_tapos_check
);
}
///Steps involved in applying a new block
///@{
...
...
libraries/chain/include/eos/chain/exceptions.hpp
浏览文件 @
4e10a2db
...
...
@@ -36,13 +36,13 @@
#define EOS_DECLARE_OP_BASE_EXCEPTIONS( op_name ) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _validate_exception, \
eos::chain::
operation
_validate_exception, \
eos::chain::
message
_validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value, \
#op_name "_operation validation exception" \
) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _evaluate_exception, \
eos::chain::
operation
_evaluate_exception, \
eos::chain::
message
_evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value, \
#op_name "_operation evaluation exception" \
)
...
...
@@ -71,13 +71,14 @@ namespace eos { namespace chain {
FC_DECLARE_DERIVED_EXCEPTION
(
database_query_exception
,
eos
::
chain
::
chain_exception
,
3010000
,
"database query exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
block_validate_exception
,
eos
::
chain
::
chain_exception
,
3020000
,
"block validation exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
transaction_exception
,
eos
::
chain
::
chain_exception
,
3030000
,
"transaction validation exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
operation_validate_exception
,
eos
::
chain
::
chain_exception
,
3040000
,
"operation validation exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
operation_evaluate_exception
,
eos
::
chain
::
chain_exception
,
3050000
,
"operation evaluation exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
utility_exception
,
eos
::
chain
::
chain_exception
,
3060000
,
"utility method exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
undo_database_exception
,
eos
::
chain
::
chain_exception
,
3070000
,
"undo database exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
unlinkable_block_exception
,
eos
::
chain
::
chain_exception
,
3080000
,
"unlinkable block"
)
FC_DECLARE_DERIVED_EXCEPTION
(
black_swan_exception
,
eos
::
chain
::
chain_exception
,
3090000
,
"black swan"
)
FC_DECLARE_DERIVED_EXCEPTION
(
unknown_block_exception
,
eos
::
chain
::
chain_exception
,
3100000
,
"unknown block"
)
FC_DECLARE_DERIVED_EXCEPTION
(
message_validate_exception
,
eos
::
chain
::
chain_exception
,
3040000
,
"message validation exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
message_precondition_exception
,
eos
::
chain
::
chain_exception
,
3050000
,
"message precondition exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
message_evaluate_exception
,
eos
::
chain
::
chain_exception
,
3060000
,
"message evaluation exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
utility_exception
,
eos
::
chain
::
chain_exception
,
3070000
,
"utility method exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
undo_database_exception
,
eos
::
chain
::
chain_exception
,
3080000
,
"undo database exception"
)
FC_DECLARE_DERIVED_EXCEPTION
(
unlinkable_block_exception
,
eos
::
chain
::
chain_exception
,
3090000
,
"unlinkable block"
)
FC_DECLARE_DERIVED_EXCEPTION
(
black_swan_exception
,
eos
::
chain
::
chain_exception
,
3100000
,
"black swan"
)
FC_DECLARE_DERIVED_EXCEPTION
(
unknown_block_exception
,
eos
::
chain
::
chain_exception
,
3110000
,
"unknown block"
)
FC_DECLARE_DERIVED_EXCEPTION
(
tx_missing_active_auth
,
eos
::
chain
::
transaction_exception
,
3030001
,
"missing required active authority"
)
FC_DECLARE_DERIVED_EXCEPTION
(
tx_missing_owner_auth
,
eos
::
chain
::
transaction_exception
,
3030002
,
"missing required owner authority"
)
...
...
libraries/chain/include/eos/chain/sys_contract.hpp
已删除
100644 → 0
浏览文件 @
cbc7793a
#pragma once
#include <eos/chain/protocol/types.hpp>
#include <eos/chain/protocol/authority.hpp>
/**
* @file sys_contract
* @brief defines logic for the native eos system contract
*/
namespace
eos
{
namespace
chain
{
struct
Transfer
{
account_name
to
;
uint64_t
amount
=
0
;
string
memo
;
};
struct
CreateAccount
{
account_name
new_account
;
Authority
owner
;
Authority
active
;
uint64_t
initial_balance
=
0
;
};
}
}
FC_REFLECT
(
eos
::
chain
::
Transfer
,
(
to
)(
amount
)(
memo
)
)
FC_REFLECT
(
eos
::
chain
::
CreateAccount
,
(
new_account
)(
owner
)(
active
)(
initial_balance
)
)
libraries/chain/sys_contract.cpp
已删除
100644 → 0
浏览文件 @
cbc7793a
#include <eos/chain/database.hpp>
#include <eos/chain/sys_contract.hpp>
#include <eos/chain/account_object.hpp>
namespace
eos
{
namespace
chain
{
void
database
::
init_sys_contract
()
{
wlog
(
"init sys contract"
);
set_validate_handler
(
"sys"
,
"sys"
,
"Transfer"
,
[
&
](
message_validate_context
&
context
)
{
auto
transfer
=
context
.
msg
.
as
<
Transfer
>
();
FC_ASSERT
(
context
.
msg
.
has_notify
(
transfer
.
to
),
"Must notify recipient of transfer"
);
});
set_precondition_validate_handler
(
"sys"
,
"sys"
,
"Transfer"
,
[
&
](
precondition_validate_context
&
context
)
{
auto
transfer
=
context
.
msg
.
as
<
Transfer
>
();
const
auto
&
from
=
get_account
(
context
.
msg
.
sender
);
FC_ASSERT
(
from
.
balance
>
transfer
.
amount
,
"Insufficient Funds"
,
(
"from.balance"
,
from
.
balance
)(
"transfer.amount"
,
transfer
.
amount
)
);
});
set_apply_handler
(
"sys"
,
"sys"
,
"Transfer"
,
[
&
](
apply_context
&
context
)
{
auto
transfer
=
context
.
msg
.
as
<
Transfer
>
();
const
auto
&
from
=
get_account
(
context
.
msg
.
sender
);
const
auto
&
to
=
get_account
(
transfer
.
to
);
modify
(
from
,
[
&
](
account_object
&
a
)
{
a
.
balance
-=
transfer
.
amount
;
});
modify
(
to
,
[
&
](
account_object
&
a
)
{
a
.
balance
+=
transfer
.
amount
;
});
});
}
}
}
// namespace eos::chain
plugins/CMakeLists.txt
浏览文件 @
4e10a2db
...
...
@@ -4,3 +4,4 @@ add_subdirectory(http_plugin)
add_subdirectory
(
chain_plugin
)
add_subdirectory
(
chain_api_plugin
)
add_subdirectory
(
producer_plugin
)
add_subdirectory
(
native_system_contract_plugin
)
plugins/chain_api_plugin/chain_api_plugin.cpp
浏览文件 @
4e10a2db
...
...
@@ -12,20 +12,6 @@ public:
chain_api_plugin_impl
(
database
&
db
)
:
db
(
db
)
{}
void
get_info
(
url_response_callback
&
cb
)
{
fc
::
mutable_variant_object
response
;
response
[
"head_block_num"
]
=
db
.
head_block_num
();
response
[
"head_block_id"
]
=
db
.
head_block_id
();
response
[
"head_block_time"
]
=
db
.
head_block_time
();
response
[
"head_block_producer"
]
=
db
.
head_block_producer
();
response
[
"recent_slots"
]
=
std
::
bitset
<
64
>
(
db
.
get_dynamic_global_properties
().
recent_slots_filled
).
to_string
();
response
[
"participation_rate"
]
=
__builtin_popcountll
(
db
.
get_dynamic_global_properties
().
recent_slots_filled
)
/
64.0
;
cb
(
200
,
fc
::
json
::
to_string
(
response
));
}
database
&
db
;
};
...
...
@@ -37,9 +23,29 @@ chain_api_plugin::~chain_api_plugin(){}
void
chain_api_plugin
::
set_program_options
(
options_description
&
,
options_description
&
)
{}
void
chain_api_plugin
::
plugin_initialize
(
const
variables_map
&
)
{}
#define CALL(api_name, api_handle, api_namespace, call_name) \
{std::string("/v1/" #api_name "/" #call_name), [this, api_handle](string, string body, url_response_callback cb) { \
try { \
if (body.empty()) body = "{}"; \
auto result = api_handle.call_name(fc::json::from_string(body).as<api_namespace::call_name ## _params>()); \
cb(200, fc::json::to_string(result)); \
} catch (fc::eof_exception) { \
cb(400, "Invalid arguments"); \
elog("Unable to parse arguments: ${args}", ("args", body)); \
} catch (fc::exception& e) { \
cb(500, e.what()); \
elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \
} \
}}
#define CHAIN_RO_CALL(call_name) CALL(chain, ro_api, chain_apis::read_only, call_name)
void
chain_api_plugin
::
plugin_startup
()
{
auto
ro_api
=
app
().
get_plugin
<
chain_plugin
>
().
get_read_only_api
();
app
().
get_plugin
<
http_plugin
>
().
add_api
({
{
std
::
string
(
"/v1/chain/get_info"
),
[
this
](
string
,
string
,
url_response_callback
cb
)
{
my
->
get_info
(
cb
);}}
CHAIN_RO_CALL
(
get_info
),
CHAIN_RO_CALL
(
get_block
)
});
}
...
...
plugins/chain_plugin/chain_plugin.cpp
浏览文件 @
4e10a2db
...
...
@@ -30,6 +30,7 @@ chain_plugin::chain_plugin()
chain_plugin
::~
chain_plugin
(){}
database
&
chain_plugin
::
db
()
{
return
my
->
db
;
}
const
chain
::
database
&
chain_plugin
::
db
()
const
{
return
my
->
db
;
}
void
chain_plugin
::
set_program_options
(
options_description
&
cli
,
options_description
&
cfg
)
{
...
...
@@ -145,4 +146,32 @@ bool chain_plugin::block_is_on_preferred_chain(const chain::block_id_type& block
return
db
().
get_block_id_for_num
(
chain
::
block_header
::
num_from_id
(
block_id
))
==
block_id
;
}
namespace
chain_apis
{
read_only
::
get_info_results
read_only
::
get_info
(
const
read_only
::
get_info_params
&
)
const
{
return
{
db
.
head_block_num
(),
db
.
head_block_id
(),
db
.
head_block_time
(),
db
.
head_block_producer
(),
std
::
bitset
<
64
>
(
db
.
get_dynamic_global_properties
().
recent_slots_filled
).
to_string
(),
__builtin_popcountll
(
db
.
get_dynamic_global_properties
().
recent_slots_filled
)
/
64.0
};
}
read_only
::
get_block_results
read_only
::
get_block
(
const
read_only
::
get_block_params
&
params
)
const
{
try
{
if
(
auto
block
=
db
.
fetch_block_by_id
(
fc
::
json
::
from_string
(
params
.
block_num_or_id
).
as
<
chain
::
block_id_type
>
()))
return
*
block
;
}
catch
(
fc
::
bad_cast_exception
)
{
/* do nothing */
}
try
{
if
(
auto
block
=
db
.
fetch_block_by_number
(
fc
::
to_uint64
(
params
.
block_num_or_id
)))
return
*
block
;
}
catch
(
fc
::
bad_cast_exception
)
{
/* do nothing */
}
FC_THROW_EXCEPTION
(
chain
::
unknown_block_exception
,
"Could not find block: ${block}"
,
(
"block"
,
params
.
block_num_or_id
));
}
}
// namespace chain_apis
}
// namespace eos
plugins/chain_plugin/include/eos/chain_plugin/chain_plugin.hpp
浏览文件 @
4e10a2db
...
...
@@ -7,29 +7,68 @@ namespace eos {
using
std
::
unique_ptr
;
using
namespace
appbase
;
class
chain_plugin
:
public
plugin
<
chain_plugin
>
{
public:
APPBASE_PLUGIN_REQUIRES
()
namespace
chain_apis
{
struct
empty
{};
chain_plugin
();
virtual
~
chain_plugin
()
;
class
read_only
{
const
database
&
db
;
virtual
void
set_program_options
(
options_description
&
cli
,
options_description
&
cfg
)
override
;
public:
read_only
(
const
database
&
db
)
:
db
(
db
)
{}
void
plugin_initialize
(
const
variables_map
&
options
);
void
plugin_startup
();
void
plugin_shutdown
();
using
get_info_params
=
empty
;
struct
get_info_results
{
uint32_t
head_block_num
;
chain
::
block_id_type
head_block_id
;
fc
::
time_point_sec
head_block_time
;
chain
::
producer_id_type
head_block_producer
;
string
recent_slots
;
double
participation_rate
;
};
get_info_results
get_info
(
const
get_info_params
&
)
const
;
bool
accept_block
(
const
chain
::
signed_block
&
block
,
bool
currently_syncing
);
void
accept_transaction
(
const
chain
::
signed_transaction
&
trx
);
struct
get_block_params
{
string
block_num_or_id
;
};
using
get_block_results
=
chain
::
signed_block
;
get_block_results
get_block
(
const
get_block_params
&
params
)
const
;
};
}
// namespace chain_apis
bool
block_is_on_preferred_chain
(
const
chain
::
block_id_type
&
block_id
);
class
chain_plugin
:
public
plugin
<
chain_plugin
>
{
public:
APPBASE_PLUGIN_REQUIRES
()
database
&
db
();
chain_plugin
();
virtual
~
chain_plugin
();
private:
unique_ptr
<
class
chain_plugin_impl
>
my
;
};
virtual
void
set_program_options
(
options_description
&
cli
,
options_description
&
cfg
)
override
;
void
plugin_initialize
(
const
variables_map
&
options
);
void
plugin_startup
();
void
plugin_shutdown
();
chain_apis
::
read_only
get_read_only_api
()
const
{
return
chain_apis
::
read_only
(
db
());
}
bool
accept_block
(
const
chain
::
signed_block
&
block
,
bool
currently_syncing
);
void
accept_transaction
(
const
chain
::
signed_transaction
&
trx
);
bool
block_is_on_preferred_chain
(
const
chain
::
block_id_type
&
block_id
);
database
&
db
();
const
database
&
db
()
const
;
private:
unique_ptr
<
class
chain_plugin_impl
>
my
;
};
}
FC_REFLECT
(
eos
::
chain_apis
::
empty
,
)
FC_REFLECT
(
eos
::
chain_apis
::
read_only
::
get_info_results
,
(
head_block_num
)(
head_block_id
)(
head_block_time
)(
head_block_producer
)
(
recent_slots
)(
participation_rate
))
FC_REFLECT
(
eos
::
chain_apis
::
read_only
::
get_block_params
,
(
block_num_or_id
))
plugins/make_new_plugin.sh
0 → 100755
浏览文件 @
4e10a2db
#!/bin/bash
if
[
$#
-ne
1
]
;
then
echo
Usage:
$0
my_new_plugin
echo
... where my_new_plugin is the name of the plugin you want to create
exit
1
fi
pluginName
=
$1
echo
Copying template...
cp
-r
template_plugin
$pluginName
echo
Renaming files/directories...
mv
$pluginName
/include/eos/template_plugin
$pluginName
/include/eos/
$pluginName
for
file
in
`
find
$pluginName
-type
f
-name
'*template_plugin*'
`
;
do
mv
$file
`
sed
s/template_plugin/
$pluginName
/g
<<<
$file
`
;
done
;
echo
Renaming
in
files...
find
$pluginName
-type
f
-exec
sed
-i
"s/template_plugin/
$pluginName
/g"
{}
\;
echo
"Done!
$pluginName
is ready. Don't forget to add it to CMakeLists.txt!"
plugins/native_system_contract_plugin/CMakeLists.txt
0 → 100644
浏览文件 @
4e10a2db
file
(
GLOB HEADERS
"include/eos/native_system_contract_plugin/*.hpp"
)
add_library
(
native_system_contract_plugin
native_system_contract_plugin.cpp
${
HEADERS
}
)
target_link_libraries
(
native_system_contract_plugin chain_plugin appbase fc
)
target_include_directories
(
native_system_contract_plugin PUBLIC
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/include"
)
install
(
TARGETS
native_system_contract_plugin
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
install
(
FILES
${
HEADERS
}
DESTINATION
"include/eos/native_system_contract_plugin"
)
plugins/native_system_contract_plugin/include/eos/native_system_contract_plugin/native_system_contract_plugin.hpp
0 → 100644
浏览文件 @
4e10a2db
#pragma once
#include <appbase/application.hpp>
#include <eos/chain_plugin/chain_plugin.hpp>
#include <eos/chain/protocol/authority.hpp>
#include <eos/chain/protocol/types.hpp>
namespace
eos
{
using
namespace
appbase
;
using
chain
::
account_name
;
using
chain
::
Authority
;
struct
Transfer
{
account_name
to
;
uint64_t
amount
=
0
;
string
memo
;
};
struct
CreateAccount
{
account_name
new_account
;
Authority
owner
;
Authority
active
;
uint64_t
initial_balance
=
0
;
};
/**
* @brief This class is a native C++ implementation of the system contract.
*/
class
native_system_contract_plugin
:
public
appbase
::
plugin
<
native_system_contract_plugin
>
{
public:
native_system_contract_plugin
();
virtual
~
native_system_contract_plugin
();
APPBASE_PLUGIN_REQUIRES
((
chain_plugin
))
virtual
void
set_program_options
(
options_description
&
,
options_description
&
)
override
{}
void
plugin_initialize
(
const
variables_map
&
options
);
void
plugin_startup
();
void
plugin_shutdown
();
/**
* @brief Install the system contract implementation on the provided database
*
* Installs the native system contract on the provided database. This method is static, and may be used without a
* native_system_contract_plugin or even AppBase. All that is required is a database to install the implementation
* on.
*/
static
void
install
(
chain
::
database
&
db
);
private:
std
::
unique_ptr
<
class
native_system_contract_plugin_impl
>
my
;
};
}
FC_REFLECT
(
eos
::
Transfer
,
(
to
)(
amount
)(
memo
))
FC_REFLECT
(
eos
::
CreateAccount
,
(
new_account
)(
owner
)(
active
)(
initial_balance
))
plugins/native_system_contract_plugin/native_system_contract_plugin.cpp
0 → 100644
浏览文件 @
4e10a2db
#include <eos/native_system_contract_plugin/native_system_contract_plugin.hpp>
#include <eos/chain/account_object.hpp>
#include <eos/chain/exceptions.hpp>
namespace
eos
{
using
namespace
chain
;
void
Transfer_validate
(
chain
::
message_validate_context
&
context
)
{
auto
transfer
=
context
.
msg
.
as
<
Transfer
>
();
EOS_ASSERT
(
context
.
msg
.
has_notify
(
transfer
.
to
),
message_validate_exception
,
"Must notify recipient of transfer"
);
}
void
Transfer_validate_preconditions
(
chain
::
precondition_validate_context
&
context
)
{
const
auto
&
db
=
context
.
db
;
auto
transfer
=
context
.
msg
.
as
<
Transfer
>
();
const
auto
&
from
=
db
.
get_account
(
context
.
msg
.
sender
);
EOS_ASSERT
(
from
.
balance
>
transfer
.
amount
,
message_precondition_exception
,
"Insufficient Funds"
,
(
"from.balance"
,
from
.
balance
)(
"transfer.amount"
,
transfer
.
amount
));
}
void
Transfer_apply
(
chain
::
apply_context
&
context
)
{
auto
&
db
=
context
.
mutable_db
;
auto
transfer
=
context
.
msg
.
as
<
Transfer
>
();
const
auto
&
from
=
db
.
get_account
(
context
.
msg
.
sender
);
const
auto
&
to
=
db
.
get_account
(
transfer
.
to
);
db
.
modify
(
from
,
[
&
](
account_object
&
a
)
{
a
.
balance
-=
transfer
.
amount
;
});
db
.
modify
(
to
,
[
&
](
account_object
&
a
)
{
a
.
balance
+=
transfer
.
amount
;
});
}
class
native_system_contract_plugin_impl
{
public:
native_system_contract_plugin_impl
(
database
&
db
)
:
db
(
db
)
{}
database
&
db
;
};
native_system_contract_plugin
::
native_system_contract_plugin
()
:
my
(
new
native_system_contract_plugin_impl
(
app
().
get_plugin
<
chain_plugin
>
().
db
())){}
native_system_contract_plugin
::~
native_system_contract_plugin
(){}
void
native_system_contract_plugin
::
plugin_initialize
(
const
variables_map
&
options
)
{
install
(
my
->
db
);
}
void
native_system_contract_plugin
::
plugin_startup
()
{
// Make the magic happen
}
void
native_system_contract_plugin
::
plugin_shutdown
()
{
// OK, that's enough magic
}
void
native_system_contract_plugin
::
install
(
database
&
db
)
{
#define SET_HANDLERS(name) \
db.set_validate_handler("sys", "sys", #name, \
[&db](chain::message_validate_context& c) mutable { name ## _validate(c); }); \
db.set_precondition_validate_handler("sys", "sys", #name, \
[&db](chain::precondition_validate_context& c) mutable { name ## _validate_preconditions(c); }); \
db.set_apply_handler("sys", "sys", #name, \
[&db](chain::apply_context& c) mutable { name ## _apply(c); })
SET_HANDLERS
(
Transfer
);
}
}
plugins/p2p_plugin/CMakeLists.txt
浏览文件 @
4e10a2db
...
...
@@ -2,6 +2,7 @@ file(GLOB HEADERS "include/eos/p2p_plugin/*.hpp")
add_library
(
p2p_plugin
p2p_plugin.cpp
${
HEADERS
}
)
target_link_libraries
(
p2p_plugin chain_plugin appbase eos_chain eos_utilities eos_net
)
...
...
plugins/template_plugin/CMakeLists.txt
0 → 100644
浏览文件 @
4e10a2db
file
(
GLOB HEADERS
"include/eos/template_plugin/*.hpp"
)
add_library
(
template_plugin
template_plugin.cpp
${
HEADERS
}
)
target_link_libraries
(
template_plugin appbase fc
)
target_include_directories
(
template_plugin PUBLIC
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/include"
)
install
(
TARGETS
template_plugin
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
install
(
FILES
${
HEADERS
}
DESTINATION
"include/eos/template_plugin"
)
plugins/template_plugin/include/eos/template_plugin/template_plugin.hpp
0 → 100644
浏览文件 @
4e10a2db
#pragma once
#include <appbase/application.hpp>
namespace
eos
{
using
namespace
appbase
;
/**
* This is a template plugin, intended to serve as a starting point for making new plugins
*/
class
template_plugin
:
public
appbase
::
plugin
<
template_plugin
>
{
public:
template_plugin
();
virtual
~
template_plugin
();
APPBASE_PLUGIN_REQUIRES
()
virtual
void
set_program_options
(
options_description
&
,
options_description
&
cfg
)
override
;
void
plugin_initialize
(
const
variables_map
&
options
);
void
plugin_startup
();
void
plugin_shutdown
();
private:
std
::
unique_ptr
<
class
template_plugin_impl
>
my
;
};
}
plugins/template_plugin/template_plugin.cpp
0 → 100644
浏览文件 @
4e10a2db
#include <eos/template_plugin/template_plugin.hpp>
namespace
eos
{
class
template_plugin_impl
{
public:
};
template_plugin
::
template_plugin
()
:
my
(
new
template_plugin_impl
()){}
template_plugin
::~
template_plugin
(){}
void
template_plugin
::
set_program_options
(
options_description
&
,
options_description
&
cfg
)
{
cfg
.
add_options
()
(
"option-name"
,
bpo
::
value
<
string
>
()
->
default_value
(
"default value"
),
"Option Description"
)
;
}
void
template_plugin
::
plugin_initialize
(
const
variables_map
&
options
)
{
if
(
options
.
count
(
"option-name"
))
{
// Handle the option
}
}
void
template_plugin
::
plugin_startup
()
{
// Make the magic happen
}
void
template_plugin
::
plugin_shutdown
()
{
// OK, that's enough magic
}
}
tests/CMakeLists.txt
浏览文件 @
4e10a2db
...
...
@@ -8,4 +8,4 @@ endif()
file
(
GLOB UNIT_TESTS
"tests/*.cpp"
)
add_executable
(
chain_test
${
UNIT_TESTS
}
${
COMMON_SOURCES
}
)
target_link_libraries
(
chain_test eos_chain eos_utilities eos_egenesis_none fc
${
PLATFORM_SPECIFIC_LIBS
}
)
target_link_libraries
(
chain_test
native_system_contract_plugin
eos_chain eos_utilities eos_egenesis_none fc
${
PLATFORM_SPECIFIC_LIBS
}
)
tests/common/database_fixture.cpp
浏览文件 @
4e10a2db
...
...
@@ -23,12 +23,15 @@
*/
#include <boost/test/unit_test.hpp>
#include <boost/program_options.hpp>
#include <boost/signals2/shared_connection_block.hpp>
#include <eos/chain/account_object.hpp>
#include <eos/chain/producer_object.hpp>
#include <eos/utilities/tempdir.hpp>
#include <eos/native_system_contract_plugin/native_system_contract_plugin.hpp>
#include <fc/crypto/digest.hpp>
#include <fc/smart_ref_impl.hpp>
...
...
@@ -89,6 +92,8 @@ testing_database::testing_database(testing_fixture& fixture, std::string id,
:
genesis_state
(
override_genesis_state
?
*
override_genesis_state
:
fixture
.
genesis_state
()),
fixture
(
fixture
)
{
data_dir
=
fixture
.
get_temp_dir
(
id
);
// Install the system contract implementation
native_system_contract_plugin
::
install
(
*
this
);
}
void
testing_database
::
open
()
{
...
...
@@ -151,9 +156,8 @@ void testing_network::connect_database(testing_database& new_database) {
}
// The new database is now in sync with any old ones; go ahead and connect the propagation signal.
databases
[
&
new_database
]
=
new_database
.
applied_block
.
connect
([
this
](
const
signed_block
&
block
)
{
if
(
!
currently_propagating_block
)
propagate_block
(
block
);
databases
[
&
new_database
]
=
new_database
.
applied_block
.
connect
([
this
,
&
new_database
](
const
signed_block
&
block
)
{
propagate_block
(
block
,
new_database
);
});
}
...
...
@@ -165,11 +169,12 @@ void testing_network::disconnect_all() {
databases
.
clear
();
}
void
testing_network
::
propagate_block
(
const
signed_block
&
block
)
{
currently_propagating_block
=
true
;
for
(
const
auto
&
pair
:
databases
)
void
testing_network
::
propagate_block
(
const
signed_block
&
block
,
const
testing_database
&
skip_db
)
{
for
(
const
auto
&
pair
:
databases
)
{
if
(
pair
.
first
==
&
skip_db
)
continue
;
boost
::
signals2
::
shared_connection_block
blocker
(
pair
.
second
);
pair
.
first
->
push_block
(
block
);
currently_propagating_block
=
false
;
}
}
}
}
// eos::chain
tests/common/database_fixture.hpp
浏览文件 @
4e10a2db
...
...
@@ -26,7 +26,9 @@
#include <eos/chain/database.hpp>
#include <eos/chain/producer_object.hpp>
#include <eos/chain/exceptions.hpp>
#include <eos/utilities/tempdir.hpp>
#include <fc/io/json.hpp>
#include <fc/smart_ref_impl.hpp>
#include <fc/signals.hpp>
...
...
@@ -240,11 +242,10 @@ public:
* @brief Send a block to all databases in this network
* @param block The block to send
*/
void
propagate_block
(
const
signed_block
&
block
);
void
propagate_block
(
const
signed_block
&
block
,
const
testing_database
&
skip_db
);
protected:
std
::
map
<
testing_database
*
,
fc
::
scoped_connection
>
databases
;
bool
currently_propagating_block
=
false
;
};
/// Some helpful macros to reduce boilerplate when making a testing_network and connecting some testing_databases @{
...
...
tests/tests/block_tests.cpp
浏览文件 @
4e10a2db
...
...
@@ -27,7 +27,8 @@
#include <eos/chain/database.hpp>
#include <eos/chain/exceptions.hpp>
#include <eos/chain/account_object.hpp>
#include <eos/chain/sys_contract.hpp>
#include <eos/native_system_contract_plugin/native_system_contract_plugin.hpp>
#include <eos/utilities/tempdir.hpp>
...
...
@@ -64,27 +65,27 @@ BOOST_FIXTURE_TEST_CASE(transfer, testing_fixture)
BOOST_CHECK_EQUAL
(
db
.
head_block_num
(),
10
);
signed_transaction
trx
;
BOOST_REQUIRE_THROW
(
db
.
push_transaction
(
trx
),
fc
::
assert_exception
);
/
// no messages
BOOST_REQUIRE_THROW
(
db
.
push_transaction
(
trx
),
transaction_exception
);
// no messages
trx
.
messages
.
resize
(
1
);
trx
.
set_reference_block
(
db
.
head_block_id
()
);
trx
.
set_expiration
(
db
.
head_block_time
()
);
trx
.
set_reference_block
(
db
.
head_block_id
()
);
trx
.
set_expiration
(
db
.
head_block_time
()
+
100
);
trx
.
messages
[
0
].
sender
=
"init1"
;
trx
.
messages
[
0
].
recipient
=
"sys"
;
trx
.
messages
[
0
].
type
=
"Undefined"
;
BOOST_REQUIRE_THROW
(
db
.
push_transaction
(
trx
),
fc
::
assert_exception
);
// "Type Undefined is not defined"
trx
.
messages
[
0
].
type
=
"Transfer"
;
trx
.
messages
[
0
].
set
(
"Transfer"
,
eos
::
chain
::
Transfer
{
"init2"
,
100
,
"memo"
}
);
BOOST_REQUIRE_THROW
(
db
.
push_transaction
(
trx
),
fc
::
assert_exception
);
// "fail to notify receiver, init2"
trx
.
messages
[
0
].
set
(
"Transfer"
,
Transfer
{
"init2"
,
100
,
"memo"
}
);
BOOST_REQUIRE_THROW
(
db
.
push_transaction
(
trx
),
message_validate_exception
);
// "fail to notify receiver, init2"
trx
.
messages
[
0
].
notify
=
{
"init2"
};
trx
.
messages
[
0
].
set
(
"Transfer"
,
eos
::
chain
::
Transfer
{
"init2"
,
100
,
"memo"
}
);
trx
.
messages
[
0
].
set
(
"Transfer"
,
Transfer
{
"init2"
,
100
,
"memo"
}
);
db
.
push_transaction
(
trx
);
BOOST_CHECK_EQUAL
(
db
.
get_account
(
"init1"
).
balance
,
100000
-
100
);
BOOST_CHECK_EQUAL
(
db
.
get_account
(
"init2"
).
balance
,
100000
+
100
);
BOOST_CHECK_EQUAL
(
db
.
get_account
(
"init1"
).
balance
,
100000
-
100
);
BOOST_CHECK_EQUAL
(
db
.
get_account
(
"init2"
).
balance
,
100000
+
100
);
db
.
produce_blocks
(
1
);
BOOST_REQUIRE_THROW
(
db
.
push_transaction
(
trx
),
fc
::
assert_exception
);
/// no messages
BOOST_REQUIRE_THROW
(
db
.
push_transaction
(
trx
),
transaction_exception
);
// not unique
}
FC_LOG_AND_RETHROW
()
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录