Compare commits
70 commits
master
...
feature/57
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
150136870d | ||
|
|
24b0327eb6 | ||
|
|
52209dbbeb | ||
|
|
0bdb826450 | ||
|
|
4d161ceeb2 | ||
|
|
fef5131a96 | ||
|
|
a818edc08d | ||
|
|
8667155f24 | ||
|
|
0390556770 | ||
|
|
87250fb20f | ||
|
|
d8e49a4d86 | ||
|
|
726f9818f6 | ||
|
|
f679588274 | ||
|
|
d5e0f2a53f | ||
|
|
cb916a0473 | ||
|
|
07dad6bcf2 | ||
|
|
64682a079c | ||
|
|
664379a8c1 | ||
|
|
b79df7db07 | ||
|
|
b6e4fc5c3c | ||
|
|
f6c6ac2cc8 | ||
|
|
56e15b8e80 | ||
|
|
60207813b0 | ||
|
|
18589ab198 | ||
|
|
c1aa13192d | ||
|
|
1520585b17 | ||
|
|
c055445e6a | ||
|
|
675eba96bb | ||
|
|
270751cb86 | ||
|
|
8e2d3cf2f6 | ||
|
|
9d687b97d2 | ||
|
|
113790d956 | ||
|
|
e24de4f199 | ||
|
|
15ebbfe6bb | ||
|
|
917e09a80b | ||
|
|
646b421308 | ||
|
|
dd2a531364 | ||
|
|
ae0a895daf | ||
|
|
8530228189 | ||
|
|
85fb3fee67 | ||
|
|
2c9fd332d4 | ||
|
|
fb01043e55 | ||
|
|
a1186372d2 | ||
|
|
3a51723e51 | ||
|
|
f23244cde0 | ||
|
|
fee7bc99fa | ||
|
|
6cf31b1075 | ||
|
|
97eaf4575a | ||
|
|
d367c308b8 | ||
|
|
838a9820f1 | ||
|
|
3e1f38d972 | ||
|
|
dfd3dfae09 | ||
|
|
1f72b4fbd6 | ||
|
|
3ee2439d5b | ||
|
|
cfecfb457b | ||
|
|
25bbacaa88 | ||
|
|
0175a7d0ec | ||
|
|
fd492ca196 | ||
|
|
2a6c917e4c | ||
|
|
6fe15f27b0 | ||
|
|
d2374aeed9 | ||
|
|
6f792db52d | ||
|
|
1b61016693 | ||
|
|
0f375777c2 | ||
|
|
a2ce65e1ef | ||
|
|
432876a677 | ||
|
|
948e7dd5e4 | ||
|
|
b21f9c4282 | ||
|
|
1586531e13 | ||
|
|
8e0e20eb6f |
32 changed files with 1440 additions and 10700 deletions
|
|
@ -32,6 +32,27 @@ build-mainnet:
|
||||||
tags:
|
tags:
|
||||||
- builder
|
- builder
|
||||||
|
|
||||||
|
build-mainnet-without-sidechain-plugin:
|
||||||
|
stage: build
|
||||||
|
script:
|
||||||
|
- rm -rf .git/modules/docs .git/modules/libraries/fc ./docs ./libraries/fc
|
||||||
|
- git submodule sync
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
- rm -rf build
|
||||||
|
- mkdir build
|
||||||
|
- cd build
|
||||||
|
- cmake -DCMAKE_BUILD_TYPE=Release -DDISABLE_PEERPLAYS_SIDECHAIN_PLUGIN=1 ..
|
||||||
|
- make -j$(nproc)
|
||||||
|
artifacts:
|
||||||
|
untracked: true
|
||||||
|
paths:
|
||||||
|
- build/libraries/
|
||||||
|
- build/programs/
|
||||||
|
- build/tests/
|
||||||
|
when: manual
|
||||||
|
tags:
|
||||||
|
- builder
|
||||||
|
|
||||||
test-mainnet:
|
test-mainnet:
|
||||||
stage: test
|
stage: test
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -83,6 +104,27 @@ build-testnet:
|
||||||
tags:
|
tags:
|
||||||
- builder
|
- builder
|
||||||
|
|
||||||
|
build-testnet-without-sidechain-plugin:
|
||||||
|
stage: build
|
||||||
|
script:
|
||||||
|
- rm -rf .git/modules/docs .git/modules/libraries/fc ./docs ./libraries/fc
|
||||||
|
- git submodule sync
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
- rm -rf build
|
||||||
|
- mkdir build
|
||||||
|
- cd build
|
||||||
|
- cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_PEERPLAYS_TESTNET=1 -DDISABLE_PEERPLAYS_SIDECHAIN_PLUGIN=1 ..
|
||||||
|
- make -j$(nproc)
|
||||||
|
artifacts:
|
||||||
|
untracked: true
|
||||||
|
paths:
|
||||||
|
- build/libraries/
|
||||||
|
- build/programs/
|
||||||
|
- build/tests/
|
||||||
|
when: manual
|
||||||
|
tags:
|
||||||
|
- builder
|
||||||
|
|
||||||
deploy-testnet:
|
deploy-testnet:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,6 @@ function(get_linux_lsb_release_information)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
find_package(cppzmq)
|
|
||||||
target_link_libraries(cppzmq)
|
|
||||||
|
|
||||||
get_linux_lsb_release_information()
|
get_linux_lsb_release_information()
|
||||||
message(STATUS "Linux ${LSB_RELEASE_ID_SHORT} ${LSB_RELEASE_VERSION_SHORT} ${LSB_RELEASE_CODENAME_SHORT}")
|
message(STATUS "Linux ${LSB_RELEASE_ID_SHORT} ${LSB_RELEASE_VERSION_SHORT} ${LSB_RELEASE_CODENAME_SHORT}")
|
||||||
string(REGEX MATCHALL "([0-9]+)" arg_list ${LSB_RELEASE_VERSION_SHORT})
|
string(REGEX MATCHALL "([0-9]+)" arg_list ${LSB_RELEASE_VERSION_SHORT})
|
||||||
|
|
@ -83,6 +80,11 @@ endmacro()
|
||||||
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS "ON")
|
set(CMAKE_EXPORT_COMPILE_COMMANDS "ON")
|
||||||
|
|
||||||
|
if(NOT DEFINED DISABLE_PEERPLAYS_SIDECHAIN_PLUGIN)
|
||||||
|
add_definitions(-DBUILD_PEERPLAYS_SIDECHAIN_PLUGIN=1)
|
||||||
|
message ("\n====================\nBuilding with Sidechain Plugin\n====================\n")
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (BUILD_PEERPLAYS_TESTNET)
|
if (BUILD_PEERPLAYS_TESTNET)
|
||||||
set(GRAPHENE_EGENESIS_JSON "${CMAKE_CURRENT_SOURCE_DIR}/genesis-testnet.json" CACHE PATH "location of the genesis.json to embed in the executable" )
|
set(GRAPHENE_EGENESIS_JSON "${CMAKE_CURRENT_SOURCE_DIR}/genesis-testnet.json" CACHE PATH "location of the genesis.json to embed in the executable" )
|
||||||
#add_compile_definitions(BUILD_PEERPLAYS_TESTNET=1)
|
#add_compile_definitions(BUILD_PEERPLAYS_TESTNET=1)
|
||||||
|
|
@ -285,3 +287,5 @@ unset(GRAPHENE_EGENESIS_JSON)
|
||||||
unset(GRAPHENE_EGENESIS_JSON CACHE)
|
unset(GRAPHENE_EGENESIS_JSON CACHE)
|
||||||
unset(BUILD_PEERPLAYS_TESTNET)
|
unset(BUILD_PEERPLAYS_TESTNET)
|
||||||
unset(BUILD_PEERPLAYS_TESTNET CACHE)
|
unset(BUILD_PEERPLAYS_TESTNET CACHE)
|
||||||
|
unset(DISABLE_PEERPLAYS_SIDECHAIN_PLUGIN)
|
||||||
|
unset(DISABLE_PEERPLAYS_SIDECHAIN_PLUGIN CACHE)
|
||||||
|
|
|
||||||
38
README.md
38
README.md
|
|
@ -114,10 +114,42 @@ cd peerplays
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
|
|
||||||
# If you want to build Mainnet node
|
# If you want to build Mainnet node
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||||
|
|
||||||
# If you want to build Testnet node
|
# If you want to build Testnet node
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_PEERPLAYS_TESTNET=1
|
mkdir build-testnet
|
||||||
|
cd build-testnet
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_PEERPLAYS_TESTNET=1 ..
|
||||||
|
|
||||||
|
# Update -j flag depending on your current system specs;
|
||||||
|
# Recommended 4GB of RAM per 1 CPU core
|
||||||
|
# make -j2 for 8GB RAM
|
||||||
|
# make -j4 for 16GB RAM
|
||||||
|
# make -j8 for 32GB RAM
|
||||||
|
make -j$(nproc)
|
||||||
|
|
||||||
|
sudo make install # this can install the executable files under /usr/local
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building without support for sidechain plugin
|
||||||
|
|
||||||
|
Building Peerplays
|
||||||
|
```
|
||||||
|
git clone https://gitlab.com/PBSA/peerplays.git
|
||||||
|
cd peerplays
|
||||||
|
git submodule update --init --recursive
|
||||||
|
|
||||||
|
# If you want to build Mainnet node
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release -DDISABLE_PEERPLAYS_SIDECHAIN_PLUGIN=1 ..
|
||||||
|
|
||||||
|
# If you want to build Testnet node
|
||||||
|
mkdir build-testnet
|
||||||
|
cd build-testnet
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_PEERPLAYS_TESTNET=1 -DDISABLE_PEERPLAYS_SIDECHAIN_PLUGIN=1 ..
|
||||||
|
|
||||||
# Update -j flag depending on your current system specs;
|
# Update -j flag depending on your current system specs;
|
||||||
# Recommended 4GB of RAM per 1 CPU core
|
# Recommended 4GB of RAM per 1 CPU core
|
||||||
|
|
@ -143,7 +175,7 @@ sudo usermod -a -G docker $USER
|
||||||
### Official docker image for Peerplas Mainnet
|
### Official docker image for Peerplas Mainnet
|
||||||
|
|
||||||
```
|
```
|
||||||
docker pull datasecuritynode/peerplays:latest
|
docker pull peerplays/peerplays:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building docker images manually
|
### Building docker images manually
|
||||||
|
|
|
||||||
10887
genesis-testnet.json
10887
genesis-testnet.json
File diff suppressed because it is too large
Load diff
|
|
@ -13,9 +13,13 @@ add_library( graphene_app
|
||||||
|
|
||||||
# need to link graphene_debug_witness because plugins aren't sufficiently isolated #246
|
# need to link graphene_debug_witness because plugins aren't sufficiently isolated #246
|
||||||
#target_link_libraries( graphene_app graphene_market_history graphene_account_history graphene_chain fc graphene_db graphene_net graphene_utilities graphene_debug_witness )
|
#target_link_libraries( graphene_app graphene_market_history graphene_account_history graphene_chain fc graphene_db graphene_net graphene_utilities graphene_debug_witness )
|
||||||
target_link_libraries( graphene_app
|
set(LIBRARIES graphene_net graphene_utilities graphene_account_history graphene_accounts_list graphene_affiliate_stats graphene_bookie graphene_debug_witness graphene_elasticsearch graphene_es_objects graphene_generate_genesis graphene_market_history)
|
||||||
PUBLIC graphene_net graphene_utilities
|
|
||||||
graphene_account_history graphene_accounts_list graphene_affiliate_stats graphene_bookie graphene_debug_witness graphene_elasticsearch graphene_es_objects graphene_generate_genesis graphene_market_history peerplays_sidechain )
|
if(NOT DEFINED DISABLE_PEERPLAYS_SIDECHAIN_PLUGIN)
|
||||||
|
list(APPEND LIBRARIES peerplays_sidechain)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries( graphene_app PUBLIC ${LIBRARIES} )
|
||||||
|
|
||||||
target_include_directories( graphene_app
|
target_include_directories( graphene_app
|
||||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
|
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||||
|
|
|
||||||
|
|
@ -103,11 +103,15 @@ void login_api::enable_api(const std::string &api_name) {
|
||||||
// can only enable this API if the plugin was loaded
|
// can only enable this API if the plugin was loaded
|
||||||
if (_app.get_plugin("affiliate_stats"))
|
if (_app.get_plugin("affiliate_stats"))
|
||||||
_affiliate_stats_api = std::make_shared<graphene::affiliate_stats::affiliate_stats_api>(std::ref(_app));
|
_affiliate_stats_api = std::make_shared<graphene::affiliate_stats::affiliate_stats_api>(std::ref(_app));
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
} else if (api_name == "sidechain_api") {
|
} else if (api_name == "sidechain_api") {
|
||||||
// can only enable this API if the plugin was loaded
|
// can only enable this API if the plugin was loaded
|
||||||
if (_app.get_plugin("peerplays_sidechain"))
|
if (_app.get_plugin("peerplays_sidechain"))
|
||||||
_sidechain_api = std::make_shared<graphene::peerplays_sidechain::sidechain_api>(std::ref(_app));
|
_sidechain_api = std::make_shared<graphene::peerplays_sidechain::sidechain_api>(std::ref(_app));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,8 +214,8 @@ network_node_api::network_node_api(application &a) :
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove expired transactions from pending_transactions
|
* Remove expired transactions from pending_transactions
|
||||||
*/
|
*/
|
||||||
for (const auto &transaction : _pending_transactions) {
|
for (const auto &transaction : _pending_transactions) {
|
||||||
if (transaction.second.expiration < block.timestamp) {
|
if (transaction.second.expiration < block.timestamp) {
|
||||||
auto transaction_it = _pending_transactions.find(transaction.second.id());
|
auto transaction_it = _pending_transactions.find(transaction.second.id());
|
||||||
|
|
@ -306,10 +310,12 @@ fc::api<graphene::affiliate_stats::affiliate_stats_api> login_api::affiliate_sta
|
||||||
return *_affiliate_stats_api;
|
return *_affiliate_stats_api;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
fc::api<graphene::peerplays_sidechain::sidechain_api> login_api::sidechain() const {
|
fc::api<graphene::peerplays_sidechain::sidechain_api> login_api::sidechain() const {
|
||||||
FC_ASSERT(_sidechain_api);
|
FC_ASSERT(_sidechain_api);
|
||||||
return *_sidechain_api;
|
return *_sidechain_api;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
vector<order_history_object> history_api::get_fill_order_history(std::string asset_a, std::string asset_b, uint32_t limit) const {
|
vector<order_history_object> history_api::get_fill_order_history(std::string asset_a, std::string asset_b, uint32_t limit) const {
|
||||||
FC_ASSERT(_app.chain_database());
|
FC_ASSERT(_app.chain_database());
|
||||||
|
|
@ -366,10 +372,9 @@ vector<operation_history_object> history_api::get_account_history(const std::str
|
||||||
_app.elasticsearch_thread = std::make_shared<fc::thread>("elasticsearch");
|
_app.elasticsearch_thread = std::make_shared<fc::thread>("elasticsearch");
|
||||||
|
|
||||||
return _app.elasticsearch_thread->async([&es, &account, &stop, &limit, &start]() {
|
return _app.elasticsearch_thread->async([&es, &account, &stop, &limit, &start]() {
|
||||||
return es->get_account_history(account, stop, limit, start);
|
return es->get_account_history(account, stop, limit, start);
|
||||||
},
|
},
|
||||||
"thread invoke for method " BOOST_PP_STRINGIZE(method_name))
|
"thread invoke for method " BOOST_PP_STRINGIZE(method_name)).wait();
|
||||||
.wait();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -391,8 +391,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If delegate has the item, the network has no need to fetch it.
|
* If delegate has the item, the network has no need to fetch it.
|
||||||
*/
|
*/
|
||||||
virtual bool has_item(const net::item_id &id) override {
|
virtual bool has_item(const net::item_id &id) override {
|
||||||
try {
|
try {
|
||||||
if (id.item_type == graphene::net::block_message_type)
|
if (id.item_type == graphene::net::block_message_type)
|
||||||
|
|
@ -404,13 +404,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief allows the application to validate an item prior to broadcasting to peers.
|
* @brief allows the application to validate an item prior to broadcasting to peers.
|
||||||
*
|
*
|
||||||
* @param sync_mode true if the message was fetched through the sync process, false during normal operation
|
* @param sync_mode true if the message was fetched through the sync process, false during normal operation
|
||||||
* @returns true if this message caused the blockchain to switch forks, false if it did not
|
* @returns true if this message caused the blockchain to switch forks, false if it did not
|
||||||
*
|
*
|
||||||
* @throws exception if error validating the item, otherwise the item is safe to broadcast on.
|
* @throws exception if error validating the item, otherwise the item is safe to broadcast on.
|
||||||
*/
|
*/
|
||||||
virtual bool handle_block(const graphene::net::block_message &blk_msg, bool sync_mode,
|
virtual bool handle_block(const graphene::net::block_message &blk_msg, bool sync_mode,
|
||||||
std::vector<fc::uint160_t> &contained_transaction_message_ids) override {
|
std::vector<fc::uint160_t> &contained_transaction_message_ids) override {
|
||||||
|
|
||||||
|
|
@ -498,14 +498,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assuming all data elements are ordered in some way, this method should
|
* Assuming all data elements are ordered in some way, this method should
|
||||||
* return up to limit ids that occur *after* the last ID in synopsis that
|
* return up to limit ids that occur *after* the last ID in synopsis that
|
||||||
* we recognize.
|
* we recognize.
|
||||||
*
|
*
|
||||||
* On return, remaining_item_count will be set to the number of items
|
* On return, remaining_item_count will be set to the number of items
|
||||||
* in our blockchain after the last item returned in the result,
|
* in our blockchain after the last item returned in the result,
|
||||||
* or 0 if the result contains the last item in the blockchain
|
* or 0 if the result contains the last item in the blockchain
|
||||||
*/
|
*/
|
||||||
virtual std::vector<item_hash_t> get_block_ids(const std::vector<item_hash_t> &blockchain_synopsis,
|
virtual std::vector<item_hash_t> get_block_ids(const std::vector<item_hash_t> &blockchain_synopsis,
|
||||||
uint32_t &remaining_item_count,
|
uint32_t &remaining_item_count,
|
||||||
uint32_t limit) override {
|
uint32_t limit) override {
|
||||||
|
|
@ -552,8 +552,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the hash of the requested data, fetch the body.
|
* Given the hash of the requested data, fetch the body.
|
||||||
*/
|
*/
|
||||||
virtual message get_item(const item_id &id) override {
|
virtual message get_item(const item_id &id) override {
|
||||||
try {
|
try {
|
||||||
// ilog("Request for item ${id}", ("id", id));
|
// ilog("Request for item ${id}", ("id", id));
|
||||||
|
|
@ -576,63 +576,63 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a synopsis of the blockchain used for syncing. This consists of a list of
|
* Returns a synopsis of the blockchain used for syncing. This consists of a list of
|
||||||
* block hashes at intervals exponentially increasing towards the genesis block.
|
* block hashes at intervals exponentially increasing towards the genesis block.
|
||||||
* When syncing to a peer, the peer uses this data to determine if we're on the same
|
* When syncing to a peer, the peer uses this data to determine if we're on the same
|
||||||
* fork as they are, and if not, what blocks they need to send us to get us on their
|
* fork as they are, and if not, what blocks they need to send us to get us on their
|
||||||
* fork.
|
* fork.
|
||||||
*
|
*
|
||||||
* In the over-simplified case, this is a straighforward synopsis of our current
|
* In the over-simplified case, this is a straighforward synopsis of our current
|
||||||
* preferred blockchain; when we first connect up to a peer, this is what we will be sending.
|
* preferred blockchain; when we first connect up to a peer, this is what we will be sending.
|
||||||
* It looks like this:
|
* It looks like this:
|
||||||
* If the blockchain is empty, it will return the empty list.
|
* If the blockchain is empty, it will return the empty list.
|
||||||
* If the blockchain has one block, it will return a list containing just that block.
|
* If the blockchain has one block, it will return a list containing just that block.
|
||||||
* If it contains more than one block:
|
* If it contains more than one block:
|
||||||
* the first element in the list will be the hash of the highest numbered block that
|
* the first element in the list will be the hash of the highest numbered block that
|
||||||
* we cannot undo
|
* we cannot undo
|
||||||
* the second element will be the hash of an item at the half way point in the undoable
|
* the second element will be the hash of an item at the half way point in the undoable
|
||||||
* segment of the blockchain
|
* segment of the blockchain
|
||||||
* the third will be ~3/4 of the way through the undoable segment of the block chain
|
* the third will be ~3/4 of the way through the undoable segment of the block chain
|
||||||
* the fourth will be at ~7/8...
|
* the fourth will be at ~7/8...
|
||||||
* &c.
|
* &c.
|
||||||
* the last item in the list will be the hash of the most recent block on our preferred chain
|
* the last item in the list will be the hash of the most recent block on our preferred chain
|
||||||
* so if the blockchain had 26 blocks labeled a - z, the synopsis would be:
|
* so if the blockchain had 26 blocks labeled a - z, the synopsis would be:
|
||||||
* a n u x z
|
* a n u x z
|
||||||
* the idea being that by sending a small (<30) number of block ids, we can summarize a huge
|
* the idea being that by sending a small (<30) number of block ids, we can summarize a huge
|
||||||
* blockchain. The block ids are more dense near the end of the chain where because we are
|
* blockchain. The block ids are more dense near the end of the chain where because we are
|
||||||
* more likely to be almost in sync when we first connect, and forks are likely to be short.
|
* more likely to be almost in sync when we first connect, and forks are likely to be short.
|
||||||
* If the peer we're syncing with in our example is on a fork that started at block 'v',
|
* If the peer we're syncing with in our example is on a fork that started at block 'v',
|
||||||
* then they will reply to our synopsis with a list of all blocks starting from block 'u',
|
* then they will reply to our synopsis with a list of all blocks starting from block 'u',
|
||||||
* the last block they know that we had in common.
|
* the last block they know that we had in common.
|
||||||
*
|
*
|
||||||
* In the real code, there are several complications.
|
* In the real code, there are several complications.
|
||||||
*
|
*
|
||||||
* First, as an optimization, we don't usually send a synopsis of the entire blockchain, we
|
* First, as an optimization, we don't usually send a synopsis of the entire blockchain, we
|
||||||
* send a synopsis of only the segment of the blockchain that we have undo data for. If their
|
* send a synopsis of only the segment of the blockchain that we have undo data for. If their
|
||||||
* fork doesn't build off of something in our undo history, we would be unable to switch, so there's
|
* fork doesn't build off of something in our undo history, we would be unable to switch, so there's
|
||||||
* no reason to fetch the blocks.
|
* no reason to fetch the blocks.
|
||||||
*
|
*
|
||||||
* Second, when a peer replies to our initial synopsis and gives us a list of the blocks they think
|
* Second, when a peer replies to our initial synopsis and gives us a list of the blocks they think
|
||||||
* we are missing, they only send a chunk of a few thousand blocks at once. After we get those
|
* we are missing, they only send a chunk of a few thousand blocks at once. After we get those
|
||||||
* block ids, we need to request more blocks by sending another synopsis (we can't just say "send me
|
* block ids, we need to request more blocks by sending another synopsis (we can't just say "send me
|
||||||
* the next 2000 ids" because they may have switched forks themselves and they don't track what
|
* the next 2000 ids" because they may have switched forks themselves and they don't track what
|
||||||
* they've sent us). For faster performance, we want to get a fairly long list of block ids first,
|
* they've sent us). For faster performance, we want to get a fairly long list of block ids first,
|
||||||
* then start downloading the blocks.
|
* then start downloading the blocks.
|
||||||
* The peer doesn't handle these follow-up block id requests any different from the initial request;
|
* The peer doesn't handle these follow-up block id requests any different from the initial request;
|
||||||
* it treats the synopsis we send as our blockchain and bases its response entirely off that. So to
|
* it treats the synopsis we send as our blockchain and bases its response entirely off that. So to
|
||||||
* get the response we want (the next chunk of block ids following the last one they sent us, or,
|
* get the response we want (the next chunk of block ids following the last one they sent us, or,
|
||||||
* failing that, the shortest fork off of the last list of block ids they sent), we need to construct
|
* failing that, the shortest fork off of the last list of block ids they sent), we need to construct
|
||||||
* a synopsis as if our blockchain was made up of:
|
* a synopsis as if our blockchain was made up of:
|
||||||
* 1. the blocks in our block chain up to the fork point (if there is a fork) or the head block (if no fork)
|
* 1. the blocks in our block chain up to the fork point (if there is a fork) or the head block (if no fork)
|
||||||
* 2. the blocks we've already pushed from their fork (if there's a fork)
|
* 2. the blocks we've already pushed from their fork (if there's a fork)
|
||||||
* 3. the block ids they've previously sent us
|
* 3. the block ids they've previously sent us
|
||||||
* Segment 3 is handled in the p2p code, it just tells us the number of blocks it has (in
|
* Segment 3 is handled in the p2p code, it just tells us the number of blocks it has (in
|
||||||
* number_of_blocks_after_reference_point) so we can leave space in the synopsis for them.
|
* number_of_blocks_after_reference_point) so we can leave space in the synopsis for them.
|
||||||
* We're responsible for constructing the synopsis of Segments 1 and 2 from our active blockchain and
|
* We're responsible for constructing the synopsis of Segments 1 and 2 from our active blockchain and
|
||||||
* fork database. The reference_point parameter is the last block from that peer that has been
|
* fork database. The reference_point parameter is the last block from that peer that has been
|
||||||
* successfully pushed to the blockchain, so that tells us whether the peer is on a fork or on
|
* successfully pushed to the blockchain, so that tells us whether the peer is on a fork or on
|
||||||
* the main chain.
|
* the main chain.
|
||||||
*/
|
*/
|
||||||
virtual std::vector<item_hash_t> get_blockchain_synopsis(const item_hash_t &reference_point,
|
virtual std::vector<item_hash_t> get_blockchain_synopsis(const item_hash_t &reference_point,
|
||||||
uint32_t number_of_blocks_after_reference_point) override {
|
uint32_t number_of_blocks_after_reference_point) override {
|
||||||
try {
|
try {
|
||||||
|
|
@ -733,26 +733,26 @@ public:
|
||||||
low_block_num += (true_high_block_num - low_block_num + 2) / 2;
|
low_block_num += (true_high_block_num - low_block_num + 2) / 2;
|
||||||
} while (low_block_num <= high_block_num);
|
} while (low_block_num <= high_block_num);
|
||||||
|
|
||||||
//idump((synopsis));
|
// idump((synopsis));
|
||||||
return synopsis;
|
return synopsis;
|
||||||
}
|
}
|
||||||
FC_CAPTURE_AND_RETHROW()
|
FC_CAPTURE_AND_RETHROW()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this after the call to handle_message succeeds.
|
* Call this after the call to handle_message succeeds.
|
||||||
*
|
*
|
||||||
* @param item_type the type of the item we're synchronizing, will be the same as item passed to the sync_from() call
|
* @param item_type the type of the item we're synchronizing, will be the same as item passed to the sync_from() call
|
||||||
* @param item_count the number of items known to the node that haven't been sent to handle_item() yet.
|
* @param item_count the number of items known to the node that haven't been sent to handle_item() yet.
|
||||||
* After `item_count` more calls to handle_item(), the node will be in sync
|
* After `item_count` more calls to handle_item(), the node will be in sync
|
||||||
*/
|
*/
|
||||||
virtual void sync_status(uint32_t item_type, uint32_t item_count) override {
|
virtual void sync_status(uint32_t item_type, uint32_t item_count) override {
|
||||||
// any status reports to GUI go here
|
// any status reports to GUI go here
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call any time the number of connected peers changes.
|
* Call any time the number of connected peers changes.
|
||||||
*/
|
*/
|
||||||
virtual void connection_count_changed(uint32_t c) override {
|
virtual void connection_count_changed(uint32_t c) override {
|
||||||
// any status reports to GUI go here
|
// any status reports to GUI go here
|
||||||
}
|
}
|
||||||
|
|
@ -769,9 +769,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the time a block was produced (if block_id = 0, returns genesis time).
|
* Returns the time a block was produced (if block_id = 0, returns genesis time).
|
||||||
* If we don't know about the block, returns time_point_sec::min()
|
* If we don't know about the block, returns time_point_sec::min()
|
||||||
*/
|
*/
|
||||||
virtual fc::time_point_sec get_block_time(const item_hash_t &block_id) override {
|
virtual fc::time_point_sec get_block_time(const item_hash_t &block_id) override {
|
||||||
try {
|
try {
|
||||||
auto opt_block = _chain_db->fetch_block_by_id(block_id);
|
auto opt_block = _chain_db->fetch_block_by_id(block_id);
|
||||||
|
|
@ -836,6 +836,11 @@ void application::set_program_options(boost::program_options::options_descriptio
|
||||||
|
|
||||||
std::vector<string> seed_nodes = {
|
std::vector<string> seed_nodes = {
|
||||||
#ifdef BUILD_PEERPLAYS_TESTNET
|
#ifdef BUILD_PEERPLAYS_TESTNET
|
||||||
|
"134.209.113.44:19777",
|
||||||
|
"165.232.84.196:19777",
|
||||||
|
"24.199.104.149:19777",
|
||||||
|
"92.119.90.95:19777",
|
||||||
|
"test-api.i9networks.net.br:19777"
|
||||||
#else
|
#else
|
||||||
"51.222.110.110:9777",
|
"51.222.110.110:9777",
|
||||||
"95.216.90.243:9777",
|
"95.216.90.243:9777",
|
||||||
|
|
|
||||||
|
|
@ -313,7 +313,7 @@ public:
|
||||||
uint32_t api_limit_get_trade_history = 100;
|
uint32_t api_limit_get_trade_history = 100;
|
||||||
uint32_t api_limit_get_trade_history_by_sequence = 100;
|
uint32_t api_limit_get_trade_history_by_sequence = 100;
|
||||||
|
|
||||||
//private:
|
// private:
|
||||||
const account_object *get_account_from_string(const std::string &name_or_id,
|
const account_object *get_account_from_string(const std::string &name_or_id,
|
||||||
bool throw_if_not_found = true) const;
|
bool throw_if_not_found = true) const;
|
||||||
const asset_object *get_asset_from_string(const std::string &symbol_or_id,
|
const asset_object *get_asset_from_string(const std::string &symbol_or_id,
|
||||||
|
|
@ -470,7 +470,7 @@ void database_api::set_subscribe_callback(std::function<void(const variant &)> c
|
||||||
}
|
}
|
||||||
|
|
||||||
void database_api_impl::set_subscribe_callback(std::function<void(const variant &)> cb, bool notify_remove_create) {
|
void database_api_impl::set_subscribe_callback(std::function<void(const variant &)> cb, bool notify_remove_create) {
|
||||||
//edump((clear_filter));
|
// edump((clear_filter));
|
||||||
_subscribe_callback = cb;
|
_subscribe_callback = cb;
|
||||||
_notify_remove_create = notify_remove_create;
|
_notify_remove_create = notify_remove_create;
|
||||||
_subscribed_accounts.clear();
|
_subscribed_accounts.clear();
|
||||||
|
|
@ -2197,7 +2197,7 @@ vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &v
|
||||||
case vote_id_type::committee: {
|
case vote_id_type::committee: {
|
||||||
auto itr = committee_idx.find(id);
|
auto itr = committee_idx.find(id);
|
||||||
if (itr != committee_idx.end())
|
if (itr != committee_idx.end())
|
||||||
result.emplace_back(variant(*itr, 1));
|
result.emplace_back(variant(*itr, 2)); // Depth of committee_member_object is 1, add 1 to be safe
|
||||||
else
|
else
|
||||||
result.emplace_back(variant());
|
result.emplace_back(variant());
|
||||||
break;
|
break;
|
||||||
|
|
@ -2205,7 +2205,7 @@ vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &v
|
||||||
case vote_id_type::witness: {
|
case vote_id_type::witness: {
|
||||||
auto itr = witness_idx.find(id);
|
auto itr = witness_idx.find(id);
|
||||||
if (itr != witness_idx.end())
|
if (itr != witness_idx.end())
|
||||||
result.emplace_back(variant(*itr, 1));
|
result.emplace_back(variant(*itr, 2)); // Depth of witness_object is 1, add 1 here to be safe
|
||||||
else
|
else
|
||||||
result.emplace_back(variant());
|
result.emplace_back(variant());
|
||||||
break;
|
break;
|
||||||
|
|
@ -2213,11 +2213,15 @@ vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &v
|
||||||
case vote_id_type::worker: {
|
case vote_id_type::worker: {
|
||||||
auto itr = for_worker_idx.find(id);
|
auto itr = for_worker_idx.find(id);
|
||||||
if (itr != for_worker_idx.end()) {
|
if (itr != for_worker_idx.end()) {
|
||||||
result.emplace_back(variant(*itr, 1));
|
result.emplace_back(variant(*itr, 4)); // Depth of worker_object is 3, add 1 here to be safe.
|
||||||
|
// If we want to extract the balance object inside,
|
||||||
|
// need to increase this value
|
||||||
} else {
|
} else {
|
||||||
auto itr = against_worker_idx.find(id);
|
auto itr = against_worker_idx.find(id);
|
||||||
if (itr != against_worker_idx.end()) {
|
if (itr != against_worker_idx.end()) {
|
||||||
result.emplace_back(variant(*itr, 1));
|
result.emplace_back(variant(*itr, 4)); // Depth of worker_object is 3, add 1 here to be safe.
|
||||||
|
// If we want to extract the balance object inside,
|
||||||
|
// need to increase this value
|
||||||
} else {
|
} else {
|
||||||
result.emplace_back(variant());
|
result.emplace_back(variant());
|
||||||
}
|
}
|
||||||
|
|
@ -2903,7 +2907,7 @@ graphene::app::gpos_info database_api::get_gpos_info(const account_id_type accou
|
||||||
}
|
}
|
||||||
|
|
||||||
graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type account) const {
|
graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type account) const {
|
||||||
FC_ASSERT(_db.head_block_time() > HARDFORK_GPOS_TIME); //Can be deleted after GPOS hardfork time
|
FC_ASSERT(_db.head_block_time() > HARDFORK_GPOS_TIME); // Can be deleted after GPOS hardfork time
|
||||||
gpos_info result;
|
gpos_info result;
|
||||||
|
|
||||||
result.vesting_factor = _db.calculate_vesting_factor(account(_db));
|
result.vesting_factor = _db.calculate_vesting_factor(account(_db));
|
||||||
|
|
@ -3550,9 +3554,9 @@ void database_api_impl::handle_object_changed(bool force_notify, bool full_objec
|
||||||
/// pushing the future back / popping the prior future if it is complete.
|
/// pushing the future back / popping the prior future if it is complete.
|
||||||
/// if a connection hangs then this could get backed up and result in
|
/// if a connection hangs then this could get backed up and result in
|
||||||
/// a failure to exit cleanly.
|
/// a failure to exit cleanly.
|
||||||
//fc::async([capture_this,this,updates,market_broadcast_queue](){
|
// fc::async([capture_this,this,updates,market_broadcast_queue](){
|
||||||
//if( _subscribe_callback )
|
// if( _subscribe_callback )
|
||||||
// _subscribe_callback( updates );
|
// _subscribe_callback( updates );
|
||||||
|
|
||||||
for (auto id : ids) {
|
for (auto id : ids) {
|
||||||
if (id.is<call_order_object>()) {
|
if (id.is<call_order_object>()) {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,9 @@
|
||||||
#include <graphene/debug_witness/debug_api.hpp>
|
#include <graphene/debug_witness/debug_api.hpp>
|
||||||
#include <graphene/elasticsearch/elasticsearch_plugin.hpp>
|
#include <graphene/elasticsearch/elasticsearch_plugin.hpp>
|
||||||
#include <graphene/market_history/market_history_plugin.hpp>
|
#include <graphene/market_history/market_history_plugin.hpp>
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
#include <graphene/peerplays_sidechain/sidechain_api.hpp>
|
#include <graphene/peerplays_sidechain/sidechain_api.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <fc/api.hpp>
|
#include <fc/api.hpp>
|
||||||
#include <fc/crypto/elliptic.hpp>
|
#include <fc/crypto/elliptic.hpp>
|
||||||
|
|
@ -85,10 +87,10 @@ struct asset_holders {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The history_api class implements the RPC API for account history
|
* @brief The history_api class implements the RPC API for account history
|
||||||
*
|
*
|
||||||
* This API contains methods to access account histories
|
* This API contains methods to access account histories
|
||||||
*/
|
*/
|
||||||
class history_api {
|
class history_api {
|
||||||
public:
|
public:
|
||||||
history_api(application &app) :
|
history_api(application &app) :
|
||||||
|
|
@ -97,27 +99,27 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get operations relevant to the specificed account
|
* @brief Get operations relevant to the specificed account
|
||||||
* @param account_id_or_name The account ID or name whose history should be queried
|
* @param account_id_or_name The account ID or name whose history should be queried
|
||||||
* @param stop ID of the earliest operation to retrieve
|
* @param stop ID of the earliest operation to retrieve
|
||||||
* @param limit Maximum number of operations to retrieve (must not exceed 100)
|
* @param limit Maximum number of operations to retrieve (must not exceed 100)
|
||||||
* @param start ID of the most recent operation to retrieve
|
* @param start ID of the most recent operation to retrieve
|
||||||
* @return A list of operations performed by account, ordered from most recent to oldest.
|
* @return A list of operations performed by account, ordered from most recent to oldest.
|
||||||
*/
|
*/
|
||||||
vector<operation_history_object> get_account_history(const std::string account_id_or_name,
|
vector<operation_history_object> get_account_history(const std::string account_id_or_name,
|
||||||
operation_history_id_type stop = operation_history_id_type(),
|
operation_history_id_type stop = operation_history_id_type(),
|
||||||
unsigned limit = 100,
|
unsigned limit = 100,
|
||||||
operation_history_id_type start = operation_history_id_type()) const;
|
operation_history_id_type start = operation_history_id_type()) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get only asked operations relevant to the specified account
|
* @brief Get only asked operations relevant to the specified account
|
||||||
* @param account_id_or_name The account ID or name whose history should be queried
|
* @param account_id_or_name The account ID or name whose history should be queried
|
||||||
* @param operation_id The ID of the operation we want to get operations in the account( 0 = transfer , 1 = limit order create, ...)
|
* @param operation_id The ID of the operation we want to get operations in the account( 0 = transfer , 1 = limit order create, ...)
|
||||||
* @param stop ID of the earliest operation to retrieve
|
* @param stop ID of the earliest operation to retrieve
|
||||||
* @param limit Maximum number of operations to retrieve (must not exceed 100)
|
* @param limit Maximum number of operations to retrieve (must not exceed 100)
|
||||||
* @param start ID of the most recent operation to retrieve
|
* @param start ID of the most recent operation to retrieve
|
||||||
* @return A list of operations performed by account, ordered from most recent to oldest.
|
* @return A list of operations performed by account, ordered from most recent to oldest.
|
||||||
*/
|
*/
|
||||||
vector<operation_history_object> get_account_history_operations(const std::string account_id_or_name,
|
vector<operation_history_object> get_account_history_operations(const std::string account_id_or_name,
|
||||||
int operation_id,
|
int operation_id,
|
||||||
operation_history_id_type start = operation_history_id_type(),
|
operation_history_id_type start = operation_history_id_type(),
|
||||||
|
|
@ -125,17 +127,17 @@ public:
|
||||||
unsigned limit = 100) const;
|
unsigned limit = 100) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @breif Get operations relevant to the specified account referenced
|
* @breif Get operations relevant to the specified account referenced
|
||||||
* by an event numbering specific to the account. The current number of operations
|
* by an event numbering specific to the account. The current number of operations
|
||||||
* for the account can be found in the account statistics (or use 0 for start).
|
* for the account can be found in the account statistics (or use 0 for start).
|
||||||
* @param account_id_or_name The account ID or name whose history should be queried
|
* @param account_id_or_name The account ID or name whose history should be queried
|
||||||
* @param stop Sequence number of earliest operation. 0 is default and will
|
* @param stop Sequence number of earliest operation. 0 is default and will
|
||||||
* query 'limit' number of operations.
|
* query 'limit' number of operations.
|
||||||
* @param limit Maximum number of operations to retrieve (must not exceed 100)
|
* @param limit Maximum number of operations to retrieve (must not exceed 100)
|
||||||
* @param start Sequence number of the most recent operation to retrieve.
|
* @param start Sequence number of the most recent operation to retrieve.
|
||||||
* 0 is default, which will start querying from the most recent operation.
|
* 0 is default, which will start querying from the most recent operation.
|
||||||
* @return A list of operations performed by account, ordered from most recent to oldest.
|
* @return A list of operations performed by account, ordered from most recent to oldest.
|
||||||
*/
|
*/
|
||||||
vector<operation_history_object> get_relative_account_history(const std::string account_id_or_name,
|
vector<operation_history_object> get_relative_account_history(const std::string account_id_or_name,
|
||||||
uint32_t stop = 0,
|
uint32_t stop = 0,
|
||||||
unsigned limit = 100,
|
unsigned limit = 100,
|
||||||
|
|
@ -156,8 +158,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Block api
|
* @brief Block api
|
||||||
*/
|
*/
|
||||||
class block_api {
|
class block_api {
|
||||||
public:
|
public:
|
||||||
block_api(graphene::chain::database &db);
|
block_api(graphene::chain::database &db);
|
||||||
|
|
@ -170,8 +172,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The network_broadcast_api class allows broadcasting of transactions.
|
* @brief The network_broadcast_api class allows broadcasting of transactions.
|
||||||
*/
|
*/
|
||||||
class network_broadcast_api : public std::enable_shared_from_this<network_broadcast_api> {
|
class network_broadcast_api : public std::enable_shared_from_this<network_broadcast_api> {
|
||||||
public:
|
public:
|
||||||
network_broadcast_api(application &a);
|
network_broadcast_api(application &a);
|
||||||
|
|
@ -186,36 +188,36 @@ public:
|
||||||
typedef std::function<void(variant /*transaction_confirmation*/)> confirmation_callback;
|
typedef std::function<void(variant /*transaction_confirmation*/)> confirmation_callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Broadcast a transaction to the network
|
* @brief Broadcast a transaction to the network
|
||||||
* @param trx The transaction to broadcast
|
* @param trx The transaction to broadcast
|
||||||
*
|
*
|
||||||
* The transaction will be checked for validity in the local database prior to broadcasting. If it fails to
|
* The transaction will be checked for validity in the local database prior to broadcasting. If it fails to
|
||||||
* apply locally, an error will be thrown and the transaction will not be broadcast.
|
* apply locally, an error will be thrown and the transaction will not be broadcast.
|
||||||
*/
|
*/
|
||||||
void broadcast_transaction(const signed_transaction &trx);
|
void broadcast_transaction(const signed_transaction &trx);
|
||||||
|
|
||||||
/** this version of broadcast transaction registers a callback method that will be called when the transaction is
|
/** this version of broadcast transaction registers a callback method that will be called when the transaction is
|
||||||
* included into a block. The callback method includes the transaction id, block number, and transaction number in the
|
* included into a block. The callback method includes the transaction id, block number, and transaction number in the
|
||||||
* block.
|
* block.
|
||||||
*/
|
*/
|
||||||
void broadcast_transaction_with_callback(confirmation_callback cb, const signed_transaction &trx);
|
void broadcast_transaction_with_callback(confirmation_callback cb, const signed_transaction &trx);
|
||||||
|
|
||||||
/** this version of broadcast transaction registers a callback method that will be called when the transaction is
|
/** this version of broadcast transaction registers a callback method that will be called when the transaction is
|
||||||
* included into a block. The callback method includes the transaction id, block number, and transaction number in the
|
* included into a block. The callback method includes the transaction id, block number, and transaction number in the
|
||||||
* block.
|
* block.
|
||||||
*/
|
*/
|
||||||
fc::variant broadcast_transaction_synchronous(const signed_transaction &trx);
|
fc::variant broadcast_transaction_synchronous(const signed_transaction &trx);
|
||||||
|
|
||||||
void broadcast_block(const signed_block &block);
|
void broadcast_block(const signed_block &block);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Not reflected, thus not accessible to API clients.
|
* @brief Not reflected, thus not accessible to API clients.
|
||||||
*
|
*
|
||||||
* This function is registered to receive the applied_block
|
* This function is registered to receive the applied_block
|
||||||
* signal from the chain database when a block is received.
|
* signal from the chain database when a block is received.
|
||||||
* It then dispatches callbacks to clients who have requested
|
* It then dispatches callbacks to clients who have requested
|
||||||
* to be notified when a particular txid is included in a block.
|
* to be notified when a particular txid is included in a block.
|
||||||
*/
|
*/
|
||||||
void on_applied_block(const signed_block &b);
|
void on_applied_block(const signed_block &b);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -225,60 +227,60 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The network_node_api class allows maintenance of p2p connections.
|
* @brief The network_node_api class allows maintenance of p2p connections.
|
||||||
*/
|
*/
|
||||||
class network_node_api {
|
class network_node_api {
|
||||||
public:
|
public:
|
||||||
network_node_api(application &a);
|
network_node_api(application &a);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return general network information, such as p2p port
|
* @brief Return general network information, such as p2p port
|
||||||
*/
|
*/
|
||||||
fc::variant_object get_info() const;
|
fc::variant_object get_info() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief add_node Connect to a new peer
|
* @brief add_node Connect to a new peer
|
||||||
* @param ep The IP/Port of the peer to connect to
|
* @param ep The IP/Port of the peer to connect to
|
||||||
*/
|
*/
|
||||||
void add_node(const fc::ip::endpoint &ep);
|
void add_node(const fc::ip::endpoint &ep);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get status of all current connections to peers
|
* @brief Get status of all current connections to peers
|
||||||
*/
|
*/
|
||||||
std::vector<net::peer_status> get_connected_peers() const;
|
std::vector<net::peer_status> get_connected_peers() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get advanced node parameters, such as desired and max
|
* @brief Get advanced node parameters, such as desired and max
|
||||||
* number of connections
|
* number of connections
|
||||||
*/
|
*/
|
||||||
fc::variant_object get_advanced_node_parameters() const;
|
fc::variant_object get_advanced_node_parameters() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set advanced node parameters, such as desired and max
|
* @brief Set advanced node parameters, such as desired and max
|
||||||
* number of connections
|
* number of connections
|
||||||
* @param params a JSON object containing the name/value pairs for the parameters to set
|
* @param params a JSON object containing the name/value pairs for the parameters to set
|
||||||
*/
|
*/
|
||||||
void set_advanced_node_parameters(const fc::variant_object ¶ms);
|
void set_advanced_node_parameters(const fc::variant_object ¶ms);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return list of potential peers
|
* @brief Return list of potential peers
|
||||||
*/
|
*/
|
||||||
std::vector<net::potential_peer_record> get_potential_peers() const;
|
std::vector<net::potential_peer_record> get_potential_peers() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return list of pending transactions.
|
* @brief Return list of pending transactions.
|
||||||
*/
|
*/
|
||||||
map<transaction_id_type, signed_transaction> list_pending_transactions() const;
|
map<transaction_id_type, signed_transaction> list_pending_transactions() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Subscribes caller for notifications about pending transactions.
|
* @brief Subscribes caller for notifications about pending transactions.
|
||||||
* @param callback a functional object which will be called when new transaction is created.
|
* @param callback a functional object which will be called when new transaction is created.
|
||||||
*/
|
*/
|
||||||
void subscribe_to_pending_transactions(std::function<void(const variant &)> callback);
|
void subscribe_to_pending_transactions(std::function<void(const variant &)> callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unsubscribes caller from notifications about pending transactions.
|
* @brief Unsubscribes caller from notifications about pending transactions.
|
||||||
*/
|
*/
|
||||||
void unsubscribe_from_pending_transactions();
|
void unsubscribe_from_pending_transactions();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -290,33 +292,33 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*/
|
*/
|
||||||
class asset_api {
|
class asset_api {
|
||||||
public:
|
public:
|
||||||
asset_api(graphene::app::application &app);
|
asset_api(graphene::app::application &app);
|
||||||
~asset_api();
|
~asset_api();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get asset holders for a specific asset
|
* @brief Get asset holders for a specific asset
|
||||||
* @param asset The specific asset id or symbol
|
* @param asset The specific asset id or symbol
|
||||||
* @param start The start index
|
* @param start The start index
|
||||||
* @param limit Maximum limit must not exceed 100
|
* @param limit Maximum limit must not exceed 100
|
||||||
* @return A list of asset holders for the specified asset
|
* @return A list of asset holders for the specified asset
|
||||||
*/
|
*/
|
||||||
vector<account_asset_balance> get_asset_holders(std::string asset, uint32_t start, uint32_t limit) const;
|
vector<account_asset_balance> get_asset_holders(std::string asset, uint32_t start, uint32_t limit) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get asset holders count for a specific asset
|
* @brief Get asset holders count for a specific asset
|
||||||
* @param asset The specific asset id or symbol
|
* @param asset The specific asset id or symbol
|
||||||
* @return Holders count for the specified asset
|
* @return Holders count for the specified asset
|
||||||
*/
|
*/
|
||||||
int get_asset_holders_count(std::string asset) const;
|
int get_asset_holders_count(std::string asset) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get all asset holders
|
* @brief Get all asset holders
|
||||||
* @return A list of all asset holders
|
* @return A list of all asset holders
|
||||||
*/
|
*/
|
||||||
vector<asset_holders> get_all_asset_holders() const;
|
vector<asset_holders> get_all_asset_holders() const;
|
||||||
|
|
||||||
uint32_t api_limit_get_asset_holders = 100;
|
uint32_t api_limit_get_asset_holders = 100;
|
||||||
|
|
@ -337,24 +339,24 @@ extern template class fc::api<graphene::debug_witness::debug_api>;
|
||||||
|
|
||||||
namespace graphene { namespace app {
|
namespace graphene { namespace app {
|
||||||
/**
|
/**
|
||||||
* @brief The login_api class implements the bottom layer of the RPC API
|
* @brief The login_api class implements the bottom layer of the RPC API
|
||||||
*
|
*
|
||||||
* All other APIs must be requested from this API.
|
* All other APIs must be requested from this API.
|
||||||
*/
|
*/
|
||||||
class login_api {
|
class login_api {
|
||||||
public:
|
public:
|
||||||
login_api(application &a);
|
login_api(application &a);
|
||||||
~login_api();
|
~login_api();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Authenticate to the RPC server
|
* @brief Authenticate to the RPC server
|
||||||
* @param user Username to login with
|
* @param user Username to login with
|
||||||
* @param password Password to login with
|
* @param password Password to login with
|
||||||
* @return True if logged in successfully; false otherwise
|
* @return True if logged in successfully; false otherwise
|
||||||
*
|
*
|
||||||
* @note This must be called prior to requesting other APIs. Other APIs may not be accessible until the client
|
* @note This must be called prior to requesting other APIs. Other APIs may not be accessible until the client
|
||||||
* has sucessfully authenticated.
|
* has sucessfully authenticated.
|
||||||
*/
|
*/
|
||||||
bool login(const string &user, const string &password);
|
bool login(const string &user, const string &password);
|
||||||
/// @brief Retrieve the network block API
|
/// @brief Retrieve the network block API
|
||||||
fc::api<block_api> block() const;
|
fc::api<block_api> block() const;
|
||||||
|
|
@ -375,7 +377,9 @@ public:
|
||||||
/// @brief Retrieve the affiliate_stats API (if available)
|
/// @brief Retrieve the affiliate_stats API (if available)
|
||||||
fc::api<graphene::affiliate_stats::affiliate_stats_api> affiliate_stats() const;
|
fc::api<graphene::affiliate_stats::affiliate_stats_api> affiliate_stats() const;
|
||||||
/// @brief Retrieve the sidechain_api API (if available)
|
/// @brief Retrieve the sidechain_api API (if available)
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
fc::api<graphene::peerplays_sidechain::sidechain_api> sidechain() const;
|
fc::api<graphene::peerplays_sidechain::sidechain_api> sidechain() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief Called to enable an API, not reflected.
|
/// @brief Called to enable an API, not reflected.
|
||||||
void enable_api(const string &api_name);
|
void enable_api(const string &api_name);
|
||||||
|
|
@ -391,7 +395,9 @@ private:
|
||||||
optional<fc::api<graphene::debug_witness::debug_api>> _debug_api;
|
optional<fc::api<graphene::debug_witness::debug_api>> _debug_api;
|
||||||
optional<fc::api<graphene::bookie::bookie_api>> _bookie_api;
|
optional<fc::api<graphene::bookie::bookie_api>> _bookie_api;
|
||||||
optional<fc::api<graphene::affiliate_stats::affiliate_stats_api>> _affiliate_stats_api;
|
optional<fc::api<graphene::affiliate_stats::affiliate_stats_api>> _affiliate_stats_api;
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
optional<fc::api<graphene::peerplays_sidechain::sidechain_api>> _sidechain_api;
|
optional<fc::api<graphene::peerplays_sidechain::sidechain_api>> _sidechain_api;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace graphene::app
|
}} // namespace graphene::app
|
||||||
|
|
@ -460,6 +466,9 @@ FC_API(graphene::app::login_api,
|
||||||
(debug)
|
(debug)
|
||||||
(bookie)
|
(bookie)
|
||||||
(affiliate_stats)
|
(affiliate_stats)
|
||||||
(sidechain))
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
|
(sidechain)
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
|
||||||
|
|
@ -198,10 +198,10 @@ public:
|
||||||
optional<block_header> get_block_header(uint32_t block_num) const;
|
optional<block_header> get_block_header(uint32_t block_num) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieve multiple block header by block numbers
|
* @brief Retrieve multiple block header by block numbers
|
||||||
* @param block_num vector containing heights of the block whose header should be returned
|
* @param block_num vector containing heights of the block whose header should be returned
|
||||||
* @return array of headers of the referenced blocks, or null if no matching block was found
|
* @return array of headers of the referenced blocks, or null if no matching block was found
|
||||||
*/
|
*/
|
||||||
map<uint32_t, optional<block_header>> get_block_header_batch(const vector<uint32_t> block_nums) const;
|
map<uint32_t, optional<block_header>> get_block_header_batch(const vector<uint32_t> block_nums) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -279,12 +279,12 @@ public:
|
||||||
vector<vector<account_id_type>> get_key_references(vector<public_key_type> key) const;
|
vector<vector<account_id_type>> get_key_references(vector<public_key_type> key) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether a textual representation of a public key
|
* Determine whether a textual representation of a public key
|
||||||
* (in Base-58 format) is *currently* linked
|
* (in Base-58 format) is *currently* linked
|
||||||
* to any *registered* (i.e. non-stealth) account on the blockchain
|
* to any *registered* (i.e. non-stealth) account on the blockchain
|
||||||
* @param public_key Public key
|
* @param public_key Public key
|
||||||
* @return Whether a public key is known
|
* @return Whether a public key is known
|
||||||
*/
|
*/
|
||||||
bool is_public_key_registered(string public_key) const;
|
bool is_public_key_registered(string public_key) const;
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
|
|
|
||||||
|
|
@ -386,23 +386,14 @@ vector<uint64_t> database::get_random_numbers(uint64_t minimum, uint64_t maximum
|
||||||
|
|
||||||
bool database::is_asset_creation_allowed(const string &symbol)
|
bool database::is_asset_creation_allowed(const string &symbol)
|
||||||
{
|
{
|
||||||
time_point_sec now = head_block_time();
|
|
||||||
std::unordered_set<std::string> post_son_hf_symbols = {"ETH", "USDT", "BNB", "ADA", "DOGE", "XRP", "USDC", "DOT", "UNI", "BUSD", "BCH", "LTC", "SOL", "LINK", "MATIC", "THETA",
|
|
||||||
"WBTC", "XLM", "ICP", "DAI", "VET", "ETC", "TRX", "FIL", "XMR", "EGR", "EOS", "SHIB", "AAVE", "CRO", "ALGO", "AMP", "BTCB",
|
|
||||||
"BSV", "KLAY", "CAKE", "FTT", "LEO", "XTZ", "TFUEL", "MIOTA", "LUNA", "NEO", "ATOM", "MKR", "FEI", "WBNB", "UST", "AVAX",
|
|
||||||
"STEEM", "HIVE", "HBD", "SBD", "BTS"};
|
|
||||||
if (symbol == "BTC")
|
if (symbol == "BTC")
|
||||||
{
|
{
|
||||||
if (now < HARDFORK_SON_TIME)
|
if (head_block_time() < HARDFORK_SON_TIME)
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (post_son_hf_symbols.find(symbol) != post_son_hf_symbols.end())
|
|
||||||
{
|
|
||||||
if (now >= HARDFORK_SON_TIME)
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} }
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,6 @@
|
||||||
#ifdef BUILD_PEERPLAYS_TESTNET
|
#ifdef BUILD_PEERPLAYS_TESTNET
|
||||||
#define HARDFORK_SON_FOR_ETHEREUM_TIME (fc::time_point_sec::from_iso_string("2023-07-17T12:00:00"))
|
#define HARDFORK_SON_FOR_ETHEREUM_TIME (fc::time_point_sec::from_iso_string("2023-07-17T12:00:00"))
|
||||||
#else
|
#else
|
||||||
#define HARDFORK_SON_FOR_ETHEREUM_TIME (fc::time_point_sec::from_iso_string("2023-07-31T12:00:00"))
|
#define HARDFORK_SON_FOR_ETHEREUM_TIME (fc::time_point_sec::from_iso_string("2023-10-24T12:00:00"))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ add_subdirectory( es_objects )
|
||||||
add_subdirectory( generate_genesis )
|
add_subdirectory( generate_genesis )
|
||||||
add_subdirectory( generate_uia_sharedrop_genesis )
|
add_subdirectory( generate_uia_sharedrop_genesis )
|
||||||
add_subdirectory( market_history )
|
add_subdirectory( market_history )
|
||||||
add_subdirectory( peerplays_sidechain )
|
if(NOT DEFINED DISABLE_PEERPLAYS_SIDECHAIN_PLUGIN)
|
||||||
|
add_subdirectory( peerplays_sidechain )
|
||||||
|
endif ()
|
||||||
add_subdirectory( snapshot )
|
add_subdirectory( snapshot )
|
||||||
add_subdirectory( witness )
|
add_subdirectory( witness )
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,14 @@ add_library( graphene_delayed_node
|
||||||
delayed_node_plugin.cpp
|
delayed_node_plugin.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries( graphene_delayed_node PRIVATE graphene_plugin graphene_accounts_list graphene_affiliate_stats graphene_bookie graphene_debug_witness graphene_elasticsearch graphene_market_history peerplays_sidechain )
|
set(LIBRARIES graphene_plugin graphene_accounts_list graphene_affiliate_stats graphene_bookie graphene_debug_witness graphene_elasticsearch graphene_market_history)
|
||||||
|
|
||||||
|
if(NOT DEFINED DISABLE_PEERPLAYS_SIDECHAIN_PLUGIN)
|
||||||
|
list(APPEND LIBRARIES peerplays_sidechain)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries( graphene_delayed_node PRIVATE ${LIBRARIES} )
|
||||||
|
|
||||||
target_include_directories( graphene_delayed_node
|
target_include_directories( graphene_delayed_node
|
||||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
file(GLOB_RECURSE HEADERS "include/graphene/peerplays_sidechain/*.hpp")
|
file(GLOB_RECURSE HEADERS "include/graphene/peerplays_sidechain/*.hpp")
|
||||||
|
|
||||||
|
find_package(cppzmq)
|
||||||
|
target_link_libraries(cppzmq)
|
||||||
|
|
||||||
add_library( peerplays_sidechain
|
add_library( peerplays_sidechain
|
||||||
peerplays_sidechain_plugin.cpp
|
peerplays_sidechain_plugin.cpp
|
||||||
sidechain_api.cpp
|
sidechain_api.cpp
|
||||||
|
|
@ -44,7 +47,7 @@ endif()
|
||||||
unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS)
|
unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS)
|
||||||
unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS CACHE)
|
unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS CACHE)
|
||||||
|
|
||||||
target_link_libraries( peerplays_sidechain PRIVATE curl graphene_plugin sha3 zmq bitcoin-system bitcoin-protocol bitcoin-client bitcoin-explorer )
|
target_link_libraries( peerplays_sidechain PRIVATE curl graphene_plugin sha3 zmq cppzmq bitcoin-system bitcoin-protocol bitcoin-client bitcoin-explorer )
|
||||||
target_include_directories( peerplays_sidechain
|
target_include_directories( peerplays_sidechain
|
||||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ void bitcoin_transaction_builder::add_in(payment_type type, tx_in txin, const by
|
||||||
txin.scriptSig = script_code;
|
txin.scriptSig = script_code;
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
if (txin.prevout.hash == fc::sha256("0000000000000000000000000000000000000000000000000000000000000000")) { //coinbase
|
if (txin.prevout.hash == fc::sha256("0000000000000000000000000000000000000000000000000000000000000000")) { // coinbase
|
||||||
FC_ASSERT(script_code != bytes());
|
FC_ASSERT(script_code != bytes());
|
||||||
txin.scriptSig = script_code;
|
txin.scriptSig = script_code;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain {
|
namespace graphene { namespace peerplays_sidechain {
|
||||||
|
|
||||||
libbitcoin_client::libbitcoin_client(std::string url) :
|
libbitcoin_client::libbitcoin_client(const std::string &url) :
|
||||||
obelisk_client(LIBBITCOIN_SERVER_TIMEOUT, LIBBITCOIN_SERVER_RETRIES) {
|
obelisk_client(LIBBITCOIN_SERVER_TIMEOUT, LIBBITCOIN_SERVER_RETRIES) {
|
||||||
|
|
||||||
std::string reg_expr = "^((?P<Protocol>https|http|tcp):\\/\\/)?(?P<Host>[a-zA-Z0-9\\-\\.]+)(:(?P<Port>\\d{1,5}))?(?P<Target>\\/.+)?";
|
const std::string reg_expr = "^((?P<Protocol>https|http|tcp):\\/\\/)?(?P<Host>[a-zA-Z0-9\\-\\.]+)(:(?P<Port>\\d{1,5}))?(?P<Target>\\/.+)?";
|
||||||
boost::xpressive::sregex sr = boost::xpressive::sregex::compile(reg_expr);
|
boost::xpressive::sregex sr = boost::xpressive::sregex::compile(reg_expr);
|
||||||
|
|
||||||
boost::xpressive::smatch sm;
|
boost::xpressive::smatch sm;
|
||||||
|
|
@ -38,10 +38,10 @@ libbitcoin_client::libbitcoin_client(std::string url) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t port_num = std::stoi(port);
|
const auto port_num = static_cast<uint16_t>(std::stoi(port));
|
||||||
std::string final_url = protocol + "://" + host;
|
const std::string final_url = protocol + "://" + host;
|
||||||
|
|
||||||
libbitcoin::config::endpoint address(final_url, port_num);
|
const libbitcoin::config::endpoint address(final_url, port_num);
|
||||||
|
|
||||||
libbitcoin::client::connection_type connection;
|
libbitcoin::client::connection_type connection;
|
||||||
connection.retries = LIBBITCOIN_SERVER_RETRIES;
|
connection.retries = LIBBITCOIN_SERVER_RETRIES;
|
||||||
|
|
@ -54,22 +54,20 @@ libbitcoin_client::libbitcoin_client(std::string url) :
|
||||||
is_connected = true;
|
is_connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string libbitcoin_client::send_transaction(std::string tx) {
|
std::string libbitcoin_client::send_transaction(const std::string &tx) {
|
||||||
|
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
||||||
auto error_handler = [&](const std::error_code &ec) {
|
auto error_handler = [](const std::error_code &ec) {
|
||||||
elog("error on sending bitcoin transaction ${error_code}", ("error_code", ec.message()));
|
elog("error on sending bitcoin transaction ${error_code}", ("error_code", ec.message()));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto result_handler = [&](libbitcoin::code result_code) {
|
auto result_handler = [&res](libbitcoin::code result_code) {
|
||||||
ilog("result code on sending transaction ${result_code}", ("result_code", result_code.message()));
|
ilog("result code on sending transaction ${result_code}", ("result_code", result_code.message()));
|
||||||
res = std::to_string(result_code.value());
|
res = std::to_string(result_code.value());
|
||||||
};
|
};
|
||||||
|
|
||||||
libbitcoin::explorer::config::transaction transaction(tx);
|
const libbitcoin::explorer::config::transaction transaction(tx);
|
||||||
|
|
||||||
libbitcoin::chain::transaction trx;
|
|
||||||
|
|
||||||
// This validates the tx, submits it to local tx pool, and notifies peers.
|
// This validates the tx, submits it to local tx pool, and notifies peers.
|
||||||
obelisk_client.transaction_pool_broadcast(error_handler, result_handler, transaction);
|
obelisk_client.transaction_pool_broadcast(error_handler, result_handler, transaction);
|
||||||
|
|
@ -78,22 +76,22 @@ std::string libbitcoin_client::send_transaction(std::string tx) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
libbitcoin::chain::output::list libbitcoin_client::get_transaction(std::string tx_id, std::string &tx_hash, uint32_t &confirmitions) {
|
libbitcoin::chain::output::list libbitcoin_client::get_transaction(const std::string &tx_id, std::string &tx_hash, uint32_t &confirmitions) {
|
||||||
|
|
||||||
libbitcoin::chain::output::list outs;
|
libbitcoin::chain::output::list outs;
|
||||||
|
|
||||||
auto error_handler = [&](const std::error_code &ec) {
|
auto error_handler = [&tx_id](const std::error_code &ec) {
|
||||||
elog("error on fetch_trx_by_hash: ${hash} ${error_code}", ("hash", tx_id)("error_code", ec.message()));
|
elog("error on fetch_trx_by_hash: ${hash} ${error_code}", ("hash", tx_id)("error_code", ec.message()));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto transaction_handler = [&](const libbitcoin::chain::transaction &tx_handler) {
|
auto transaction_handler = [&tx_hash, &confirmitions, &outs](const libbitcoin::chain::transaction &tx_handler) {
|
||||||
tx_hash = libbitcoin::config::hash256(tx_handler.hash(false)).to_string();
|
tx_hash = libbitcoin::config::hash256(tx_handler.hash(false)).to_string();
|
||||||
// TODO try to find this value (confirmitions)
|
// TODO try to find this value (confirmitions)
|
||||||
confirmitions = 1;
|
confirmitions = 1;
|
||||||
outs = tx_handler.outputs();
|
outs = tx_handler.outputs();
|
||||||
};
|
};
|
||||||
|
|
||||||
libbitcoin::hash_digest hash = libbitcoin::config::hash256(tx_id);
|
const libbitcoin::hash_digest hash = libbitcoin::config::hash256(tx_id);
|
||||||
|
|
||||||
// obelisk_client.blockchain_fetch_transaction (error_handler, transaction_handler,hash);
|
// obelisk_client.blockchain_fetch_transaction (error_handler, transaction_handler,hash);
|
||||||
obelisk_client.blockchain_fetch_transaction2(error_handler, transaction_handler, hash);
|
obelisk_client.blockchain_fetch_transaction2(error_handler, transaction_handler, hash);
|
||||||
|
|
@ -103,14 +101,14 @@ libbitcoin::chain::output::list libbitcoin_client::get_transaction(std::string t
|
||||||
return outs;
|
return outs;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<list_unspent_replay> libbitcoin_client::listunspent(std::string address, double amount) {
|
std::vector<list_unspent_replay> libbitcoin_client::listunspent(const std::string &address, double amount) {
|
||||||
std::vector<list_unspent_replay> result;
|
std::vector<list_unspent_replay> result;
|
||||||
|
|
||||||
auto error_handler = [&](const std::error_code &ec) {
|
auto error_handler = [](const std::error_code &ec) {
|
||||||
elog("error on list_unspent ${error_code}", ("error_code", ec.message()));
|
elog("error on list_unspent ${error_code}", ("error_code", ec.message()));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto replay_handler = [&](const libbitcoin::chain::points_value &points) {
|
auto replay_handler = [&result](const libbitcoin::chain::points_value &points) {
|
||||||
for (auto &point : points.points) {
|
for (auto &point : points.points) {
|
||||||
list_unspent_replay output;
|
list_unspent_replay output;
|
||||||
output.hash = libbitcoin::config::hash256(point.hash()).to_string();
|
output.hash = libbitcoin::config::hash256(point.hash()).to_string();
|
||||||
|
|
@ -120,8 +118,8 @@ std::vector<list_unspent_replay> libbitcoin_client::listunspent(std::string addr
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
libbitcoin::wallet::payment_address payment_address(address);
|
const libbitcoin::wallet::payment_address payment_address(address);
|
||||||
uint64_t satoshi = 100000000 * amount;
|
const auto satoshi = static_cast<uint64_t>(100000000 * amount);
|
||||||
|
|
||||||
obelisk_client.blockchain_fetch_unspent_outputs(error_handler,
|
obelisk_client.blockchain_fetch_unspent_outputs(error_handler,
|
||||||
replay_handler, payment_address, satoshi, libbitcoin::wallet::select_outputs::algorithm::individual);
|
replay_handler, payment_address, satoshi, libbitcoin::wallet::select_outputs::algorithm::individual);
|
||||||
|
|
@ -135,12 +133,12 @@ bool libbitcoin_client::get_is_test_net() {
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
auto error_handler = [&](const std::error_code &ec) {
|
auto error_handler = [](const std::error_code &ec) {
|
||||||
elog("error on fetching genesis block ${error_code}", ("error_code", ec.message()));
|
elog("error on fetching genesis block ${error_code}", ("error_code", ec.message()));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto block_header_handler = [&](const libbitcoin::chain::header &block_header) {
|
auto block_header_handler = [&result](const libbitcoin::chain::header &block_header) {
|
||||||
std::string hash_str = libbitcoin::config::hash256(block_header.hash()).to_string();
|
const std::string hash_str = libbitcoin::config::hash256(block_header.hash()).to_string();
|
||||||
if (hash_str == GENESIS_TESTNET_HASH || hash_str == GENESIS_REGTEST_HASH) {
|
if (hash_str == GENESIS_TESTNET_HASH || hash_str == GENESIS_REGTEST_HASH) {
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +150,7 @@ bool libbitcoin_client::get_is_test_net() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t libbitcoin_client::get_fee_from_trx(libbitcoin::chain::transaction trx) {
|
uint64_t libbitcoin_client::get_fee_from_trx(const libbitcoin::chain::transaction &trx) {
|
||||||
bool general_fee_est_error = false;
|
bool general_fee_est_error = false;
|
||||||
|
|
||||||
if (trx.is_coinbase()) {
|
if (trx.is_coinbase()) {
|
||||||
|
|
@ -169,15 +167,15 @@ uint64_t libbitcoin_client::get_fee_from_trx(libbitcoin::chain::transaction trx)
|
||||||
|
|
||||||
// fetch the trx to get total input value
|
// fetch the trx to get total input value
|
||||||
uint64_t total_input_value = 0;
|
uint64_t total_input_value = 0;
|
||||||
auto transaction_handler = [&](const libbitcoin::chain::transaction &tx_handler) {
|
auto transaction_handler = [&prev_out_trxs, &total_input_value](const libbitcoin::chain::transaction &tx_handler) {
|
||||||
std::vector<uint32_t> indexes = prev_out_trxs[tx_handler.hash()];
|
std::vector<uint32_t> indexes = prev_out_trxs[tx_handler.hash()];
|
||||||
|
|
||||||
for (auto &index : indexes) {
|
for (const auto &index : indexes) {
|
||||||
total_input_value += tx_handler.outputs()[index].value();
|
total_input_value += tx_handler.outputs()[index].value();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto error_handler = [&](const std::error_code &ec) {
|
auto error_handler = [&general_fee_est_error](const std::error_code &ec) {
|
||||||
elog("error on fetching trx ${error_code}", ("error_code", ec.message()));
|
elog("error on fetching trx ${error_code}", ("error_code", ec.message()));
|
||||||
general_fee_est_error = true;
|
general_fee_est_error = true;
|
||||||
};
|
};
|
||||||
|
|
@ -201,12 +199,12 @@ uint64_t libbitcoin_client::get_fee_from_trx(libbitcoin::chain::transaction trx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t libbitcoin_client::get_average_fee_from_trxs(std::vector<libbitcoin::chain::transaction> trx_list) {
|
uint64_t libbitcoin_client::get_average_fee_from_trxs(const std::vector<libbitcoin::chain::transaction> &trx_list) {
|
||||||
std::vector<uint64_t> fee_per_trxs;
|
std::vector<uint64_t> fee_per_trxs;
|
||||||
|
|
||||||
for (auto &trx : trx_list) {
|
for (auto &trx : trx_list) {
|
||||||
|
|
||||||
uint64_t fee = get_fee_from_trx(trx);
|
const uint64_t fee = get_fee_from_trx(trx);
|
||||||
if (fee > 0) {
|
if (fee > 0) {
|
||||||
fee_per_trxs.emplace_back(fee);
|
fee_per_trxs.emplace_back(fee);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -384,7 +384,7 @@ rpc_client::~rpc_client() {
|
||||||
if (connection_selection_task.valid())
|
if (connection_selection_task.valid())
|
||||||
connection_selection_task.cancel_and_wait(__FUNCTION__);
|
connection_selection_task.cancel_and_wait(__FUNCTION__);
|
||||||
} catch (fc::canceled_exception &) {
|
} catch (fc::canceled_exception &) {
|
||||||
//Expected exception. Move along.
|
// Expected exception. Move along.
|
||||||
} catch (fc::exception &e) {
|
} catch (fc::exception &e) {
|
||||||
edump((e.to_detail_string()));
|
edump((e.to_detail_string()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@
|
||||||
#include <bitcoin/system/chain/block.hpp>
|
#include <bitcoin/system/chain/block.hpp>
|
||||||
|
|
||||||
#include <boost/signals2.hpp>
|
#include <boost/signals2.hpp>
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
#define LIBBITCOIN_SERVER_TIMEOUT (10)
|
#define LIBBITCOIN_SERVER_TIMEOUT (10)
|
||||||
#define LIBBITCOIN_SERVER_RETRIES (100)
|
#define LIBBITCOIN_SERVER_RETRIES (100)
|
||||||
#define DEAFULT_LIBBITCOIN_TRX_FEE (20000)
|
#define DEAFULT_LIBBITCOIN_TRX_FEE (20000)
|
||||||
#define MAX_TRXS_IN_MEMORY_POOL (30000)
|
#define MAX_TRXS_IN_MEMORY_POOL (10000)
|
||||||
#define MIN_TRXS_IN_BUCKET (100)
|
#define MIN_TRXS_IN_BUCKET (100)
|
||||||
|
#define MAX_THREADS (5)
|
||||||
|
|
||||||
#define GENESIS_MAINNET_HASH "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
#define GENESIS_MAINNET_HASH "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
||||||
#define GENESIS_TESTNET_HASH "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
|
#define GENESIS_TESTNET_HASH "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
|
||||||
|
|
@ -19,9 +19,6 @@
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain {
|
namespace graphene { namespace peerplays_sidechain {
|
||||||
|
|
||||||
typedef std::function<void(const libbitcoin::chain::block &)>
|
|
||||||
block_update_handler;
|
|
||||||
|
|
||||||
struct list_unspent_replay {
|
struct list_unspent_replay {
|
||||||
std::string hash;
|
std::string hash;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
|
@ -30,12 +27,12 @@ struct list_unspent_replay {
|
||||||
|
|
||||||
class libbitcoin_client {
|
class libbitcoin_client {
|
||||||
public:
|
public:
|
||||||
libbitcoin_client(std::string url);
|
explicit libbitcoin_client(const std::string &url);
|
||||||
std::string send_transaction(const std::string tx);
|
std::string send_transaction(const std::string &tx);
|
||||||
libbitcoin::chain::output::list get_transaction(std::string tx_id, std::string &tx_hash, uint32_t &confirmitions);
|
libbitcoin::chain::output::list get_transaction(const std::string &tx_id, std::string &tx_hash, uint32_t &confirmitions);
|
||||||
std::vector<list_unspent_replay> listunspent(std::string address, double amount);
|
std::vector<list_unspent_replay> listunspent(const std::string &address, double amount);
|
||||||
uint64_t get_average_fee_from_trxs(std::vector<libbitcoin::chain::transaction> trx_list);
|
uint64_t get_average_fee_from_trxs(const std::vector<libbitcoin::chain::transaction> &trx_list);
|
||||||
uint64_t get_fee_from_trx(libbitcoin::chain::transaction trx);
|
uint64_t get_fee_from_trx(const libbitcoin::chain::transaction &trx);
|
||||||
bool get_is_test_net();
|
bool get_is_test_net();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -22,15 +22,15 @@ typedef fc::ecc::private_key private_key_type;
|
||||||
typedef fc::sha256 chain_id_type;
|
typedef fc::sha256 chain_id_type;
|
||||||
typedef std::string account_name_type;
|
typedef std::string account_name_type;
|
||||||
typedef fc::ripemd160 block_id_type;
|
typedef fc::ripemd160 block_id_type;
|
||||||
//typedef fc::ripemd160 checksum_type;
|
// typedef fc::ripemd160 checksum_type;
|
||||||
typedef fc::ripemd160 transaction_id_type;
|
typedef fc::ripemd160 transaction_id_type;
|
||||||
typedef fc::sha256 digest_type;
|
typedef fc::sha256 digest_type;
|
||||||
typedef fc::ecc::compact_signature signature_type;
|
typedef fc::ecc::compact_signature signature_type;
|
||||||
typedef fc::safe<int64_t> share_type;
|
typedef fc::safe<int64_t> share_type;
|
||||||
//typedef safe<uint64_t> ushare_type;
|
// typedef safe<uint64_t> ushare_type;
|
||||||
//typedef uint16_t weight_type;
|
// typedef uint16_t weight_type;
|
||||||
//typedef uint32_t contribution_id_type;
|
// typedef uint32_t contribution_id_type;
|
||||||
//typedef fixed_string<32> custom_id_type;
|
// typedef fixed_string<32> custom_id_type;
|
||||||
|
|
||||||
struct public_key_type {
|
struct public_key_type {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ public:
|
||||||
std::string label;
|
std::string label;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
virtual ~bitcoin_client_base() = default;
|
||||||
virtual uint64_t estimatesmartfee(uint16_t conf_target = 1) = 0;
|
virtual uint64_t estimatesmartfee(uint16_t conf_target = 1) = 0;
|
||||||
virtual std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2) = 0;
|
virtual std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2) = 0;
|
||||||
virtual btc_tx getrawtransaction(const std::string &txid, const bool verbose = false) = 0;
|
virtual btc_tx getrawtransaction(const std::string &txid, const bool verbose = false) = 0;
|
||||||
|
|
@ -70,8 +71,8 @@ public:
|
||||||
virtual std::string getblockchaininfo() = 0;
|
virtual std::string getblockchaininfo() = 0;
|
||||||
virtual std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999) = 0;
|
virtual std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999) = 0;
|
||||||
virtual std::string sendrawtransaction(const std::string &tx_hex) = 0;
|
virtual std::string sendrawtransaction(const std::string &tx_hex) = 0;
|
||||||
virtual void importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan = true) {
|
virtual void importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan = true){
|
||||||
;
|
//! Default implementation does nothing
|
||||||
};
|
};
|
||||||
virtual std::string loadwallet(const std::string &filename) {
|
virtual std::string loadwallet(const std::string &filename) {
|
||||||
return "";
|
return "";
|
||||||
|
|
@ -96,44 +97,37 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
class bitcoin_rpc_client : public bitcoin_client_base, public rpc_client {
|
class bitcoin_rpc_client : public bitcoin_client_base, public rpc_client {
|
||||||
public:
|
|
||||||
public:
|
public:
|
||||||
bitcoin_rpc_client(const std::vector<rpc_credentials> &_credentials, bool _debug_rpc_calls, bool _simulate_connection_reselection);
|
bitcoin_rpc_client(const std::vector<rpc_credentials> &_credentials, bool _debug_rpc_calls, bool _simulate_connection_reselection);
|
||||||
|
uint64_t estimatesmartfee(uint16_t conf_target = 1) final;
|
||||||
uint64_t estimatesmartfee(uint16_t conf_target = 1);
|
std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2) final;
|
||||||
std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2);
|
btc_tx getrawtransaction(const std::string &txid, const bool verbose = false) final;
|
||||||
btc_tx getrawtransaction(const std::string &txid, const bool verbose = false);
|
void getnetworkinfo() final;
|
||||||
void getnetworkinfo();
|
std::string getblockchaininfo() final;
|
||||||
std::string getblockchaininfo();
|
void importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan = true) final;
|
||||||
void importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan = true);
|
|
||||||
std::vector<btc_txout> listunspent(const uint32_t minconf = 1, const uint32_t maxconf = 9999999);
|
std::vector<btc_txout> listunspent(const uint32_t minconf = 1, const uint32_t maxconf = 9999999);
|
||||||
std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999);
|
std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999) final;
|
||||||
std::string loadwallet(const std::string &filename);
|
std::string loadwallet(const std::string &filename) final;
|
||||||
std::string sendrawtransaction(const std::string &tx_hex);
|
std::string sendrawtransaction(const std::string &tx_hex) final;
|
||||||
std::string walletlock();
|
std::string walletlock() final;
|
||||||
bool walletpassphrase(const std::string &passphrase, uint32_t timeout = 60);
|
bool walletpassphrase(const std::string &passphrase, uint32_t timeout = 60) final;
|
||||||
|
|
||||||
virtual uint64_t ping(rpc_connection &conn) const override;
|
uint64_t ping(rpc_connection &conn) const final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string ip;
|
|
||||||
std::string user;
|
|
||||||
std::string password;
|
|
||||||
std::string wallet_name;
|
|
||||||
std::string wallet_password;
|
|
||||||
uint32_t bitcoin_major_version;
|
uint32_t bitcoin_major_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
class bitcoin_libbitcoin_client : public bitcoin_client_base, public libbitcoin_client {
|
class bitcoin_libbitcoin_client : public bitcoin_client_base, public libbitcoin_client {
|
||||||
public:
|
public:
|
||||||
bitcoin_libbitcoin_client(std::string url);
|
explicit bitcoin_libbitcoin_client(const std::string &url);
|
||||||
uint64_t estimatesmartfee(uint16_t conf_target = 1);
|
uint64_t estimatesmartfee(uint16_t conf_target = 1) final;
|
||||||
std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2);
|
std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2) final;
|
||||||
btc_tx getrawtransaction(const std::string &txid, const bool verbose = false);
|
btc_tx getrawtransaction(const std::string &txid, const bool verbose = false) final;
|
||||||
void getnetworkinfo();
|
void getnetworkinfo() final;
|
||||||
std::string getblockchaininfo();
|
std::string getblockchaininfo() final;
|
||||||
std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999);
|
std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999) final;
|
||||||
std::string sendrawtransaction(const std::string &tx_hex);
|
std::string sendrawtransaction(const std::string &tx_hex) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool is_test_net = false;
|
bool is_test_net = false;
|
||||||
|
|
@ -145,13 +139,13 @@ private:
|
||||||
|
|
||||||
class zmq_listener_base {
|
class zmq_listener_base {
|
||||||
public:
|
public:
|
||||||
virtual ~zmq_listener_base(){};
|
zmq_listener_base(const std::string &_ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port = 0) :
|
||||||
zmq_listener_base(std::string _ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port = 0) {
|
ip(_ip),
|
||||||
ip = _ip;
|
block_zmq_port(_block_zmq_port),
|
||||||
block_zmq_port = _block_zmq_port;
|
trx_zmq_port(_trx_zmq_port),
|
||||||
trx_zmq_port = _trx_zmq_port;
|
stopped(false){};
|
||||||
stopped = false;
|
virtual ~zmq_listener_base() = default;
|
||||||
};
|
|
||||||
virtual void start() = 0;
|
virtual void start() = 0;
|
||||||
boost::signals2::signal<void(const block_data &)> block_event_received;
|
boost::signals2::signal<void(const block_data &)> block_event_received;
|
||||||
boost::signals2::signal<void(const libbitcoin::chain::transaction &)> trx_event_received;
|
boost::signals2::signal<void(const libbitcoin::chain::transaction &)> trx_event_received;
|
||||||
|
|
@ -167,9 +161,9 @@ protected:
|
||||||
|
|
||||||
class zmq_listener : public zmq_listener_base {
|
class zmq_listener : public zmq_listener_base {
|
||||||
public:
|
public:
|
||||||
zmq_listener(std::string _ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port = 0);
|
zmq_listener(const std::string &_ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port = 0);
|
||||||
virtual ~zmq_listener();
|
~zmq_listener() final;
|
||||||
void start();
|
void start() final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handle_zmq();
|
void handle_zmq();
|
||||||
|
|
@ -181,9 +175,9 @@ private:
|
||||||
|
|
||||||
class zmq_listener_libbitcoin : public zmq_listener_base {
|
class zmq_listener_libbitcoin : public zmq_listener_base {
|
||||||
public:
|
public:
|
||||||
zmq_listener_libbitcoin(std::string _ip, uint32_t _block_zmq_port = 9093, uint32_t _trx_zmq_port = 9094);
|
zmq_listener_libbitcoin(const std::string &_ip, uint32_t _block_zmq_port = 9093, uint32_t _trx_zmq_port = 9094);
|
||||||
virtual ~zmq_listener_libbitcoin();
|
~zmq_listener_libbitcoin() final;
|
||||||
void start();
|
void start() final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handle_block();
|
void handle_block();
|
||||||
|
|
@ -192,6 +186,7 @@ private:
|
||||||
libbitcoin::protocol::zmq::context block_context;
|
libbitcoin::protocol::zmq::context block_context;
|
||||||
libbitcoin::protocol::zmq::socket block_socket;
|
libbitcoin::protocol::zmq::socket block_socket;
|
||||||
libbitcoin::protocol::zmq::poller block_poller;
|
libbitcoin::protocol::zmq::poller block_poller;
|
||||||
|
|
||||||
libbitcoin::protocol::zmq::context trx_context;
|
libbitcoin::protocol::zmq::context trx_context;
|
||||||
libbitcoin::protocol::zmq::socket trx_socket;
|
libbitcoin::protocol::zmq::socket trx_socket;
|
||||||
libbitcoin::protocol::zmq::poller trx_poller;
|
libbitcoin::protocol::zmq::poller trx_poller;
|
||||||
|
|
@ -202,17 +197,17 @@ private:
|
||||||
class sidechain_net_handler_bitcoin : public sidechain_net_handler {
|
class sidechain_net_handler_bitcoin : public sidechain_net_handler {
|
||||||
public:
|
public:
|
||||||
sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
||||||
virtual ~sidechain_net_handler_bitcoin();
|
~sidechain_net_handler_bitcoin() final;
|
||||||
|
|
||||||
bool process_proposal(const proposal_object &po);
|
bool process_proposal(const proposal_object &po) final;
|
||||||
void process_primary_wallet();
|
void process_primary_wallet() final;
|
||||||
void process_sidechain_addresses();
|
void process_sidechain_addresses() final;
|
||||||
bool process_deposit(const son_wallet_deposit_object &swdo);
|
bool process_deposit(const son_wallet_deposit_object &swdo) final;
|
||||||
bool process_withdrawal(const son_wallet_withdraw_object &swwo);
|
bool process_withdrawal(const son_wallet_withdraw_object &swwo) final;
|
||||||
std::string process_sidechain_transaction(const sidechain_transaction_object &sto);
|
std::string process_sidechain_transaction(const sidechain_transaction_object &sto) final;
|
||||||
std::string send_sidechain_transaction(const sidechain_transaction_object &sto);
|
std::string send_sidechain_transaction(const sidechain_transaction_object &sto) final;
|
||||||
bool settle_sidechain_transaction(const sidechain_transaction_object &sto, asset &settle_amount);
|
bool settle_sidechain_transaction(const sidechain_transaction_object &sto, asset &settle_amount) final;
|
||||||
virtual optional<asset> estimate_withdrawal_transaction_fee() const override;
|
optional<asset> estimate_withdrawal_transaction_fee() const final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<rpc_credentials> _rpc_credentials;
|
std::vector<rpc_credentials> _rpc_credentials;
|
||||||
|
|
@ -229,10 +224,16 @@ private:
|
||||||
fc::future<void> on_changed_objects_task;
|
fc::future<void> on_changed_objects_task;
|
||||||
|
|
||||||
bitcoin::bitcoin_address::network network_type;
|
bitcoin::bitcoin_address::network network_type;
|
||||||
uint32_t bitcoin_major_version;
|
|
||||||
|
|
||||||
std::mutex event_handler_mutex;
|
std::mutex event_handler_mutex;
|
||||||
typedef std::lock_guard<decltype(event_handler_mutex)> scoped_lock;
|
using scoped_lock = std::lock_guard<decltype(event_handler_mutex)>;
|
||||||
|
|
||||||
|
boost::asio::io_context io_context_block;
|
||||||
|
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> work_guard_block;
|
||||||
|
boost::thread_group thread_pool_block;
|
||||||
|
boost::asio::io_context io_context_trx;
|
||||||
|
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> work_guard_trx;
|
||||||
|
boost::thread_group thread_pool_trx;
|
||||||
|
|
||||||
std::string create_primary_wallet_address(const std::vector<son_sidechain_info> &son_pubkeys);
|
std::string create_primary_wallet_address(const std::vector<son_sidechain_info> &son_pubkeys);
|
||||||
|
|
||||||
|
|
@ -240,7 +241,7 @@ private:
|
||||||
std::string create_deposit_transaction(const son_wallet_deposit_object &swdo);
|
std::string create_deposit_transaction(const son_wallet_deposit_object &swdo);
|
||||||
std::string create_withdrawal_transaction(const son_wallet_withdraw_object &swwo);
|
std::string create_withdrawal_transaction(const son_wallet_withdraw_object &swwo);
|
||||||
|
|
||||||
std::string create_transaction(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs, std::string &redeem_script);
|
std::string create_transaction(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs, const std::string &redeem_script);
|
||||||
std::string sign_transaction(const sidechain_transaction_object &sto);
|
std::string sign_transaction(const sidechain_transaction_object &sto);
|
||||||
std::string send_transaction(const sidechain_transaction_object &sto);
|
std::string send_transaction(const sidechain_transaction_object &sto);
|
||||||
|
|
||||||
|
|
@ -249,6 +250,8 @@ private:
|
||||||
std::string get_redeemscript_for_userdeposit(const std::string &user_address);
|
std::string get_redeemscript_for_userdeposit(const std::string &user_address);
|
||||||
void on_changed_objects(const vector<object_id_type> &ids, const flat_set<account_id_type> &accounts);
|
void on_changed_objects(const vector<object_id_type> &ids, const flat_set<account_id_type> &accounts);
|
||||||
void on_changed_objects_cb(const vector<object_id_type> &ids, const flat_set<account_id_type> &accounts);
|
void on_changed_objects_cb(const vector<object_id_type> &ids, const flat_set<account_id_type> &accounts);
|
||||||
|
|
||||||
|
void init_thread_pool(boost::asio::io_context &io_context, boost::thread_group &thread_pool, int num_threads);
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace graphene::peerplays_sidechain
|
}} // namespace graphene::peerplays_sidechain
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ peerplays_sidechain_plugin_impl::~peerplays_sidechain_plugin_impl() {
|
||||||
if (_heartbeat_task.valid())
|
if (_heartbeat_task.valid())
|
||||||
_heartbeat_task.cancel_and_wait(__FUNCTION__);
|
_heartbeat_task.cancel_and_wait(__FUNCTION__);
|
||||||
} catch (fc::canceled_exception &) {
|
} catch (fc::canceled_exception &) {
|
||||||
//Expected exception. Move along.
|
// Expected exception. Move along.
|
||||||
} catch (fc::exception &e) {
|
} catch (fc::exception &e) {
|
||||||
edump((e.to_detail_string()));
|
edump((e.to_detail_string()));
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +156,7 @@ peerplays_sidechain_plugin_impl::~peerplays_sidechain_plugin_impl() {
|
||||||
_son_processing_task.at(active_sidechain_type).wait();
|
_son_processing_task.at(active_sidechain_type).wait();
|
||||||
}
|
}
|
||||||
} catch (fc::canceled_exception &) {
|
} catch (fc::canceled_exception &) {
|
||||||
//Expected exception. Move along.
|
// Expected exception. Move along.
|
||||||
} catch (fc::exception &e) {
|
} catch (fc::exception &e) {
|
||||||
edump((e.to_detail_string()));
|
edump((e.to_detail_string()));
|
||||||
}
|
}
|
||||||
|
|
@ -540,11 +540,11 @@ void peerplays_sidechain_plugin_impl::son_processing(sidechain_type sidechain) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//fc::time_point now_fine = fc::time_point::now();
|
// fc::time_point now_fine = fc::time_point::now();
|
||||||
//fc::time_point_sec now = now_fine + fc::microseconds(500000);
|
// fc::time_point_sec now = now_fine + fc::microseconds(500000);
|
||||||
//if (plugin.database().get_slot_time(1) < now) {
|
// if (plugin.database().get_slot_time(1) < now) {
|
||||||
// return; // Not synced
|
// return; // Not synced
|
||||||
//}
|
// }
|
||||||
|
|
||||||
const fc::time_point now_fine = fc::time_point::now();
|
const fc::time_point now_fine = fc::time_point::now();
|
||||||
const fc::time_point_sec now = now_fine - fc::milliseconds(3000);
|
const fc::time_point_sec now = now_fine - fc::milliseconds(3000);
|
||||||
|
|
@ -873,15 +873,12 @@ void peerplays_sidechain_plugin_impl::settle_sidechain_transactions(sidechain_ty
|
||||||
|
|
||||||
void peerplays_sidechain_plugin_impl::on_applied_block(const signed_block &b) {
|
void peerplays_sidechain_plugin_impl::on_applied_block(const signed_block &b) {
|
||||||
if (first_block_skipped) {
|
if (first_block_skipped) {
|
||||||
if(son_processing_enabled) {
|
if (son_processing_enabled) {
|
||||||
schedule_son_processing();
|
schedule_son_processing();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
const fc::time_point now_fine = fc::time_point::now();
|
const fc::time_point now_fine = fc::time_point::now();
|
||||||
const fc::time_point_sec now = now_fine + fc::microseconds( 500000 );
|
const fc::time_point_sec now = now_fine + fc::microseconds(500000);
|
||||||
if( plugin.database().get_slot_time(1) >= now )
|
if (plugin.database().get_slot_time(1) >= now) {
|
||||||
{
|
|
||||||
son_processing_enabled = true;
|
son_processing_enabled = true;
|
||||||
schedule_son_processing();
|
schedule_son_processing();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -184,11 +184,11 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
|
||||||
|
|
||||||
bool enable_peerplays_asset_deposits = false;
|
bool enable_peerplays_asset_deposits = false;
|
||||||
#ifdef ENABLE_PEERPLAYS_ASSET_DEPOSITS
|
#ifdef ENABLE_PEERPLAYS_ASSET_DEPOSITS
|
||||||
//enable_peerplays_asset_deposits = (sed.sidechain == sidechain_type::peerplays) &&
|
// enable_peerplays_asset_deposits = (sed.sidechain == sidechain_type::peerplays) &&
|
||||||
// (sed.sidechain_currency.compare("BTC") != 0) &&
|
// (sed.sidechain_currency.compare("BTC") != 0) &&
|
||||||
// (sed.sidechain_currency.compare("ETH") != 0) &&
|
// (sed.sidechain_currency.compare("ETH") != 0) &&
|
||||||
// (sed.sidechain_currency.compare("HBD") != 0) &&
|
// (sed.sidechain_currency.compare("HBD") != 0) &&
|
||||||
// (sed.sidechain_currency.compare("HIVE") != 0);
|
// (sed.sidechain_currency.compare("HIVE") != 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const bool deposit_condition = (sed.peerplays_to == gpo.parameters.son_account()) &&
|
const bool deposit_condition = (sed.peerplays_to == gpo.parameters.son_account()) &&
|
||||||
|
|
@ -451,7 +451,7 @@ void sidechain_net_handler::process_deposits() {
|
||||||
if (swdo.id == object_id_type(0, 0, 0) || !plugin.can_son_participate(sidechain, chain::operation::tag<chain::son_wallet_deposit_process_operation>::value, swdo.id)) {
|
if (swdo.id == object_id_type(0, 0, 0) || !plugin.can_son_participate(sidechain, chain::operation::tag<chain::son_wallet_deposit_process_operation>::value, swdo.id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Ignore the deposits which are not valid anymore, considered refunds.
|
// Ignore the deposits which are not valid anymore, considered refunds.
|
||||||
const auto &sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_deposit_address_and_expires>();
|
const auto &sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_deposit_address_and_expires>();
|
||||||
const auto &addr_itr = sidechain_addresses_idx.find(std::make_tuple(sidechain, swdo.sidechain_from, time_point_sec::maximum()));
|
const auto &addr_itr = sidechain_addresses_idx.find(std::make_tuple(sidechain, swdo.sidechain_from, time_point_sec::maximum()));
|
||||||
if (addr_itr == sidechain_addresses_idx.end()) {
|
if (addr_itr == sidechain_addresses_idx.end()) {
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,8 @@ uint64_t bitcoin_rpc_client::estimatesmartfee(uint16_t conf_target) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<info_for_vin> bitcoin_rpc_client::getblock(const block_data &block, int32_t verbosity) {
|
std::vector<info_for_vin> bitcoin_rpc_client::getblock(const block_data &block, int32_t verbosity) {
|
||||||
std::string params = std::string("[\"") + block.block_hash + std::string("\",") + std::to_string(verbosity) + std::string("]");
|
const std::string params = std::string("[\"") + block.block_hash + std::string("\",") + std::to_string(verbosity) + std::string("]");
|
||||||
std::string str = send_post_request("getblock", params, debug_rpc_calls);
|
const std::string str = send_post_request("getblock", params, debug_rpc_calls);
|
||||||
std::vector<info_for_vin> result;
|
std::vector<info_for_vin> result;
|
||||||
|
|
||||||
if (str.empty()) {
|
if (str.empty()) {
|
||||||
|
|
@ -66,7 +66,7 @@ std::vector<info_for_vin> bitcoin_rpc_client::getblock(const block_data &block,
|
||||||
boost::property_tree::ptree json;
|
boost::property_tree::ptree json;
|
||||||
boost::property_tree::read_json(ss, json);
|
boost::property_tree::read_json(ss, json);
|
||||||
|
|
||||||
auto json_result = json.get_child_optional("result");
|
const auto json_result = json.get_child_optional("result");
|
||||||
|
|
||||||
for (const auto &tx_child : json_result.get().get_child("tx")) {
|
for (const auto &tx_child : json_result.get().get_child("tx")) {
|
||||||
const auto &tx = tx_child.second;
|
const auto &tx = tx_child.second;
|
||||||
|
|
@ -103,8 +103,8 @@ std::vector<info_for_vin> bitcoin_rpc_client::getblock(const block_data &block,
|
||||||
}
|
}
|
||||||
|
|
||||||
void bitcoin_rpc_client::getnetworkinfo() {
|
void bitcoin_rpc_client::getnetworkinfo() {
|
||||||
std::string params = std::string("[]");
|
static const std::string params = std::string("[]");
|
||||||
std::string str = send_post_request("getnetworkinfo", params, debug_rpc_calls);
|
const std::string str = send_post_request("getnetworkinfo", params, debug_rpc_calls);
|
||||||
|
|
||||||
std::stringstream network_info_ss(str);
|
std::stringstream network_info_ss(str);
|
||||||
boost::property_tree::ptree network_info_json;
|
boost::property_tree::ptree network_info_json;
|
||||||
|
|
@ -115,8 +115,8 @@ void bitcoin_rpc_client::getnetworkinfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
btc_tx bitcoin_rpc_client::getrawtransaction(const std::string &txid, const bool verbose) {
|
btc_tx bitcoin_rpc_client::getrawtransaction(const std::string &txid, const bool verbose) {
|
||||||
std::string params = std::string("[\"") + txid + std::string("\",") + (verbose ? "true" : "false") + std::string("]");
|
const std::string params = std::string("[\"") + txid + std::string("\",") + (verbose ? "true" : "false") + std::string("]");
|
||||||
std::string str = send_post_request("getrawtransaction", params, debug_rpc_calls);
|
const std::string str = send_post_request("getrawtransaction", params, debug_rpc_calls);
|
||||||
|
|
||||||
btc_tx tx;
|
btc_tx tx;
|
||||||
|
|
||||||
|
|
@ -126,10 +126,10 @@ btc_tx bitcoin_rpc_client::getrawtransaction(const std::string &txid, const bool
|
||||||
|
|
||||||
if (tx_json.count("error") && tx_json.get_child("error").empty()) {
|
if (tx_json.count("error") && tx_json.get_child("error").empty()) {
|
||||||
|
|
||||||
std::string tx_txid = tx_json.get<std::string>("result.txid");
|
const std::string tx_txid = tx_json.get<std::string>("result.txid");
|
||||||
uint32_t tx_confirmations = tx_json.get<uint32_t>("result.confirmations");
|
const uint32_t tx_confirmations = tx_json.get<uint32_t>("result.confirmations");
|
||||||
|
|
||||||
tx.tx_txid = tx_txid;
|
tx.tx_txid = std::move(tx_txid);
|
||||||
tx.tx_confirmations = tx_confirmations;
|
tx.tx_confirmations = tx_confirmations;
|
||||||
|
|
||||||
for (auto &input : tx_json.get_child("result.vout")) {
|
for (auto &input : tx_json.get_child("result.vout")) {
|
||||||
|
|
@ -332,14 +332,14 @@ bool bitcoin_rpc_client::walletpassphrase(const std::string &passphrase, uint32_
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bitcoin_libbitcoin_client::bitcoin_libbitcoin_client(std::string url) :
|
bitcoin_libbitcoin_client::bitcoin_libbitcoin_client(const std::string &url) :
|
||||||
libbitcoin_client(url) {
|
libbitcoin_client(url) {
|
||||||
|
|
||||||
estimate_fee_ext = std::unique_ptr<estimate_fee_external>(new estimate_fee_external());
|
estimate_fee_ext = std::unique_ptr<estimate_fee_external>(new estimate_fee_external());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t bitcoin_libbitcoin_client::estimatesmartfee(uint16_t conf_target) {
|
uint64_t bitcoin_libbitcoin_client::estimatesmartfee(uint16_t conf_target) {
|
||||||
std::vector<std::pair<std::string, uint64_t>> fees = estimate_fee_ext->get_fee_external(conf_target);
|
const std::vector<std::pair<std::string, uint64_t>> fees = estimate_fee_ext->get_fee_external(conf_target);
|
||||||
std::vector<uint64_t> accumulated_fees;
|
std::vector<uint64_t> accumulated_fees;
|
||||||
for (auto &external_fees : fees) {
|
for (auto &external_fees : fees) {
|
||||||
if (external_fees.second != 0) {
|
if (external_fees.second != 0) {
|
||||||
|
|
@ -357,28 +357,30 @@ uint64_t bitcoin_libbitcoin_client::estimatesmartfee(uint16_t conf_target) {
|
||||||
|
|
||||||
std::vector<info_for_vin> bitcoin_libbitcoin_client::getblock(const block_data &block, int32_t verbosity) {
|
std::vector<info_for_vin> bitcoin_libbitcoin_client::getblock(const block_data &block, int32_t verbosity) {
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lck(libbitcoin_event_mutex);
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(libbitcoin_event_mutex);
|
||||||
|
|
||||||
// estimate fee
|
// estimate fee
|
||||||
const auto &block_trxs = block.block.transactions();
|
const auto &block_trxs = block.block.transactions();
|
||||||
std::vector<libbitcoin::chain::transaction> bucket_trxs;
|
std::vector<libbitcoin::chain::transaction> bucket_trxs;
|
||||||
for (auto &mem_pool_trx : trx_memory_pool) {
|
for (auto &mem_pool_trx : trx_memory_pool) {
|
||||||
for (auto &trx : block_trxs) {
|
for (auto &trx : block_trxs) {
|
||||||
if (mem_pool_trx.hash() == trx.hash()) {
|
if (mem_pool_trx.hash() == trx.hash()) {
|
||||||
bucket_trxs.emplace_back(mem_pool_trx);
|
bucket_trxs.emplace_back(mem_pool_trx);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t average_fee = get_average_fee_from_trxs(bucket_trxs);
|
const uint64_t average_fee = get_average_fee_from_trxs(bucket_trxs);
|
||||||
if (average_fee > 0 && bucket_trxs.size() >= MIN_TRXS_IN_BUCKET) {
|
if (average_fee > 0 && bucket_trxs.size() >= MIN_TRXS_IN_BUCKET) {
|
||||||
current_internal_fee = average_fee;
|
current_internal_fee = average_fee;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We could consider accumulation which could spread to multiple blocks for better metric
|
// We could consider accumulation which could spread to multiple blocks for better metric
|
||||||
// for now we only keep tracking for not confirmed transaction until we get next block
|
// for now we only keep tracking for not confirmed transaction until we get next block
|
||||||
trx_memory_pool.clear();
|
trx_memory_pool.clear();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<info_for_vin> result;
|
std::vector<info_for_vin> result;
|
||||||
|
|
||||||
|
|
@ -481,8 +483,8 @@ std::string bitcoin_libbitcoin_client::getblockchaininfo() {
|
||||||
std::vector<btc_txout> bitcoin_libbitcoin_client::listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf, const uint32_t maxconf) {
|
std::vector<btc_txout> bitcoin_libbitcoin_client::listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf, const uint32_t maxconf) {
|
||||||
|
|
||||||
std::vector<btc_txout> result;
|
std::vector<btc_txout> result;
|
||||||
std::vector<list_unspent_replay> outputs = listunspent(address, transfer_amount);
|
const std::vector<list_unspent_replay> outputs = listunspent(address, transfer_amount);
|
||||||
for (auto &output : outputs) {
|
for (const auto &output : outputs) {
|
||||||
btc_txout txo;
|
btc_txout txo;
|
||||||
txo.txid_ = output.hash;
|
txo.txid_ = output.hash;
|
||||||
txo.out_num_ = output.index;
|
txo.out_num_ = output.index;
|
||||||
|
|
@ -494,12 +496,12 @@ std::vector<btc_txout> bitcoin_libbitcoin_client::listunspent_by_address_and_amo
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string bitcoin_libbitcoin_client::sendrawtransaction(const std::string &tx_hex) {
|
std::string bitcoin_libbitcoin_client::sendrawtransaction(const std::string &tx_hex) {
|
||||||
std::string res = send_transaction(tx_hex);
|
const std::string res = send_transaction(tx_hex);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t bitcoin_rpc_client::ping(rpc_connection &conn) const {
|
uint64_t bitcoin_rpc_client::ping(rpc_connection &conn) const {
|
||||||
std::string str = send_post_request(conn, "getblockcount", "[]", debug_rpc_calls);
|
const std::string str = send_post_request(conn, "getblockcount", "[]", debug_rpc_calls);
|
||||||
if (str.length() > 0)
|
if (str.length() > 0)
|
||||||
return std::stoll(str);
|
return std::stoll(str);
|
||||||
return std::numeric_limits<uint64_t>::max();
|
return std::numeric_limits<uint64_t>::max();
|
||||||
|
|
@ -507,7 +509,7 @@ uint64_t bitcoin_rpc_client::ping(rpc_connection &conn) const {
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
zmq_listener::zmq_listener(std::string _ip, uint32_t _zmq_block_port, uint32_t _zmq_trx_port) :
|
zmq_listener::zmq_listener(const std::string &_ip, uint32_t _zmq_block_port, uint32_t _zmq_trx_port) :
|
||||||
zmq_listener_base(_ip, _zmq_block_port, _zmq_trx_port),
|
zmq_listener_base(_ip, _zmq_block_port, _zmq_trx_port),
|
||||||
ctx(1),
|
ctx(1),
|
||||||
socket(ctx, ZMQ_SUB) {
|
socket(ctx, ZMQ_SUB) {
|
||||||
|
|
@ -577,7 +579,7 @@ void zmq_listener::handle_zmq() {
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
zmq_listener_libbitcoin::zmq_listener_libbitcoin(std::string _ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port) :
|
zmq_listener_libbitcoin::zmq_listener_libbitcoin(const std::string &_ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port) :
|
||||||
zmq_listener_base(_ip, _block_zmq_port, _trx_zmq_port),
|
zmq_listener_base(_ip, _block_zmq_port, _trx_zmq_port),
|
||||||
block_socket(block_context, libbitcoin::protocol::zmq::socket::role::subscriber),
|
block_socket(block_context, libbitcoin::protocol::zmq::socket::role::subscriber),
|
||||||
trx_socket(trx_context, libbitcoin::protocol::zmq::socket::role::subscriber) {
|
trx_socket(trx_context, libbitcoin::protocol::zmq::socket::role::subscriber) {
|
||||||
|
|
@ -590,7 +592,7 @@ zmq_listener_libbitcoin::~zmq_listener_libbitcoin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmq_listener_libbitcoin::start() {
|
void zmq_listener_libbitcoin::start() {
|
||||||
std::string endpoint_address = "tcp://" + ip;
|
const std::string endpoint_address = "tcp://" + ip;
|
||||||
|
|
||||||
libbitcoin::config::endpoint block_address(endpoint_address, block_zmq_port);
|
libbitcoin::config::endpoint block_address(endpoint_address, block_zmq_port);
|
||||||
libbitcoin::config::endpoint trx_address(endpoint_address, trx_zmq_port);
|
libbitcoin::config::endpoint trx_address(endpoint_address, trx_zmq_port);
|
||||||
|
|
@ -662,18 +664,20 @@ void zmq_listener_libbitcoin::handle_block() {
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
||||||
sidechain_net_handler(sidechain_type::bitcoin, _plugin, options) {
|
sidechain_net_handler(sidechain_type::bitcoin, _plugin, options),
|
||||||
|
work_guard_block(io_context_block.get_executor()),
|
||||||
|
work_guard_trx(io_context_trx.get_executor()) {
|
||||||
|
|
||||||
if (options.count("debug-rpc-calls")) {
|
if (options.count("debug-rpc-calls")) {
|
||||||
debug_rpc_calls = options.at("debug-rpc-calls").as<bool>();
|
debug_rpc_calls = options.at("debug-rpc-calls").as<bool>();
|
||||||
}
|
}
|
||||||
bool simulate_connection_reselection = options.at("simulate-rpc-connection-reselection").as<bool>();
|
const bool simulate_connection_reselection = options.at("simulate-rpc-connection-reselection").as<bool>();
|
||||||
|
|
||||||
std::vector<std::string> ips = options.at("bitcoin-node-ip").as<std::vector<std::string>>();
|
const std::vector<std::string> ips = options.at("bitcoin-node-ip").as<std::vector<std::string>>();
|
||||||
bitcoin_node_zmq_port = options.at("bitcoin-node-zmq-port").as<uint32_t>();
|
bitcoin_node_zmq_port = options.at("bitcoin-node-zmq-port").as<uint32_t>();
|
||||||
uint32_t rpc_port = options.at("bitcoin-node-rpc-port").as<uint32_t>();
|
const uint32_t rpc_port = options.at("bitcoin-node-rpc-port").as<uint32_t>();
|
||||||
std::string rpc_user = options.at("bitcoin-node-rpc-user").as<std::string>();
|
const std::string rpc_user = options.at("bitcoin-node-rpc-user").as<std::string>();
|
||||||
std::string rpc_password = options.at("bitcoin-node-rpc-password").as<std::string>();
|
const std::string rpc_password = options.at("bitcoin-node-rpc-password").as<std::string>();
|
||||||
|
|
||||||
if (options.count("use-bitcoind-client")) {
|
if (options.count("use-bitcoind-client")) {
|
||||||
use_bitcoind_client = options.at("use-bitcoind-client").as<bool>();
|
use_bitcoind_client = options.at("use-bitcoind-client").as<bool>();
|
||||||
|
|
@ -732,7 +736,7 @@ sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain
|
||||||
listener = std::unique_ptr<zmq_listener_libbitcoin>(new zmq_listener_libbitcoin(libbitcoin_server_ip, libbitcoin_block_zmq_port, libbitcoin_trx_zmq_port));
|
listener = std::unique_ptr<zmq_listener_libbitcoin>(new zmq_listener_libbitcoin(libbitcoin_server_ip, libbitcoin_block_zmq_port, libbitcoin_trx_zmq_port));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string chain_info = bitcoin_client->getblockchaininfo();
|
const std::string chain_info = bitcoin_client->getblockchaininfo();
|
||||||
|
|
||||||
using namespace bitcoin;
|
using namespace bitcoin;
|
||||||
network_type = bitcoin_address::network::mainnet;
|
network_type = bitcoin_address::network::mainnet;
|
||||||
|
|
@ -745,12 +749,15 @@ sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain
|
||||||
|
|
||||||
bitcoin_client->getnetworkinfo();
|
bitcoin_client->getnetworkinfo();
|
||||||
|
|
||||||
|
init_thread_pool(io_context_block, thread_pool_block, MAX_THREADS);
|
||||||
|
init_thread_pool(io_context_trx, thread_pool_trx, MAX_THREADS);
|
||||||
|
|
||||||
listener->block_event_received.connect([this](const block_data &block_event_data) {
|
listener->block_event_received.connect([this](const block_data &block_event_data) {
|
||||||
std::thread(&sidechain_net_handler_bitcoin::block_handle_event, this, block_event_data).detach();
|
io_context_block.post(boost::bind(&sidechain_net_handler_bitcoin::block_handle_event, this, block_event_data));
|
||||||
});
|
});
|
||||||
|
|
||||||
listener->trx_event_received.connect([this](const libbitcoin::chain::transaction &trx_event_data) {
|
listener->trx_event_received.connect([this](const libbitcoin::chain::transaction &trx_event_data) {
|
||||||
std::thread(&sidechain_net_handler_bitcoin::trx_handle_event, this, trx_event_data).detach();
|
io_context_trx.post(boost::bind(&sidechain_net_handler_bitcoin::trx_handle_event, this, trx_event_data));
|
||||||
});
|
});
|
||||||
|
|
||||||
listener->start();
|
listener->start();
|
||||||
|
|
@ -761,6 +768,11 @@ sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain
|
||||||
}
|
}
|
||||||
|
|
||||||
sidechain_net_handler_bitcoin::~sidechain_net_handler_bitcoin() {
|
sidechain_net_handler_bitcoin::~sidechain_net_handler_bitcoin() {
|
||||||
|
work_guard_block.reset();
|
||||||
|
work_guard_trx.reset();
|
||||||
|
thread_pool_block.join_all();
|
||||||
|
thread_pool_trx.join_all();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (on_changed_objects_task.valid()) {
|
if (on_changed_objects_task.valid()) {
|
||||||
on_changed_objects_task.cancel_and_wait(__FUNCTION__);
|
on_changed_objects_task.cancel_and_wait(__FUNCTION__);
|
||||||
|
|
@ -1212,7 +1224,7 @@ bool sidechain_net_handler_bitcoin::process_deposit(const son_wallet_deposit_obj
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tx_str = create_deposit_transaction(swdo);
|
const std::string tx_str = create_deposit_transaction(swdo);
|
||||||
|
|
||||||
if (!tx_str.empty()) {
|
if (!tx_str.empty()) {
|
||||||
const chain::global_property_object &gpo = database.get_global_properties();
|
const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
|
|
@ -1263,7 +1275,7 @@ bool sidechain_net_handler_bitcoin::process_withdrawal(const son_wallet_withdraw
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tx_str = create_withdrawal_transaction(swwo);
|
const std::string tx_str = create_withdrawal_transaction(swwo);
|
||||||
|
|
||||||
if (!tx_str.empty()) {
|
if (!tx_str.empty()) {
|
||||||
const chain::global_property_object &gpo = database.get_global_properties();
|
const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
|
|
@ -1327,7 +1339,7 @@ bool sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
btc_tx tx = bitcoin_client->getrawtransaction(sto.sidechain_transaction, true);
|
const btc_tx tx = bitcoin_client->getrawtransaction(sto.sidechain_transaction, true);
|
||||||
|
|
||||||
if (tx.tx_in_list.empty()) {
|
if (tx.tx_in_list.empty()) {
|
||||||
// This case will result with segmentation fault.
|
// This case will result with segmentation fault.
|
||||||
|
|
@ -1349,11 +1361,11 @@ bool sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain
|
||||||
payment_type_address = payment_type::P2WSH;
|
payment_type_address = payment_type::P2WSH;
|
||||||
}
|
}
|
||||||
|
|
||||||
btc_weighted_multisig_address addr(pubkey_weights, network_type, payment_type_address);
|
const btc_weighted_multisig_address addr(pubkey_weights, network_type, payment_type_address);
|
||||||
|
|
||||||
std::string tx_txid = tx.tx_txid;
|
const std::string tx_txid = tx.tx_txid;
|
||||||
uint32_t tx_confirmations = tx.tx_confirmations;
|
const uint32_t tx_confirmations = tx.tx_confirmations;
|
||||||
std::string tx_address = addr.get_address();
|
const std::string tx_address = addr.get_address();
|
||||||
int64_t tx_amount = -1;
|
int64_t tx_amount = -1;
|
||||||
|
|
||||||
if (tx_confirmations >= gpo.parameters.son_bitcoin_min_tx_confirmations()) {
|
if (tx_confirmations >= gpo.parameters.son_bitcoin_min_tx_confirmations()) {
|
||||||
|
|
@ -1397,14 +1409,14 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_address(const s
|
||||||
if (use_bitcoind_client) {
|
if (use_bitcoind_client) {
|
||||||
payment_type_address = payment_type::P2WSH;
|
payment_type_address = payment_type::P2WSH;
|
||||||
}
|
}
|
||||||
btc_weighted_multisig_address addr(pubkey_weights, network_type, payment_type_address);
|
const btc_weighted_multisig_address addr(pubkey_weights, network_type, payment_type_address);
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
ss << "{\"result\": {\"address\": \"" << addr.get_address() << "\", \"redeemScript\": \"" << fc::to_hex(addr.get_redeem_script()) << "\""
|
ss << "{\"result\": {\"address\": \"" << addr.get_address() << "\", \"redeemScript\": \"" << fc::to_hex(addr.get_redeem_script()) << "\""
|
||||||
<< "}, \"error\":null}";
|
<< "}, \"error\":null}";
|
||||||
|
|
||||||
std::string res = ss.str();
|
const std::string res = ss.str();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1423,8 +1435,8 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_transaction(con
|
||||||
std::stringstream prev_sw_ss(s);
|
std::stringstream prev_sw_ss(s);
|
||||||
boost::property_tree::ptree prev_sw_pt;
|
boost::property_tree::ptree prev_sw_pt;
|
||||||
boost::property_tree::read_json(prev_sw_ss, prev_sw_pt);
|
boost::property_tree::read_json(prev_sw_ss, prev_sw_pt);
|
||||||
std::string prev_pw_address = prev_sw_pt.get<std::string>("address");
|
const std::string prev_pw_address = prev_sw_pt.get<std::string>("address");
|
||||||
std::string prev_redeem_script = prev_sw_pt.get<std::string>("redeemScript");
|
const std::string prev_redeem_script = prev_sw_pt.get<std::string>("redeemScript");
|
||||||
|
|
||||||
if (prev_pw_address == new_sw_address) {
|
if (prev_pw_address == new_sw_address) {
|
||||||
wlog("BTC previous and new primary wallet addresses are same. No funds moving needed [from ${prev_sw} to ${new_sw_address}]", ("prev_swo", prev_swo.id)("active_sw", new_sw_address));
|
wlog("BTC previous and new primary wallet addresses are same. No funds moving needed [from ${prev_sw} to ${new_sw_address}]", ("prev_swo", prev_swo.id)("active_sw", new_sw_address));
|
||||||
|
|
@ -1465,18 +1477,18 @@ std::string sidechain_net_handler_bitcoin::create_deposit_transaction(const son_
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
// Get redeem script for deposit address
|
// Get redeem script for deposit address
|
||||||
std::string redeem_script = get_redeemscript_for_userdeposit(swdo.sidechain_from);
|
const std::string redeem_script = get_redeemscript_for_userdeposit(swdo.sidechain_from);
|
||||||
std::string pw_address_json = obj->addresses.find(sidechain)->second;
|
const std::string pw_address_json = obj->addresses.find(sidechain)->second;
|
||||||
|
|
||||||
std::stringstream ss(pw_address_json);
|
std::stringstream ss(pw_address_json);
|
||||||
boost::property_tree::ptree json;
|
boost::property_tree::ptree json;
|
||||||
boost::property_tree::read_json(ss, json);
|
boost::property_tree::read_json(ss, json);
|
||||||
|
|
||||||
std::string pw_address = json.get<std::string>("address");
|
const std::string pw_address = json.get<std::string>("address");
|
||||||
|
|
||||||
std::string txid = swdo.sidechain_transaction_id;
|
const std::string txid = swdo.sidechain_transaction_id;
|
||||||
std::string suid = swdo.sidechain_uid;
|
const std::string suid = swdo.sidechain_uid;
|
||||||
std::string nvout = suid.substr(suid.find_last_of("-") + 1);
|
const std::string nvout = suid.substr(suid.find_last_of("-") + 1);
|
||||||
uint64_t deposit_amount = swdo.sidechain_amount.value;
|
uint64_t deposit_amount = swdo.sidechain_amount.value;
|
||||||
uint64_t fee_rate = bitcoin_client->estimatesmartfee();
|
uint64_t fee_rate = bitcoin_client->estimatesmartfee();
|
||||||
const uint64_t min_fee_rate = 1000;
|
const uint64_t min_fee_rate = 1000;
|
||||||
|
|
@ -1488,7 +1500,7 @@ std::string sidechain_net_handler_bitcoin::create_deposit_transaction(const son_
|
||||||
}
|
}
|
||||||
|
|
||||||
deposit_amount -= fee_rate; // Deduct minimum relay fee
|
deposit_amount -= fee_rate; // Deduct minimum relay fee
|
||||||
double transfer_amount = (double)deposit_amount / 100000000.0;
|
const double transfer_amount = (double)deposit_amount / 100000000.0;
|
||||||
|
|
||||||
std::vector<btc_txout> inputs;
|
std::vector<btc_txout> inputs;
|
||||||
fc::flat_map<std::string, double> outputs;
|
fc::flat_map<std::string, double> outputs;
|
||||||
|
|
@ -1512,14 +1524,14 @@ std::string sidechain_net_handler_bitcoin::create_withdrawal_transaction(const s
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string pw_address_json = obj->addresses.find(sidechain)->second;
|
const std::string pw_address_json = obj->addresses.find(sidechain)->second;
|
||||||
|
|
||||||
std::stringstream ss(pw_address_json);
|
std::stringstream ss(pw_address_json);
|
||||||
boost::property_tree::ptree json;
|
boost::property_tree::ptree json;
|
||||||
boost::property_tree::read_json(ss, json);
|
boost::property_tree::read_json(ss, json);
|
||||||
|
|
||||||
std::string pw_address = json.get<std::string>("address");
|
const std::string pw_address = json.get<std::string>("address");
|
||||||
std::string redeem_script = json.get<std::string>("redeemScript");
|
const std::string redeem_script = json.get<std::string>("redeemScript");
|
||||||
|
|
||||||
int64_t fee_rate = bitcoin_client->estimatesmartfee();
|
int64_t fee_rate = bitcoin_client->estimatesmartfee();
|
||||||
const int64_t min_fee_rate = 1000;
|
const int64_t min_fee_rate = 1000;
|
||||||
|
|
@ -1551,7 +1563,7 @@ std::string sidechain_net_handler_bitcoin::create_withdrawal_transaction(const s
|
||||||
return create_transaction(inputs, outputs, redeem_script);
|
return create_transaction(inputs, outputs, redeem_script);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sidechain_net_handler_bitcoin::create_transaction(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs, std::string &redeem_script) {
|
std::string sidechain_net_handler_bitcoin::create_transaction(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs, const std::string &redeem_script) {
|
||||||
using namespace bitcoin;
|
using namespace bitcoin;
|
||||||
|
|
||||||
bitcoin_transaction_builder tb;
|
bitcoin_transaction_builder tb;
|
||||||
|
|
@ -1570,15 +1582,15 @@ std::string sidechain_net_handler_bitcoin::create_transaction(const std::vector<
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto tx = tb.get_transaction();
|
const auto tx = tb.get_transaction();
|
||||||
std::string hex_tx = fc::to_hex(pack(tx));
|
const std::string hex_tx = fc::to_hex(pack(tx));
|
||||||
std::string tx_raw = write_transaction_data(hex_tx, in_amounts, redeem_script);
|
const std::string tx_raw = write_transaction_data(hex_tx, in_amounts, redeem_script);
|
||||||
return tx_raw;
|
return tx_raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sidechain_net_handler_bitcoin::sign_transaction(const sidechain_transaction_object &sto) {
|
std::string sidechain_net_handler_bitcoin::sign_transaction(const sidechain_transaction_object &sto) {
|
||||||
using namespace bitcoin;
|
using namespace bitcoin;
|
||||||
std::string pubkey = plugin.get_current_son_object(sidechain).sidechain_public_keys.at(sidechain);
|
const std::string pubkey = plugin.get_current_son_object(sidechain).sidechain_public_keys.at(sidechain);
|
||||||
std::string prvkey = get_private_key(pubkey);
|
const std::string prvkey = get_private_key(pubkey);
|
||||||
std::vector<uint64_t> in_amounts;
|
std::vector<uint64_t> in_amounts;
|
||||||
std::string tx_hex;
|
std::string tx_hex;
|
||||||
std::string redeem_script;
|
std::string redeem_script;
|
||||||
|
|
@ -1589,14 +1601,14 @@ std::string sidechain_net_handler_bitcoin::sign_transaction(const sidechain_tran
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
const auto secret = btc_private_key->get_secret();
|
const auto secret = btc_private_key->get_secret();
|
||||||
bitcoin::bytes privkey_signing(secret.data(), secret.data() + secret.data_size());
|
const bitcoin::bytes privkey_signing(secret.data(), secret.data() + secret.data_size());
|
||||||
|
|
||||||
read_transaction_data(sto.transaction, tx_hex, in_amounts, redeem_script);
|
read_transaction_data(sto.transaction, tx_hex, in_amounts, redeem_script);
|
||||||
|
|
||||||
bitcoin_transaction tx = unpack(parse_hex(tx_hex));
|
const bitcoin_transaction tx = unpack(parse_hex(tx_hex));
|
||||||
std::vector<bitcoin::bytes> redeem_scripts(tx.vin.size(), parse_hex(redeem_script));
|
const std::vector<bitcoin::bytes> redeem_scripts(tx.vin.size(), parse_hex(redeem_script));
|
||||||
auto sigs = sign_witness_transaction_part(tx, redeem_scripts, in_amounts, privkey_signing, btc_context(), 1);
|
auto sigs = sign_witness_transaction_part(tx, redeem_scripts, in_amounts, privkey_signing, btc_context(), 1);
|
||||||
std::string tx_signature = write_transaction_signatures(sigs);
|
const std::string tx_signature = write_transaction_signatures(sigs);
|
||||||
|
|
||||||
return tx_signature;
|
return tx_signature;
|
||||||
}
|
}
|
||||||
|
|
@ -1613,7 +1625,7 @@ std::string sidechain_net_handler_bitcoin::send_transaction(const sidechain_tran
|
||||||
|
|
||||||
std::vector<bitcoin::bytes> redeem_scripts(tx.vin.size(), parse_hex(redeem_script));
|
std::vector<bitcoin::bytes> redeem_scripts(tx.vin.size(), parse_hex(redeem_script));
|
||||||
|
|
||||||
uint32_t inputs_number = in_amounts.size();
|
const uint32_t inputs_number = in_amounts.size();
|
||||||
vector<bitcoin::bytes> dummy;
|
vector<bitcoin::bytes> dummy;
|
||||||
dummy.resize(inputs_number);
|
dummy.resize(inputs_number);
|
||||||
// Organise weighted address signatures
|
// Organise weighted address signatures
|
||||||
|
|
@ -1645,8 +1657,8 @@ std::string sidechain_net_handler_bitcoin::send_transaction(const sidechain_tran
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string final_tx_hex = fc::to_hex(pack(tx));
|
const std::string final_tx_hex = fc::to_hex(pack(tx));
|
||||||
std::string res = bitcoin_client->sendrawtransaction(final_tx_hex);
|
const std::string res = bitcoin_client->sendrawtransaction(final_tx_hex);
|
||||||
|
|
||||||
if (res.empty()) {
|
if (res.empty()) {
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -1657,7 +1669,7 @@ std::string sidechain_net_handler_bitcoin::send_transaction(const sidechain_tran
|
||||||
|
|
||||||
void sidechain_net_handler_bitcoin::block_handle_event(const block_data &event_data) {
|
void sidechain_net_handler_bitcoin::block_handle_event(const block_data &event_data) {
|
||||||
|
|
||||||
auto vins = bitcoin_client->getblock(event_data);
|
const auto vins = bitcoin_client->getblock(event_data);
|
||||||
|
|
||||||
add_to_son_listener_log("BLOCK : " + event_data.block_hash);
|
add_to_son_listener_log("BLOCK : " + event_data.block_hash);
|
||||||
|
|
||||||
|
|
@ -1698,6 +1710,7 @@ void sidechain_net_handler_bitcoin::block_handle_event(const block_data &event_d
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_bitcoin::trx_handle_event(const libbitcoin::chain::transaction &trx_data) {
|
void sidechain_net_handler_bitcoin::trx_handle_event(const libbitcoin::chain::transaction &trx_data) {
|
||||||
|
|
||||||
bitcoin_client->import_trx_to_memory_pool(trx_data);
|
bitcoin_client->import_trx_to_memory_pool(trx_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1720,20 +1733,20 @@ std::string sidechain_net_handler_bitcoin::get_redeemscript_for_userdeposit(cons
|
||||||
auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(son.public_key)));
|
auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(son.public_key)));
|
||||||
pubkey_weights.push_back(std::make_pair(pub_key, son.weight));
|
pubkey_weights.push_back(std::make_pair(pub_key, son.weight));
|
||||||
}
|
}
|
||||||
auto user_pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(addr_itr->deposit_public_key)));
|
const auto user_pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(addr_itr->deposit_public_key)));
|
||||||
|
|
||||||
payment_type payment_type_address = payment_type::P2SH_WSH;
|
payment_type payment_type_address = payment_type::P2SH_WSH;
|
||||||
if (use_bitcoind_client) {
|
if (use_bitcoind_client) {
|
||||||
payment_type_address = payment_type::P2WSH;
|
payment_type_address = payment_type::P2WSH;
|
||||||
}
|
}
|
||||||
btc_one_or_weighted_multisig_address deposit_addr(user_pub_key, pubkey_weights, network_type, payment_type_address);
|
const btc_one_or_weighted_multisig_address deposit_addr(user_pub_key, pubkey_weights, network_type, payment_type_address);
|
||||||
|
|
||||||
return fc::to_hex(deposit_addr.get_redeem_script());
|
return fc::to_hex(deposit_addr.get_redeem_script());
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_bitcoin::on_changed_objects(const vector<object_id_type> &ids, const flat_set<account_id_type> &accounts) {
|
void sidechain_net_handler_bitcoin::on_changed_objects(const vector<object_id_type> &ids, const flat_set<account_id_type> &accounts) {
|
||||||
fc::time_point now = fc::time_point::now();
|
const fc::time_point now = fc::time_point::now();
|
||||||
int64_t time_to_next_changed_objects_processing = 5000;
|
const int64_t time_to_next_changed_objects_processing = 5000;
|
||||||
|
|
||||||
fc::time_point next_wakeup(now + fc::microseconds(time_to_next_changed_objects_processing));
|
fc::time_point next_wakeup(now + fc::microseconds(time_to_next_changed_objects_processing));
|
||||||
|
|
||||||
|
|
@ -1784,6 +1797,12 @@ void sidechain_net_handler_bitcoin::on_changed_objects_cb(const vector<object_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sidechain_net_handler_bitcoin::init_thread_pool(boost::asio::io_context &io_context, boost::thread_group &thread_pool, int num_threads) {
|
||||||
|
for (int i = 0; i < num_threads; ++i) {
|
||||||
|
thread_pool.create_thread(boost::bind(&boost::asio::io_context::run, &io_context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
}
|
}
|
||||||
} // namespace graphene::peerplays_sidechain
|
} // namespace graphene::peerplays_sidechain
|
||||||
|
|
|
||||||
|
|
@ -757,8 +757,8 @@ bool sidechain_net_handler_ethereum::settle_sidechain_transaction(const sidechai
|
||||||
if ("0x1" == json_receipt.get<std::string>("result.status")) {
|
if ("0x1" == json_receipt.get<std::string>("result.status")) {
|
||||||
count += 1;
|
count += 1;
|
||||||
//! Fixme - compare data somehow?
|
//! Fixme - compare data somehow?
|
||||||
//if( sto.transaction == entry_receipt.second.get<std::string>("data") ) {
|
// if( sto.transaction == entry_receipt.second.get<std::string>("data") ) {
|
||||||
//}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -858,14 +858,14 @@ bool sidechain_net_handler_hive::settle_sidechain_transaction(const sidechain_tr
|
||||||
boost::property_tree::ptree tx_json;
|
boost::property_tree::ptree tx_json;
|
||||||
boost::property_tree::read_json(ss_tx, tx_json);
|
boost::property_tree::read_json(ss_tx, tx_json);
|
||||||
|
|
||||||
//const chain::global_property_object &gpo = database.get_global_properties();
|
// const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
|
|
||||||
std::string tx_txid = tx_json.get<std::string>("result.transaction_id");
|
std::string tx_txid = tx_json.get<std::string>("result.transaction_id");
|
||||||
uint32_t tx_block_num = tx_json.get<uint32_t>("result.block_num");
|
uint32_t tx_block_num = tx_json.get<uint32_t>("result.block_num");
|
||||||
const uint32_t last_irreversible_block = std::stoul(rpc_client->get_last_irreversible_block_num());
|
const uint32_t last_irreversible_block = std::stoul(rpc_client->get_last_irreversible_block_num());
|
||||||
|
|
||||||
//std::string tx_address = addr.get_address();
|
// std::string tx_address = addr.get_address();
|
||||||
//int64_t tx_amount = -1;
|
// int64_t tx_amount = -1;
|
||||||
|
|
||||||
if (tx_block_num <= last_irreversible_block) {
|
if (tx_block_num <= last_irreversible_block) {
|
||||||
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
||||||
|
|
@ -918,15 +918,15 @@ void sidechain_net_handler_hive::hive_listener_loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::string reply = rpc_client->get_last_irreversible_block_num();
|
// std::string reply = rpc_client->get_last_irreversible_block_num();
|
||||||
//if (!reply.empty()) {
|
// if (!reply.empty()) {
|
||||||
// uint64_t last_irreversible_block = std::stoul(reply);
|
// uint64_t last_irreversible_block = std::stoul(reply);
|
||||||
// if (last_irreversible_block != last_block_received) {
|
// if (last_irreversible_block != last_block_received) {
|
||||||
// std::string event_data = std::to_string(last_irreversible_block);
|
// std::string event_data = std::to_string(last_irreversible_block);
|
||||||
// handle_event(event_data);
|
// handle_event(event_data);
|
||||||
// last_block_received = last_irreversible_block;
|
// last_block_received = last_irreversible_block;
|
||||||
// }
|
// }
|
||||||
//}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_hive::handle_event(const std::string &event_data) {
|
void sidechain_net_handler_hive::handle_event(const std::string &event_data) {
|
||||||
|
|
@ -960,7 +960,7 @@ void sidechain_net_handler_hive::handle_event(const std::string &event_data) {
|
||||||
const auto &amount_child = op_value.get_child("amount");
|
const auto &amount_child = op_value.get_child("amount");
|
||||||
|
|
||||||
uint64_t amount = amount_child.get<uint64_t>("amount");
|
uint64_t amount = amount_child.get<uint64_t>("amount");
|
||||||
//uint64_t precision = amount_child.get<uint64_t>("precision");
|
// uint64_t precision = amount_child.get<uint64_t>("precision");
|
||||||
std::string nai = amount_child.get<std::string>("nai");
|
std::string nai = amount_child.get<std::string>("nai");
|
||||||
std::string sidechain_currency = "";
|
std::string sidechain_currency = "";
|
||||||
price sidechain_currency_price = {};
|
price sidechain_currency_price = {};
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,15 @@ namespace graphene { namespace peerplays_sidechain {
|
||||||
|
|
||||||
sidechain_net_handler_peerplays::sidechain_net_handler_peerplays(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
sidechain_net_handler_peerplays::sidechain_net_handler_peerplays(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
||||||
sidechain_net_handler(sidechain_type::peerplays, _plugin, options) {
|
sidechain_net_handler(sidechain_type::peerplays, _plugin, options) {
|
||||||
//const auto &assets_by_symbol = database.get_index_type<asset_index>().indices().get<by_symbol>();
|
// const auto &assets_by_symbol = database.get_index_type<asset_index>().indices().get<by_symbol>();
|
||||||
//const auto get_asset_id = [&assets_by_symbol](const string &symbol) {
|
// const auto get_asset_id = [&assets_by_symbol](const string &symbol) {
|
||||||
// auto asset_itr = assets_by_symbol.find(symbol);
|
// auto asset_itr = assets_by_symbol.find(symbol);
|
||||||
// FC_ASSERT(asset_itr != assets_by_symbol.end(), "Unable to find asset '${sym}'", ("sym", symbol));
|
// FC_ASSERT(asset_itr != assets_by_symbol.end(), "Unable to find asset '${sym}'", ("sym", symbol));
|
||||||
// return asset_itr->get_id();
|
// return asset_itr->get_id();
|
||||||
//};
|
// };
|
||||||
//tracked_assets.push_back(get_asset_id("PBTC"));
|
// tracked_assets.push_back(get_asset_id("PBTC"));
|
||||||
//tracked_assets.push_back(get_asset_id("PETH"));
|
// tracked_assets.push_back(get_asset_id("PETH"));
|
||||||
//tracked_assets.push_back(get_asset_id("PEOS"));
|
// tracked_assets.push_back(get_asset_id("PEOS"));
|
||||||
|
|
||||||
if (options.count("peerplays-private-key")) {
|
if (options.count("peerplays-private-key")) {
|
||||||
const std::vector<std::string> pub_priv_keys = options["peerplays-private-key"].as<std::vector<std::string>>();
|
const std::vector<std::string> pub_priv_keys = options["peerplays-private-key"].as<std::vector<std::string>>();
|
||||||
|
|
@ -284,8 +284,8 @@ bool sidechain_net_handler_peerplays::settle_sidechain_transaction(const sidecha
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sto.object_id.is<son_wallet_deposit_id_type>()) {
|
if (sto.object_id.is<son_wallet_deposit_id_type>()) {
|
||||||
//auto swdo = database.get<son_wallet_deposit_object>(sto.object_id);
|
// auto swdo = database.get<son_wallet_deposit_object>(sto.object_id);
|
||||||
//settle_amount = asset(swdo.sidechain_amount, swdo.sidechain_currency);
|
// settle_amount = asset(swdo.sidechain_amount, swdo.sidechain_currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
||||||
|
|
|
||||||
|
|
@ -934,6 +934,31 @@ class wallet_api
|
||||||
string memo,
|
string memo,
|
||||||
bool broadcast = false);
|
bool broadcast = false);
|
||||||
|
|
||||||
|
/** Transfer an amount from one account to another,
|
||||||
|
* even without the authority of the from account. This function
|
||||||
|
* is an "issuer override." To use it, you must be the issuer of
|
||||||
|
* the asset and the override permission must be retained and enabled
|
||||||
|
* on the asset.
|
||||||
|
* @param from the name or id of the account sending the funds
|
||||||
|
* @param to the name or id of the account receiving the funds
|
||||||
|
* @param issuer the name or id of the asset issuer
|
||||||
|
* @param amount the amount to send (in nominal units -- to send half of a BTS, specify 0.5)
|
||||||
|
* @param asset_symbol the symbol or id of the asset to send
|
||||||
|
* @param memo a memo to attach to the transaction. The memo will be encrypted in the
|
||||||
|
* transaction and readable for the receiver. There is no length limit
|
||||||
|
* other than the limit imposed by maximum transaction size, but transaction
|
||||||
|
* increase with transaction size
|
||||||
|
* @param broadcast true to broadcast the transaction on the network
|
||||||
|
* @returns the signed transaction transferring funds
|
||||||
|
*/
|
||||||
|
signed_transaction override_transfer(string from,
|
||||||
|
string to,
|
||||||
|
string issuer,
|
||||||
|
string amount,
|
||||||
|
string asset_symbol,
|
||||||
|
string memo,
|
||||||
|
bool broadcast = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method works just like transfer, except it always broadcasts and
|
* This method works just like transfer, except it always broadcasts and
|
||||||
* returns the transaction ID (hash) along with the signed transaction.
|
* returns the transaction ID (hash) along with the signed transaction.
|
||||||
|
|
@ -1965,6 +1990,7 @@ class wallet_api
|
||||||
std::vector<std::string> witnesses_to_reject,
|
std::vector<std::string> witnesses_to_reject,
|
||||||
uint16_t desired_number_of_witnesses,
|
uint16_t desired_number_of_witnesses,
|
||||||
bool broadcast = false);
|
bool broadcast = false);
|
||||||
|
|
||||||
/** Set the voting proxy for an account.
|
/** Set the voting proxy for an account.
|
||||||
*
|
*
|
||||||
* If a user does not wish to take an active part in voting, they can choose
|
* If a user does not wish to take an active part in voting, they can choose
|
||||||
|
|
@ -2012,6 +2038,18 @@ class wallet_api
|
||||||
uint16_t desired_number_of_committee_members,
|
uint16_t desired_number_of_committee_members,
|
||||||
bool broadcast = false);
|
bool broadcast = false);
|
||||||
|
|
||||||
|
/** Vote recharge gpos.
|
||||||
|
*
|
||||||
|
* Explicit voting recharge function that is used solely when the user wishes to recharge their GPOS voting power
|
||||||
|
* without changing their voting slate
|
||||||
|
*
|
||||||
|
* @param voting_account the name or id of the account who is voting with their shares
|
||||||
|
* @param broadcast true if you wish to broadcast the transaction
|
||||||
|
* @return the signed transaction changing your vote for the given SON
|
||||||
|
*/
|
||||||
|
signed_transaction vote_recharge_gpos(string voting_account,
|
||||||
|
bool broadcast = false);
|
||||||
|
|
||||||
/** Signs a transaction.
|
/** Signs a transaction.
|
||||||
*
|
*
|
||||||
* Given a fully-formed transaction that is only lacking signatures, this signs
|
* Given a fully-formed transaction that is only lacking signatures, this signs
|
||||||
|
|
@ -2684,6 +2722,7 @@ class wallet_api
|
||||||
*/
|
*/
|
||||||
voters_info get_voters(const string &account_name_or_id) const;
|
voters_info get_voters(const string &account_name_or_id) const;
|
||||||
|
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
/**
|
/**
|
||||||
* @brief Demo plugin api
|
* @brief Demo plugin api
|
||||||
* @return The hello world string
|
* @return The hello world string
|
||||||
|
|
@ -2702,6 +2741,7 @@ class wallet_api
|
||||||
* @return Gas fee in ETH
|
* @return Gas fee in ETH
|
||||||
*/
|
*/
|
||||||
std::string eth_estimate_withdrawal_transaction_fee() const;
|
std::string eth_estimate_withdrawal_transaction_fee() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
fc::signal<void(bool)> lock_changed;
|
fc::signal<void(bool)> lock_changed;
|
||||||
std::shared_ptr<detail::wallet_api_impl> my;
|
std::shared_ptr<detail::wallet_api_impl> my;
|
||||||
|
|
@ -2804,6 +2844,7 @@ FC_API( graphene::wallet::wallet_api,
|
||||||
(borrow_asset)
|
(borrow_asset)
|
||||||
(cancel_order)
|
(cancel_order)
|
||||||
(transfer)
|
(transfer)
|
||||||
|
(override_transfer)
|
||||||
(transfer2)
|
(transfer2)
|
||||||
(get_transaction_id)
|
(get_transaction_id)
|
||||||
(create_asset)
|
(create_asset)
|
||||||
|
|
@ -2850,7 +2891,7 @@ FC_API( graphene::wallet::wallet_api,
|
||||||
(get_son_wallets)
|
(get_son_wallets)
|
||||||
(add_sidechain_address)
|
(add_sidechain_address)
|
||||||
(delete_sidechain_address)
|
(delete_sidechain_address)
|
||||||
(sidechain_withdrawal_transaction)
|
(sidechain_withdrawal_transaction)
|
||||||
(get_sidechain_addresses_by_account)
|
(get_sidechain_addresses_by_account)
|
||||||
(get_sidechain_addresses_by_sidechain)
|
(get_sidechain_addresses_by_sidechain)
|
||||||
(get_sidechain_address_by_account_and_sidechain)
|
(get_sidechain_address_by_account_and_sidechain)
|
||||||
|
|
@ -2870,6 +2911,7 @@ FC_API( graphene::wallet::wallet_api,
|
||||||
(update_witness_votes)
|
(update_witness_votes)
|
||||||
(set_voting_proxy)
|
(set_voting_proxy)
|
||||||
(set_desired_witness_and_committee_member_count)
|
(set_desired_witness_and_committee_member_count)
|
||||||
|
(vote_recharge_gpos)
|
||||||
(get_account)
|
(get_account)
|
||||||
(get_account_id)
|
(get_account_id)
|
||||||
(get_block)
|
(get_block)
|
||||||
|
|
@ -3002,7 +3044,9 @@ FC_API( graphene::wallet::wallet_api,
|
||||||
(get_votes)
|
(get_votes)
|
||||||
(get_voters_by_id)
|
(get_voters_by_id)
|
||||||
(get_voters)
|
(get_voters)
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
(get_son_listener_log)
|
(get_son_listener_log)
|
||||||
(estimate_withdrawal_transaction_fee)
|
(estimate_withdrawal_transaction_fee)
|
||||||
(eth_estimate_withdrawal_transaction_fee)
|
(eth_estimate_withdrawal_transaction_fee)
|
||||||
|
#endif
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,9 @@
|
||||||
#include <graphene/wallet/api_documentation.hpp>
|
#include <graphene/wallet/api_documentation.hpp>
|
||||||
#include <graphene/wallet/reflect_util.hpp>
|
#include <graphene/wallet/reflect_util.hpp>
|
||||||
#include <graphene/debug_witness/debug_api.hpp>
|
#include <graphene/debug_witness/debug_api.hpp>
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
#include <graphene/peerplays_sidechain/sidechain_api.hpp>
|
#include <graphene/peerplays_sidechain/sidechain_api.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
|
|
@ -3101,6 +3103,31 @@ public:
|
||||||
return sign_transaction( tx, broadcast );
|
return sign_transaction( tx, broadcast );
|
||||||
} FC_CAPTURE_AND_RETHROW( (account_to_modify)(desired_number_of_witnesses)(desired_number_of_committee_members)(broadcast) ) }
|
} FC_CAPTURE_AND_RETHROW( (account_to_modify)(desired_number_of_witnesses)(desired_number_of_committee_members)(broadcast) ) }
|
||||||
|
|
||||||
|
signed_transaction vote_recharge_gpos(string voting_account,
|
||||||
|
bool broadcast /* = false */)
|
||||||
|
{ try {
|
||||||
|
|
||||||
|
const std::vector<vesting_balance_object_with_info> vbo_info = get_vesting_balances(voting_account);
|
||||||
|
std::vector<vesting_balance_object_with_info>::const_iterator vbo_iter;
|
||||||
|
vbo_iter = std::find_if(vbo_info.begin(), vbo_info.end(), [](vesting_balance_object_with_info const& obj){return obj.balance_type == vesting_balance_type::gpos;});
|
||||||
|
if( vbo_info.size() == 0 || vbo_iter == vbo_info.end())
|
||||||
|
FC_THROW("Account ${account} has no core Token ${TOKEN} vested and will not be allowed to recharge the votes", ("account", voting_account)("TOKEN", GRAPHENE_SYMBOL));
|
||||||
|
|
||||||
|
const account_object voting_account_object = get_account(voting_account);
|
||||||
|
|
||||||
|
account_update_operation account_update_op;
|
||||||
|
account_update_op.account = voting_account_object.id;
|
||||||
|
account_update_op.new_options = voting_account_object.options;
|
||||||
|
account_update_op.extensions.value.update_last_voting_time = true; //Allow user to vote in each sub-period (Update voting time, which is reference in calculating VF)
|
||||||
|
|
||||||
|
signed_transaction tx;
|
||||||
|
tx.operations.push_back( account_update_op );
|
||||||
|
set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees);
|
||||||
|
tx.validate();
|
||||||
|
|
||||||
|
return sign_transaction( tx, broadcast );
|
||||||
|
} FC_CAPTURE_AND_RETHROW( (voting_account)(broadcast) ) }
|
||||||
|
|
||||||
signed_transaction sign_transaction(signed_transaction tx, bool broadcast = false)
|
signed_transaction sign_transaction(signed_transaction tx, bool broadcast = false)
|
||||||
{
|
{
|
||||||
set<public_key_type> pks = _remote_db->get_potential_signatures(tx);
|
set<public_key_type> pks = _remote_db->get_potential_signatures(tx);
|
||||||
|
|
@ -3359,6 +3386,7 @@ public:
|
||||||
|
|
||||||
//! For sidechain withdrawal check if amount is greater than fee
|
//! For sidechain withdrawal check if amount is greater than fee
|
||||||
if(to_id == _remote_db->get_global_properties().parameters.son_account()) {
|
if(to_id == _remote_db->get_global_properties().parameters.son_account()) {
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
const auto sidechain = get_sidechain_type_from_asset(asset_obj->id);
|
const auto sidechain = get_sidechain_type_from_asset(asset_obj->id);
|
||||||
const auto transaction_fee = estimate_withdrawal_transaction_fee(sidechain);
|
const auto transaction_fee = estimate_withdrawal_transaction_fee(sidechain);
|
||||||
|
|
||||||
|
|
@ -3368,11 +3396,71 @@ public:
|
||||||
("sidechain_fee", get_asset(transaction_fee->asset_id).amount_to_pretty_string(transaction_fee->amount))("amount", get_asset(xfer_op.amount.asset_id).amount_to_pretty_string(xfer_op.amount.amount)));
|
("sidechain_fee", get_asset(transaction_fee->asset_id).amount_to_pretty_string(transaction_fee->amount))("amount", get_asset(xfer_op.amount.asset_id).amount_to_pretty_string(xfer_op.amount.amount)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
FC_THROW("Withdrawal to SON account is not supported without sidechain plugin enabled");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return sign_transaction(tx, broadcast);
|
return sign_transaction(tx, broadcast);
|
||||||
} FC_CAPTURE_AND_RETHROW( (from)(to)(amount)(asset_symbol)(memo)(broadcast) ) }
|
} FC_CAPTURE_AND_RETHROW( (from)(to)(amount)(asset_symbol)(memo)(broadcast) ) }
|
||||||
|
|
||||||
|
signed_transaction override_transfer(string from, string to, string issuer, string amount,
|
||||||
|
string asset_symbol, string memo, bool broadcast = false) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
FC_ASSERT(!self.is_locked());
|
||||||
|
fc::optional<asset_object> asset_obj = get_asset(asset_symbol);
|
||||||
|
FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_symbol));
|
||||||
|
|
||||||
|
account_object from_account = get_account(from);
|
||||||
|
account_object to_account = get_account(to);
|
||||||
|
account_object issuer_account = get_account(issuer);
|
||||||
|
|
||||||
|
account_id_type from_id = from_account.id;
|
||||||
|
account_id_type to_id = get_account_id(to);
|
||||||
|
account_id_type issuer_id = get_account_id(issuer);
|
||||||
|
|
||||||
|
override_transfer_operation xfer_op;
|
||||||
|
xfer_op.issuer = issuer_id;
|
||||||
|
xfer_op.from = from_id;
|
||||||
|
xfer_op.to = to_id;
|
||||||
|
xfer_op.amount = asset_obj->amount_from_string(amount);
|
||||||
|
|
||||||
|
if (memo.size()) {
|
||||||
|
xfer_op.memo = memo_data();
|
||||||
|
xfer_op.memo->from = from_account.options.memo_key;
|
||||||
|
xfer_op.memo->to = to_account.options.memo_key;
|
||||||
|
xfer_op.memo->set_message(get_private_key(from_account.options.memo_key),
|
||||||
|
to_account.options.memo_key, memo);
|
||||||
|
}
|
||||||
|
|
||||||
|
signed_transaction tx;
|
||||||
|
tx.operations.push_back(xfer_op);
|
||||||
|
set_operation_fees(tx, _remote_db->get_global_properties().parameters.current_fees);
|
||||||
|
tx.validate();
|
||||||
|
|
||||||
|
//! For sidechain withdrawal check if amount is greater than fee
|
||||||
|
if (to_id == _remote_db->get_global_properties().parameters.son_account()) {
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
|
const auto sidechain = get_sidechain_type_from_asset(asset_obj->id);
|
||||||
|
const auto transaction_fee = estimate_withdrawal_transaction_fee(sidechain);
|
||||||
|
|
||||||
|
if (transaction_fee) {
|
||||||
|
if (*transaction_fee >= xfer_op.amount) {
|
||||||
|
FC_THROW("Transaction fee: ${sidechain_fee}, is greater than or equal to the transferred amount ${amount}",
|
||||||
|
("sidechain_fee", get_asset(transaction_fee->asset_id).amount_to_pretty_string(transaction_fee->amount))("amount", get_asset(xfer_op.amount.asset_id).amount_to_pretty_string(xfer_op.amount.amount)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
FC_THROW("Override transfer to SON account is not supported without sidechain plugin enabled");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return sign_transaction(tx, broadcast);
|
||||||
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((from)(to)(issuer)(amount)(asset_symbol)(memo)(broadcast))
|
||||||
|
}
|
||||||
|
|
||||||
signed_transaction issue_asset(string to_account, string amount, string symbol,
|
signed_transaction issue_asset(string to_account, string amount, string symbol,
|
||||||
string memo, bool broadcast = false)
|
string memo, bool broadcast = false)
|
||||||
{
|
{
|
||||||
|
|
@ -4123,6 +4211,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
void use_sidechain_api()
|
void use_sidechain_api()
|
||||||
{
|
{
|
||||||
if( _remote_sidechain )
|
if( _remote_sidechain )
|
||||||
|
|
@ -4142,6 +4231,7 @@ public:
|
||||||
"\n";
|
"\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void network_add_nodes( const vector<string>& nodes )
|
void network_add_nodes( const vector<string>& nodes )
|
||||||
{
|
{
|
||||||
|
|
@ -4259,6 +4349,7 @@ public:
|
||||||
FC_CAPTURE_AND_RETHROW( (account_name_or_id) )
|
FC_CAPTURE_AND_RETHROW( (account_name_or_id) )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
std::map<sidechain_type, std::vector<std::string>> get_son_listener_log()
|
std::map<sidechain_type, std::vector<std::string>> get_son_listener_log()
|
||||||
{
|
{
|
||||||
use_sidechain_api();
|
use_sidechain_api();
|
||||||
|
|
@ -4293,6 +4384,7 @@ public:
|
||||||
}
|
}
|
||||||
FC_CAPTURE_AND_RETHROW()
|
FC_CAPTURE_AND_RETHROW()
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
string _wallet_filename;
|
string _wallet_filename;
|
||||||
wallet_data _wallet;
|
wallet_data _wallet;
|
||||||
|
|
@ -4308,7 +4400,9 @@ public:
|
||||||
fc::api<bookie_api> _remote_bookie;
|
fc::api<bookie_api> _remote_bookie;
|
||||||
optional< fc::api<network_node_api> > _remote_net_node;
|
optional< fc::api<network_node_api> > _remote_net_node;
|
||||||
optional< fc::api<graphene::debug_witness::debug_api> > _remote_debug;
|
optional< fc::api<graphene::debug_witness::debug_api> > _remote_debug;
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
optional< fc::api<graphene::peerplays_sidechain::sidechain_api> > _remote_sidechain;
|
optional< fc::api<graphene::peerplays_sidechain::sidechain_api> > _remote_sidechain;
|
||||||
|
#endif
|
||||||
|
|
||||||
flat_map<string, operation> _prototype_ops;
|
flat_map<string, operation> _prototype_ops;
|
||||||
|
|
||||||
|
|
@ -5072,6 +5166,12 @@ signed_transaction wallet_api::transfer(string from, string to, string amount,
|
||||||
{
|
{
|
||||||
return my->transfer(from, to, amount, asset_symbol, memo, broadcast);
|
return my->transfer(from, to, amount, asset_symbol, memo, broadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signed_transaction wallet_api::override_transfer(string from, string to, string issuer, string amount,
|
||||||
|
string asset_symbol, string memo, bool broadcast /* = false */) {
|
||||||
|
return my->override_transfer(from, to, issuer, amount, asset_symbol, memo, broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
signed_transaction wallet_api::create_asset(string issuer,
|
signed_transaction wallet_api::create_asset(string issuer,
|
||||||
string symbol,
|
string symbol,
|
||||||
uint8_t precision,
|
uint8_t precision,
|
||||||
|
|
@ -5551,6 +5651,12 @@ signed_transaction wallet_api::set_desired_witness_and_committee_member_count(st
|
||||||
desired_number_of_committee_members, broadcast);
|
desired_number_of_committee_members, broadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signed_transaction wallet_api::vote_recharge_gpos(string voting_account,
|
||||||
|
bool broadcast /* = false */)
|
||||||
|
{
|
||||||
|
return my->vote_recharge_gpos(voting_account, broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
void wallet_api::set_wallet_filename(string wallet_filename)
|
void wallet_api::set_wallet_filename(string wallet_filename)
|
||||||
{
|
{
|
||||||
my->_wallet_filename = wallet_filename;
|
my->_wallet_filename = wallet_filename;
|
||||||
|
|
@ -7360,6 +7466,7 @@ voters_info wallet_api::get_voters(const string &account_name_or_id) const
|
||||||
return my->get_voters(account_name_or_id);
|
return my->get_voters(account_name_or_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
std::map<sidechain_type, std::vector<std::string>> wallet_api::get_son_listener_log() const
|
std::map<sidechain_type, std::vector<std::string>> wallet_api::get_son_listener_log() const
|
||||||
{
|
{
|
||||||
return my->get_son_listener_log();
|
return my->get_son_listener_log();
|
||||||
|
|
@ -7374,6 +7481,7 @@ std::string wallet_api::eth_estimate_withdrawal_transaction_fee() const
|
||||||
{
|
{
|
||||||
return my->eth_estimate_withdrawal_transaction_fee();
|
return my->eth_estimate_withdrawal_transaction_fee();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
vesting_balance_object_with_info::vesting_balance_object_with_info()
|
vesting_balance_object_with_info::vesting_balance_object_with_info()
|
||||||
: vesting_balance_object()
|
: vesting_balance_object()
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,13 @@ if( GPERFTOOLS_FOUND )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# We have to link against graphene_debug_witness because deficiency in our API infrastructure doesn't allow plugins to be fully abstracted #246
|
# We have to link against graphene_debug_witness because deficiency in our API infrastructure doesn't allow plugins to be fully abstracted #246
|
||||||
target_link_libraries( witness_node
|
set(LIBRARIES graphene_app graphene_egenesis_full graphene_snapshot graphene_delayed_node graphene_witness ${PLATFORM_SPECIFIC_LIBS})
|
||||||
PRIVATE graphene_app graphene_egenesis_full graphene_snapshot graphene_delayed_node graphene_witness peerplays_sidechain ${PLATFORM_SPECIFIC_LIBS} )
|
|
||||||
|
if(NOT DEFINED DISABLE_PEERPLAYS_SIDECHAIN_PLUGIN)
|
||||||
|
list(APPEND LIBRARIES peerplays_sidechain)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries( witness_node PRIVATE ${LIBRARIES} )
|
||||||
# also add dependencies to graphene_generate_genesis graphene_generate_uia_sharedrop_genesis if you want those plugins
|
# also add dependencies to graphene_generate_genesis graphene_generate_uia_sharedrop_genesis if you want those plugins
|
||||||
|
|
||||||
install( TARGETS
|
install( TARGETS
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,9 @@
|
||||||
//#include <graphene/generate_uia_sharedrop_genesis/generate_uia_sharedrop_genesis.hpp>
|
//#include <graphene/generate_uia_sharedrop_genesis/generate_uia_sharedrop_genesis.hpp>
|
||||||
#include <graphene/affiliate_stats/affiliate_stats_plugin.hpp>
|
#include <graphene/affiliate_stats/affiliate_stats_plugin.hpp>
|
||||||
#include <graphene/bookie/bookie_plugin.hpp>
|
#include <graphene/bookie/bookie_plugin.hpp>
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
#include <graphene/peerplays_sidechain/peerplays_sidechain_plugin.hpp>
|
#include <graphene/peerplays_sidechain/peerplays_sidechain_plugin.hpp>
|
||||||
|
#endif
|
||||||
#include <graphene/delayed_node/delayed_node_plugin.hpp>
|
#include <graphene/delayed_node/delayed_node_plugin.hpp>
|
||||||
#include <graphene/utilities/git_revision.hpp>
|
#include <graphene/utilities/git_revision.hpp>
|
||||||
#include <graphene/snapshot/snapshot.hpp>
|
#include <graphene/snapshot/snapshot.hpp>
|
||||||
|
|
@ -89,7 +91,9 @@ int main(int argc, char** argv) {
|
||||||
auto list_plug = node->register_plugin<accounts_list::accounts_list_plugin>();
|
auto list_plug = node->register_plugin<accounts_list::accounts_list_plugin>();
|
||||||
auto affiliate_stats_plug = node->register_plugin<affiliate_stats::affiliate_stats_plugin>();
|
auto affiliate_stats_plug = node->register_plugin<affiliate_stats::affiliate_stats_plugin>();
|
||||||
auto bookie_plug = node->register_plugin<bookie::bookie_plugin>();
|
auto bookie_plug = node->register_plugin<bookie::bookie_plugin>();
|
||||||
|
#ifdef BUILD_PEERPLAYS_SIDECHAIN_PLUGIN
|
||||||
auto peerplays_sidechain = node->register_plugin<peerplays_sidechain::peerplays_sidechain_plugin>();
|
auto peerplays_sidechain = node->register_plugin<peerplays_sidechain::peerplays_sidechain_plugin>();
|
||||||
|
#endif
|
||||||
auto snapshot_plug = node->register_plugin<snapshot_plugin::snapshot_plugin>();
|
auto snapshot_plug = node->register_plugin<snapshot_plugin::snapshot_plugin>();
|
||||||
auto delayed_plug = node->register_plugin<delayed_node::delayed_node_plugin>();
|
auto delayed_plug = node->register_plugin<delayed_node::delayed_node_plugin>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,11 @@ file(GLOB BETTING_TESTS "betting/*.cpp")
|
||||||
add_executable( betting_test ${BETTING_TESTS} )
|
add_executable( betting_test ${BETTING_TESTS} )
|
||||||
target_link_libraries( betting_test PRIVATE graphene_tests_common ${PLATFORM_SPECIFIC_LIBS} )
|
target_link_libraries( betting_test PRIVATE graphene_tests_common ${PLATFORM_SPECIFIC_LIBS} )
|
||||||
|
|
||||||
file(GLOB PEERPLAYS_SIDECHAIN_TESTS "peerplays_sidechain/*.cpp")
|
if(NOT DEFINED DISABLE_PEERPLAYS_SIDECHAIN_PLUGIN)
|
||||||
add_executable( peerplays_sidechain_test ${PEERPLAYS_SIDECHAIN_TESTS} )
|
file(GLOB PEERPLAYS_SIDECHAIN_TESTS "peerplays_sidechain/*.cpp")
|
||||||
target_link_libraries( peerplays_sidechain_test PRIVATE graphene_tests_common peerplays_sidechain ${PLATFORM_SPECIFIC_LIBS} )
|
add_executable( peerplays_sidechain_test ${PEERPLAYS_SIDECHAIN_TESTS} )
|
||||||
|
target_link_libraries( peerplays_sidechain_test PRIVATE graphene_tests_common peerplays_sidechain ${PLATFORM_SPECIFIC_LIBS} )
|
||||||
|
endif ()
|
||||||
|
|
||||||
file(GLOB TOURNAMENT_TESTS "tournament/*.cpp")
|
file(GLOB TOURNAMENT_TESTS "tournament/*.cpp")
|
||||||
add_executable( tournament_test ${TOURNAMENT_TESTS} )
|
add_executable( tournament_test ${TOURNAMENT_TESTS} )
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue