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