This document is intended to outline generic design of sidechain plugin used by Peerplays Node, to monitor and process events of interest on a target sidechain nodes. This interface will be extended to meet various other integrations.
- Sidechain plugin purpose is to monitor and process events of interest on a multiple target sidechains.
- Sidechain node provides interface for monitoring changes in a sidechain.
- Monitoring is based on new block, new transaction or filtered single event (like transfer operation to specific address).
- There is a sufficient C/C++ library for connecting to monitoring interface.
- Sidechain node provides communication interface which sidechain handler can use to read all the required info about event of interest. E.g. HTTP/RPC…
Link to Draw.io file
https://drive.google.com/file/d/1BXeRwK_2PNt6wMnzIl8M6OMRnuM5CumQ/view?usp=sharing
- Peerplays Sidechain is implemented as a plugin.
- Sidechain Manager is a component in a Peerplays Plugin, which contains a collection of Sidechain Handlers.
- No multiple sidechain handlers for same network is allowed.
- No communication between sidechain handlers is allowed or needed.
- One Sidechain Handler handles only one sidechain network.
- Each Sidechain Handler monitors and processes events of interests on its target network.
- Each Sidechain Handler implements only sidechain specific processing, eg reading transaction info, parsing transaction data, etc…
- The result of Sidechain Handler processing saved into peerplays network for further processing
- In general, Sidechain Handler contains event listener, communication interface and event handler.
- Event listener is “listening” for events on a sidechain. When event happens, event listener will notify event handler about incoming event.
- Event handler uses communication interface to read all the information needed in order to process the event.
- Once the processing is finished, event handler will pass the result to the Sidechan Manager, for further processing.
Link to draw.io file
https://drive.google.com/file/d/17kbez7C1Djaj-2AgyEzQ1Z-5CrSZ5wZE/view?usp=sharing
For the simplicity, sequence diagram shows interactions between components in a single sidechain handler.
- peerplays_sidechain_plugin is a class implementing a peerplays sidechain plugin.
- Contains the instance of sidechain_manager
- sidechain_manager is a class implementing Sidechain Manager
- Contains the collection (std::vector) of sidechain_handlers
- Contains the factory method for creating instance of sidechain_handler for particular sidechain
- Factory method parameters include program options, used to pass configure options to a sidechain handler
- Contains methods for calling sidechain_handlers methods for processing events of interest
- recreate_primary_wallet This method will initiate recreation of primary wallet on active SON set change, if needed
- process_deposits This method will call sidechain handlers method for processing sidechain deposits
- process_withdrawals This method will call sidechain handlers method for processing sidechain withdrawals
- sidechain_handler is a base class for implementing sidechain handlers
- Needs to have access to user sidechain address mapping list, in order to filter events by checking addresses involved in a transaction against the list of addresses of interests.
- sidechain_type get_sidechain() Gets the sidechain type
- std::vectorstd::string get_sidechain_deposit_addresses() Gets the list of deposit addresses for a sidechain
- std::vectorstd::string get_sidechain_withdraw_addresses() Gets the list of withdrawal addresses for a sidechain
- std::string get_private_key(std::string public_key) Gets the private key for a given public key, for signing sidechain transactions
- Needs to contain method receiving the data structure describing event of interest as the parameter
- sidechain_event_data_received(const sidechain_event_data &sed)
- // Sidechain type
- enum class sidechain_type {
- bitcoin,
- ethereum,
- eos,
- peerplays
- };
- struct sidechain_event_data {
- fc::time_point_sec timestamp; // time when event was detected
- sidechain_type sidechain; // sidechain where event happened
- std::string sidechain_uid; // transaction unique id for a sidechain
- std::string sidechain_transaction_id; // transaction id on a sidechain
- std::string sidechain_from; // sidechain senders account, if available
- std::string sidechain_to; // sidechain receiver account, if available
- std::string sidechain_currency; // sidechain transfer currency
- fc::safe<int64_t> sidechain_amount; // sidechain asset amount
- chain::account_id_type peerplays_from; // perplays senders account matching sidechain senders account
- chain::account_id_type peerplays_to; // peerplays receiver account matching sidechain receiver account
- chain::asset peerplays_asset; // transfer value in peerplays core asset
- Needs to have access to user sidechain address mapping list, in order to filter events by checking addresses involved in a transaction against the list of addresses of interests.
};
-
- For deposits, sidechain handler will create deposit descriptor object son_wallet_deposit_object, using data from sidechain_evend_data structure
- class son_wallet_deposit_object : public abstract_object<son_wallet_deposit_object>
- {
- public:
- static const uint8_t space_id = protocol_ids;
- static const uint8_t type_id = son_wallet_deposit_object_type;
- time_point_sec timestamp;
- peerplays_sidechain::sidechain_type sidechain;
- int64_t confirmations;
- std::string sidechain_uid;
- std::string sidechain_transaction_id;
- std::string sidechain_from;
- std::string sidechain_to;
- std::string sidechain_currency;
- safe<int64_t> sidechain_amount;
- chain::account_id_type peerplays_from;
- chain::account_id_type peerplays_to;
- chain::asset peerplays_asset;
- bool processed;
};
-
- For withdrawals, sidechain handler will create withdrawal descriptor object son_wallet_withdraw_object, using data from sidechain_event_data structure
- class son_wallet_withdraw_object : public abstract_object<son_wallet_withdraw_object>
- {
- public:
- static const uint8_t space_id = protocol_ids;
- static const uint8_t type_id = son_wallet_withdraw_object_type;
- time_point_sec timestamp;
- peerplays_sidechain::sidechain_type sidechain;
- int64_t confirmations;
- std::string peerplays_uid;
- std::string peerplays_transaction_id;
- chain::account_id_type peerplays_from;
- chain::asset peerplays_asset;
- peerplays_sidechain::sidechain_type withdraw_sidechain;
- std::string withdraw_address;
- std::string withdraw_currency;
- safe<int64_t> withdraw_amount;
- bool processed;
};
-
- Contains following abstract methods (the list can change anytime):
- virtual void recreate_primary_wallet() = 0; Method is called by sidechain manager, to recreate the primary wallet on a sidechain, if needed
- virtual void process_deposit(const son_wallet_deposit_object &swdo) = 0; Callback method, called for each deposit that needs to be processed by a sidechain handler
- virtual void process_withdrawal(const son_wallet_withdraw_object &swwo) = 0;
- Callback method, called for each withdrawal that needs to be processed by a sidechain handler
- Contains following abstract methods (the list can change anytime):
- sidechain_handler_bitcoin is a class, inheriting sidechain_handler, implementing sidechain handler for Bitcoin
- Listener may be implemented by ZeroMQ (also spelled ØMQ, 0MQ or ZMQ), high-performance asynchronous messaging library
- Communication interface may be implemented as HTTP client, using RPC bitcoin node interface
- Implement any RPC call that might be needed
- std::string addmultisigaddress(const std::vector<std::string> public_keys);
- std::string createrawtransaction(const std::vector<btc_txout> &ins, const fc::flat_map<std::string, double> outs);
- std::string createwallet(const std::string &wallet_name);
- std::string encryptwallet(const std::string &passphrase);
- uint64_t estimatesmartfee();
- std::string getblock(const std::string &block_hash, int32_t verbosity = 2);
- void importaddress(const std::string &address_or_script);
- std::vector<btc_txout> listunspent();
- std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount);
- std::string loadwallet(const std::string &filename);
- void sendrawtransaction(const std::string &tx_hex);
- std::string signrawtransactionwithkey(const std::string &tx_hash, const std::string &private_key);
- std::string signrawtransactionwithwallet(const std::string &tx_hash);
- std::string unloadwallet(const std::string &filename);
std::string walletlock();
-
- Implements abstract methods:
- void recreate_primary_wallet() override; Method is called by sidechain manager, to recreate the primary wallet on a sidechain, if needed
- void process_deposit(const son_wallet_deposit_object &swdo) override; Callback method, called for each deposit that needs to be processed by a sidechain handler
- void process_withdrawal(const son_wallet_withdraw_object &swwo) override; Callback method, called for each withdrawal that needs to be processed by a sidechain handler
- Implements abstract methods:
- sidechain_handler_ethereum is a class, inheriting sidechain_handler, implementing sidechain handler for Ethereum
- TBD
- sidechain_handler_eos is a class, inheriting sidechain_handler, implementing sidechain handler for EOS
- TBD
- sidechain_handler_peerplays is a class, inheriting sidechain_handler, implementing sidechain handler for Peerplays
- Listener can be implemented as a callback of database.applied_block signal. This will give us access to newly created blocks, and its content.
- Communication interface, like RPC client from Bitcoin handler, is not really needed, as we can read all the data we need from blockchain database.
- Implements abstract methods:
- void recreate_primary_wallet() override; Method is called by sidechain manager, to recreate the primary wallet on a sidechain, if needed
- void process_deposit(const son_wallet_deposit_object &swdo) override; Callback method, called for each deposit that needs to be processed by a sidechain handler
- void process_withdrawal(const son_wallet_withdraw_object &swwo) override; Callback method, called for each withdrawal that needs to be processed by a sidechain handler
- sidechain_handler_* is a class, inheriting sidechain_handler, implementing sidechain handler for *
- Any future sidechain
- TBD