Peerplays API Libraries
Tools and Integrations
Development Workflow Docs
Other Documentation
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

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 Sidechan Manager, for further processing.

Sequence diagram

Link to draw.io file
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