BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
custom_operations_plugin.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 oxarbitrage and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
26 
28 
29 namespace graphene { namespace custom_operations {
30 
31 namespace detail
32 {
34 {
35  public:
37  : _self( _plugin )
38  { }
39 
40  void onBlock();
41 
43  {
44  return _self.database();
45  }
46 
48 
49  private:
51 
52  uint32_t _start_block = 45000000;
53 };
54 
56 {
57  typedef void result_type;
58  account_id_type _fee_payer;
60 
61  custom_op_visitor(database& db, account_id_type fee_payer) { _db = &db; _fee_payer = fee_payer; };
62 
63  template<typename T>
64  void operator()(T &v) const {
65  v.validate();
67  evaluator.do_apply(v);
68  }
69 };
70 
72 {
74  const vector<optional< operation_history_object > >& hist = db.get_applied_operations();
75  for( const optional< operation_history_object >& o_operation : hist )
76  {
77  if(!o_operation.valid() || !o_operation->op.is_type<custom_operation>())
78  continue;
79 
80  const custom_operation& custom_op = o_operation->op.get<custom_operation>();
81 
82  if(custom_op.data.size() == 0)
83  continue;
84 
85  try {
86  auto unpacked = fc::raw::unpack<custom_plugin_operation>(custom_op.data);
87  custom_op_visitor vtor(db, custom_op.fee_payer());
88  unpacked.visit(vtor);
89  }
90  catch (fc::exception& e) { // only api node will know if the unpack, validate or apply fails
91  wlog("Custom operations plugin serializing error: ${ex} in operation: ${op}",
92  ("ex", e.to_detail_string())("op", fc::json::to_string(custom_op)));
93  continue;
94  }
95  }
96 }
97 
98 } // end namespace detail
99 
101  plugin(app),
102  my( std::make_unique<detail::custom_operations_plugin_impl>(*this) )
103 {
104  // Nothing to do
105 }
106 
108 
110 {
111  return "custom_operations";
112 }
114 {
115  return "Stores arbitrary data for accounts by creating specially crafted custom operations.";
116 }
117 
119  boost::program_options::options_description& cli,
120  boost::program_options::options_description& cfg
121  )
122 {
123  cli.add_options()
124  ("custom-operations-start-block", boost::program_options::value<uint32_t>()->default_value(45000000),
125  "Start processing custom operations transactions with the plugin only after this block")
126  ;
127  cfg.add(cli);
128 
129 }
130 
131 void custom_operations_plugin::plugin_initialize(const boost::program_options::variables_map& options)
132 {
134 
135  if (options.count("custom-operations-start-block") > 0) {
136  my->_start_block = options["custom-operations-start-block"].as<uint32_t>();
137  }
138 
139  // connect with group 0 to process before some special steps (e.g. snapshot or next_object_id)
140  database().applied_block.connect( 0, [this]( const signed_block& b) {
141  if( b.block_num() >= my->_start_block )
142  my->onBlock();
143  } );
144 }
145 
147 {
148  ilog("custom_operations: plugin_startup() begin");
149 }
150 
151 } }
graphene::chain::database
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
graphene::protocol::custom_operation
provides a generic way to add higher level protocols on top of witness consensus
Definition: custom.hpp:38
wlog
#define wlog(FORMAT,...)
Definition: logger.hpp:123
fc::exception
Used to generate a useful error report when an exception is thrown.
Definition: exception.hpp:56
graphene::db::primary_index
Wraps a derived index to intercept calls to create, modify, and remove so that callbacks may be fired...
Definition: index.hpp:312
graphene::app::plugin::database
chain::database & database()
Definition: plugin.hpp:115
graphene::custom_operations::detail::custom_operations_plugin_impl::onBlock
void onBlock()
Definition: custom_operations_plugin.cpp:71
graphene::custom_operations::detail::custom_op_visitor
Definition: custom_operations_plugin.cpp:55
graphene::custom_operations::detail::custom_op_visitor::operator()
void operator()(T &v) const
Definition: custom_operations_plugin.cpp:64
graphene::custom_operations::custom_operations_plugin
Definition: custom_operations_plugin.hpp:41
graphene::chain::database::get_applied_operations
const vector< optional< operation_history_object > > & get_applied_operations() const
Definition: db_block.cpp:566
graphene::chain::database::applied_block
fc::signal< void(const signed_block &)> applied_block
Definition: database.hpp:624
graphene::custom_operations::custom_generic_evaluator
Definition: custom_evaluators.hpp:30
graphene::custom_operations::custom_operations_plugin::plugin_set_program_options
void plugin_set_program_options(boost::program_options::options_description &cli, boost::program_options::options_description &cfg) override
Fill in command line parameters used by the plugin.
Definition: custom_operations_plugin.cpp:118
fc::json::to_string
static string to_string(const variant &v, output_formatting format=stringify_large_ints_and_doubles, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:650
graphene::protocol::block_header::block_num
uint32_t block_num() const
Definition: block.hpp:34
graphene::app::application
Definition: application.hpp:91
graphene::custom_operations::detail::custom_operations_plugin_impl::custom_operations_plugin_impl
custom_operations_plugin_impl(custom_operations_plugin &_plugin)
Definition: custom_operations_plugin.cpp:36
ilog
#define ilog(FORMAT,...)
Definition: logger.hpp:117
graphene::db::object_database::add_index
IndexType * add_index()
Definition: object_database.hpp:144
graphene::custom_operations::detail::custom_op_visitor::_fee_payer
account_id_type _fee_payer
Definition: custom_operations_plugin.cpp:58
graphene::custom_operations::detail::custom_operations_plugin_impl::database
graphene::chain::database & database()
Definition: custom_operations_plugin.cpp:42
graphene::custom_operations::detail::custom_operations_plugin_impl
Definition: custom_operations_plugin.cpp:33
graphene::chain::evaluator
Definition: evaluator.hpp:142
fc::exception::to_detail_string
std::string to_detail_string(log_level ll=log_level::all) const
Definition: exception.cpp:183
graphene::custom_operations::custom_operations_plugin::plugin_name
std::string plugin_name() const override
Get the name of the plugin.
Definition: custom_operations_plugin.cpp:109
graphene::custom_operations::custom_operations_plugin::plugin_initialize
void plugin_initialize(const boost::program_options::variables_map &options) override
Perform early startup routines and register plugin indexes, callbacks, etc.
Definition: custom_operations_plugin.cpp:131
graphene::protocol::custom_operation::fee_payer
account_id_type fee_payer() const
Definition: custom.hpp:51
graphene::custom_operations::custom_operations_plugin::plugin_startup
void plugin_startup() override
Begin normal runtime operations.
Definition: custom_operations_plugin.cpp:146
graphene::protocol::custom_operation::data
vector< char > data
Definition: custom.hpp:49
operation_history_object.hpp
custom_operations_plugin.hpp
std
Definition: zeroed_array.hpp:76
graphene::custom_operations::detail::custom_op_visitor::_db
database * _db
Definition: custom_operations_plugin.cpp:59
graphene::custom_operations::custom_operations_plugin::plugin_description
std::string plugin_description() const override
Get the description of the plugin.
Definition: custom_operations_plugin.cpp:113
graphene::custom_operations::custom_operations_plugin::custom_operations_plugin
custom_operations_plugin(graphene::app::application &app)
Definition: custom_operations_plugin.cpp:100
fc::optional
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
graphene::custom_operations::detail::custom_op_visitor::custom_op_visitor
custom_op_visitor(database &db, account_id_type fee_payer)
Definition: custom_operations_plugin.cpp:61
graphene::protocol::signed_block
Definition: block.hpp:64
graphene
Definition: api.cpp:48
graphene::custom_operations::custom_operations_plugin::~custom_operations_plugin
~custom_operations_plugin() override
graphene::custom_operations::detail::custom_op_visitor::result_type
void result_type
Definition: custom_operations_plugin.cpp:57