eosauthority / eosio-watcher-plugin Goto Github PK
View Code? Open in Web Editor NEWEOSIO watcher plugin: HTTP POST to endpoint for on chain actions
License: MIT License
EOSIO watcher plugin: HTTP POST to endpoint for on chain actions
License: MIT License
There has been a recent change in eos that allows an easy way to run external plugins, you can see how sql_plugin can be plugged in this readme: https://github.com/asiniscalchi/eosio_sql_plugin
in cmake:
-DEOSIO_ADDITIONAL_PLUGINS=<path_to_eosio_sql_plugin_source>
Enable support for Web Sockets in addition to HTTP end point.
Requested by Syed Jafri - Cafe
CMake Error at plugins/CMakeLists.txt:28 (target_link_libraries):
Cannot specify link libraries for target "nodeos" which is not built by
this project.
nodeos version: mainnet-1.3.1
watcher-plugin config:
#=============
#Enable plugin
plugin = eosio::watcher_plugin
watch = eosio.stake:
watch = cannontest11:
watch-receiver-url = http://127.0.0.1:8080/
watch-age-limit = 5
#=============
Issue:
I can get notified while there is a stake action to eosio.stake, but can't get any post notification for account cannontest11.
For a real Security
Fresh install, Ubuntu 16.04
stdout log:
Scanning dependencies of target watcher_plugin
[ 95%] Building CXX object additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/src/watcher_plugin.cpp.o
[ 95%] Building CXX object unittests/CMakeFiles/unit_test.dir/producer_schedule_tests.cpp.o
[ 95%] Linking CXX static library libproducer_plugin.a
[ 95%] Built target producer_plugin
[ 95%] Building CXX object unittests/CMakeFiles/unit_test.dir/protocol_feature_tests.cpp.o
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:96:41: error: no member named 'receiver' in 'fc::optionaleosio::chain::action_receipt'; did you mean to
use '->' instead of '.'?
if( filter_on.find({act.receipt.receiver, act.act.name}) != filter_on.end())
^
->
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:98:46: error: no member named 'receiver' in 'fc::optionaleosio::chain::action_receipt'; did you mean to
use '->' instead of '.'?
else if( filter_on.find({act.receipt.receiver, 0}) != filter_on.end())
^
->
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:122:83: error: no member named 'receiver' in 'fc::optionaleosio::chain::action_receipt'; did you mean to
use '->' instead of '.'?
act.receipt.receiver)));
^
->
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:127:39: error: no member named 'inline_traces' in 'eosio::chain::action_trace'
for( const auto& iline : act.inline_traces ) {
~~~ ^
In file included from /root/eosio-watcher-plugin/src/watcher_plugin.cpp:5:
In file included from /root/eosio-watcher-plugin/include/eosio/watcher_plugin/watcher_plugin.hpp:6:
In file included from /root/eos/plugins/chain_plugin/../../libraries/appbase/include/appbase/application.hpp:2:
In file included from /root/eos/plugins/chain_plugin/../../libraries/appbase/include/appbase/plugin.hpp:2:
In file included from /root/src/boost_1_70_0/include/boost/program_options.hpp:15:
In file included from /root/src/boost_1_70_0/include/boost/program_options/options_description.hpp:13:
In file included from /root/src/boost_1_70_0/include/boost/program_options/value_semantic.hpp:13:
In file included from /root/src/boost_1_70_0/include/boost/function/function1.hpp:11:
In file included from /root/src/boost_1_70_0/include/boost/function/detail/maybe_include.hpp:22:
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:158:33: error: no matching function for call to object of type '(lambda at
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)'
BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
^~~~
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:80:36: note: expanded from macro 'BOOST_FUNCTION_RETURN'
^
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:931:53: note: in instantiation of member function
'boost::detail::function::void_function_obj_invoker1<(lambda at /root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13), void, std::tuple<const
std::shared_ptreosio::chain::transaction_trace &, const eosio::chain::signed_transaction &> >::invoke' requested here
{ { &manager_type::manage }, &invoker_type::invoke };
^
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:720:13: note: in instantiation of function template specialization
'boost::function1<void, std::tuple<const std::shared_ptreosio::chain::transaction_trace &, const eosio::chain::signed_transaction &>
>::assign_to<(lambda at /root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
this->assign_to(f);
^
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:1068:5: note: in instantiation of function template specialization
'boost::function1<void, std::tuple<const std::shared_ptreosio::chain::transaction_trace &, const eosio::chain::signed_transaction &>
>::function1<(lambda at /root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
base_type(f)
^
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:1121:5: note: in instantiation of function template specialization 'boost::function<void
(std::tuple<const std::shared_ptreosio::chain::transaction_trace &, const eosio::chain::signed_transaction &>)>::function<(lambda at
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
self_type(f).swap(*this);
^
/root/src/boost_1_70_0/include/boost/signals2/detail/slot_template.hpp:160:24: note: in instantiation of function template specialization
'boost::function<void (std::tuple<const std::shared_ptreosio::chain::transaction_trace &, const eosio::chain::signed_transaction
&>)>::operator=<(lambda at /root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
_slot_function = detail::get_invocable_slot(f, detail::tag_type(f));
^
/root/src/boost_1_70_0/include/boost/signals2/detail/slot_template.hpp:85:9: note: in instantiation of function template specialization
'boost::signals2::slot<void (std::tuple<const std::shared_ptreosio::chain::transaction_trace &, const eosio::chain::signed_transaction &>),
boost::function<void (std::tuple<const std::shared_ptreosio::chain::transaction_trace &, const eosio::chain::signed_transaction &>)>
>::init_slot_function<(lambda at /root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
init_slot_function(f);
^
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13: note: in instantiation of function template specialization 'boost::signals2::slot<void
(std::tuple<const std::shared_ptreosio::chain::transaction_trace &, const eosio::chain::signed_transaction &>), boost::function<void
(std::tuple<const std::shared_ptreosio::chain::transaction_trace &, const eosio::chain::signed_transaction &>)> >::slot<(lambda at
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
[&](const transaction_trace_ptr& tt) {
^
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13: note: candidate function not viable: no known conversion from 'std::tuple<const
std::shared_ptreosio::chain::transaction_trace &, const eosio::chain::signed_transaction &>' to 'const eosio::chain::transaction_trace_ptr' (aka
'const shared_ptreosio::chain::transaction_trace') for 1st argument
5 errors generated.
additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/build.make:62: recipe for target 'additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/src/watcher_plugin.cpp.o' failed
make[2]: *** [additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/src/watcher_plugin.cpp.o] Error 1
CMakeFiles/Makefile2:4173: recipe for target 'additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/all' failed
+#pragma once
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/use_future.hpp>
#include <fc/variant.hpp>
#include <fc/reflect/variant.hpp>
#include <fc/time.hpp>
#include <fc/network/http/http_client.hpp>
#include
namespace eosio {
using namespace fc;
namespace asio = boost::asio;
template
struct final_action {
final_action(F f) : clean{f} {}
~final_action() { clean(); }
private:
F clean;
};
template
final_action finally(F f) {
return final_action(f);
}
class http_async_client {
public:
http_async_client() : sync_client(std::make_unique<http_client>()),
work_guard(asio::make_work_guard(ioc)) {
}
~http_async_client() {
work_guard.reset();
}
void start() {
worker = std::make_unique<std::thread>( [this]() {
ioc.run();
});
}
void stop() {
work_guard.reset();
worker->join();
}
// TODO: return result as future
template<typename T>
void post(const url& dest, const T& payload,
const time_point& deadline = time_point::maximum()) {
// Make sure only sync_client and these arguments (copied by value) are accessed from
// separate tread.
// T type could have pointers, but it doesn't make sense for payload to have them anyway.
asio::post( ioc.get_executor(), [this, dest, payload, deadline]() {
post_sync(dest, payload, deadline);
});
}
// TODO: implement. Add call_impl function which could be used by post as well as these.
// void add_cert(const std::string& cert_pem_string);
// void set_verify_peers(bool enabled);
private:
template
void post_sync(const url& dest, const T& payload,
const time_point& deadline = time_point::maximum()) {
auto exit = finally( [this](){ retry = true; } );
try {
sync_client->post_sync(dest, payload, deadline);
} catch( const fc::eof_exception& exc) {
// FIXME: http_client expects body in response and throws eof if it doesn't get it.
} catch( const fc::assert_exception& exc ) {
// Thrown when sending or reading response fails
// Try once more
wlog("Exception while trying to send: ${exc}", ("exc", exc.to_detail_string()));
if( retry ) {
wlog("Trying again");
retry = false;
post_sync(dest, payload, deadline);
}
}
FC_CAPTURE_AND_LOG( (dest)(payload)(deadline) )
}
std::unique_ptr<http_client> sync_client;
std::unique_ptr<std::thread> worker;
asio::io_context ioc;
asio::executor_work_guard<asio::io_context::executor_type> work_guard;
bool retry = true;
};
}
It would be great to add some information to make sure that actions are sorted. Right now if two actions comes in the same tx or block they can be sorted wrong due to latency / http.
Suggestion could be to add (if possible):
Hi,
I got error when used eosio_watcher_plugin
Here is my error:
warn 2019-03-06T03:54:15.005 thread-1 http_async_client.hpp:82 post_sync ] Exception while trying to send: 10 assert_exception: Assert Exception
!ec: Failed to read response: end of stream
{"message":"end of stream"}
thread-1 http_client.cpp:360 post_sync
warn 2019-03-06T03:54:15.005 thread-1 http_async_client.hpp:84 post_sync ] Trying again
warn 2019-03-06T03:54:15.025 thread-1 http_async_client.hpp:89 post_sync ] 4 parse_error_exception: Parse Error
Unexpected char '79' in "OK"
{"c":79,"s":"OK"}
thread-1 json.cpp:437 variant_from_stream
{"str":"OK"}
thread-1 json.cpp:460 from_string
warn 2019-03-06T03:54:15.025 thread-1 http_async_client.hpp:89 post_sync ] dest: http://127.0.0.1:8082/blockchain_action payload: {"actions":[{"tx_id":"6a173c0024cb24676f5f65c89f18046941ba9fb1d1f55073c1f23de3d6e4cbb7","account".....
And here is my express server:
const express = require('express');
const app = express()
const port = 8082
app.post('/blockchain_action', function (req, res) {
console.log(req.body)
res.sendStatus(200)
});
app.listen(port, () => console.log(Example app listening on port ${port}!
))
-> It returned undefined
result to console
Pls help me, thanks!
Currently unable to use this plugin on Jungle Testnet, as the testnet now requires nodeos v1.8.0
, but the plugin does not compile.
v1.8.0-rc2
stdout log:
Scanning dependencies of target watcher_plugin
[ 95%] Building CXX object additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/src/watcher_plugin.cpp.o
[ 95%] Building CXX object unittests/CMakeFiles/unit_test.dir/producer_schedule_tests.cpp.o
[ 95%] Linking CXX static library libproducer_plugin.a
[ 95%] Built target producer_plugin
[ 95%] Building CXX object unittests/CMakeFiles/unit_test.dir/protocol_feature_tests.cpp.o
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:96:41: error: no member named 'receiver' in 'fc::optional<eosio::chain::action_receipt>'; did you mean to
use '->' instead of '.'?
if( filter_on.find({act.receipt.receiver, act.act.name}) != filter_on.end())
^
->
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:98:46: error: no member named 'receiver' in 'fc::optional<eosio::chain::action_receipt>'; did you mean to
use '->' instead of '.'?
else if( filter_on.find({act.receipt.receiver, 0}) != filter_on.end())
^
->
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:122:83: error: no member named 'receiver' in 'fc::optional<eosio::chain::action_receipt>'; did you mean to
use '->' instead of '.'?
act.receipt.receiver)));
^
->
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:127:39: error: no member named 'inline_traces' in 'eosio::chain::action_trace'
for( const auto& iline : act.inline_traces ) {
~~~ ^
In file included from /root/eosio-watcher-plugin/src/watcher_plugin.cpp:5:
In file included from /root/eosio-watcher-plugin/include/eosio/watcher_plugin/watcher_plugin.hpp:6:
In file included from /root/eos/plugins/chain_plugin/../../libraries/appbase/include/appbase/application.hpp:2:
In file included from /root/eos/plugins/chain_plugin/../../libraries/appbase/include/appbase/plugin.hpp:2:
In file included from /root/src/boost_1_70_0/include/boost/program_options.hpp:15:
In file included from /root/src/boost_1_70_0/include/boost/program_options/options_description.hpp:13:
In file included from /root/src/boost_1_70_0/include/boost/program_options/value_semantic.hpp:13:
In file included from /root/src/boost_1_70_0/include/boost/function/function1.hpp:11:
In file included from /root/src/boost_1_70_0/include/boost/function/detail/maybe_include.hpp:22:
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:158:33: error: no matching function for call to object of type '(lambda at
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)'
BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
^~~~
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:80:36: note: expanded from macro 'BOOST_FUNCTION_RETURN'
# define BOOST_FUNCTION_RETURN(X) X
^
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:931:53: note: in instantiation of member function
'boost::detail::function::void_function_obj_invoker1<(lambda at /root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13), void, std::tuple<const
std::shared_ptr<eosio::chain::transaction_trace> &, const eosio::chain::signed_transaction &> >::invoke' requested here
{ { &manager_type::manage }, &invoker_type::invoke };
^
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:720:13: note: in instantiation of function template specialization
'boost::function1<void, std::tuple<const std::shared_ptr<eosio::chain::transaction_trace> &, const eosio::chain::signed_transaction &>
>::assign_to<(lambda at /root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
this->assign_to(f);
^
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:1068:5: note: in instantiation of function template specialization
'boost::function1<void, std::tuple<const std::shared_ptr<eosio::chain::transaction_trace> &, const eosio::chain::signed_transaction &>
>::function1<(lambda at /root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
base_type(f)
^
/root/src/boost_1_70_0/include/boost/function/function_template.hpp:1121:5: note: in instantiation of function template specialization 'boost::function<void
(std::tuple<const std::shared_ptr<eosio::chain::transaction_trace> &, const eosio::chain::signed_transaction &>)>::function<(lambda at
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
self_type(f).swap(*this);
^
/root/src/boost_1_70_0/include/boost/signals2/detail/slot_template.hpp:160:24: note: in instantiation of function template specialization
'boost::function<void (std::tuple<const std::shared_ptr<eosio::chain::transaction_trace> &, const eosio::chain::signed_transaction
&>)>::operator=<(lambda at /root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
_slot_function = detail::get_invocable_slot(f, detail::tag_type(f));
^
/root/src/boost_1_70_0/include/boost/signals2/detail/slot_template.hpp:85:9: note: in instantiation of function template specialization
'boost::signals2::slot<void (std::tuple<const std::shared_ptr<eosio::chain::transaction_trace> &, const eosio::chain::signed_transaction &>),
boost::function<void (std::tuple<const std::shared_ptr<eosio::chain::transaction_trace> &, const eosio::chain::signed_transaction &>)>
>::init_slot_function<(lambda at /root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
init_slot_function(f);
^
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13: note: in instantiation of function template specialization 'boost::signals2::slot<void
(std::tuple<const std::shared_ptr<eosio::chain::transaction_trace> &, const eosio::chain::signed_transaction &>), boost::function<void
(std::tuple<const std::shared_ptr<eosio::chain::transaction_trace> &, const eosio::chain::signed_transaction &>)> >::slot<(lambda at
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13)>' requested here
[&](const transaction_trace_ptr& tt) {
^
/root/eosio-watcher-plugin/src/watcher_plugin.cpp:276:13: note: candidate function not viable: no known conversion from 'std::tuple<const
std::shared_ptr<eosio::chain::transaction_trace> &, const eosio::chain::signed_transaction &>' to 'const eosio::chain::transaction_trace_ptr' (aka
'const shared_ptr<eosio::chain::transaction_trace>') for 1st argument
5 errors generated.
additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/build.make:62: recipe for target 'additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/src/watcher_plugin.cpp.o' failed
make[2]: *** [additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/src/watcher_plugin.cpp.o] Error 1
CMakeFiles/Makefile2:4173: recipe for target 'additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/all' failed
make[1]: *** [additional_plugins/9f79a1f6-ce0b-371c-9c87-15c24fbd5e6f/CMakeFiles/watcher_plugin.dir/all] Error 2
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.