generic-sidechain-high-level-design
Objective
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.
Assumptions
- 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… 
Block Diagram
Link to Draw.io file
https://drive.google.com/file/d/1BXeRwK_2PNt6wMnzIl8M6OMRnuM5CumQ/view?usp=sharing
Description
- 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 Sidechain Manager, for further processing. 
Sequence diagram
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.
Suggested implementation
- 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 
 
 
};
- 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 
 
 
- 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 
 
 
- 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 
 
Last updated
Was this helpful?
