arrow-left

All pages
gitbookPowered by GitBook
1 of 8

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

System Architecture

Components that implement blockchain and consensus protocol

The Energy Web Chain is comprised of different components that provide the functionalities determined by the blockchain’s protocol.

Broadly speaking, protocols are defined rules and standards. Internet protocols, like HTTP protocol for example, define standard procedures for the transfer of data over the internet.

A blockchain network is no different. In a decentralized and self-executing system like a public blockchain, protocols are of significant importance in establishing how the system works, and then ensuring that the system continues to self-execute as designed.

Protocols exist to determine specific aspects of blockchain behavior, such as:

  • How transactions are validated

  • Who gets to validate transactions and when

  • How validators are compensated

  • How peer nodes interact with each other

The system components below ensure that the Energy Web blockchain adheres to Ethereum's protocols, and the protocols established by OpenEthereum's . (OpenEthereum is the Ethereum client that is used by the Energy Web Chain. You can read more about the purpose of Ethereum clients )

hashtag
System Components

hashtag

System Contracts are that implement the protocols. Read more about Energy Web's system contracts

hashtag

The validator node architecture monitors validator behavior to ensure consistent and secure blockchain operation. Read more about the validator node architecture

hashtag
Related Content

Proof-of-Authority consensus enginearrow-up-right
here.
1. System Contracts
smart contracts arrow-up-right
Authority Roundtable Proof-of-Authority consensus enginearrow-up-right
here.
2. Validator Node Architecture
here.
Proof-of-Authority Consensus Mechanismchevron-right
Validator Node Architecturechevron-right

Name Registry

Energy Web has deployed OpenEthereum's Name Registry contract.arrow-up-right This contract is identical to OpenEthereum's original contract, with the exception that it was made Ownable by Energy Web Foundation. Only Energy Web can reserve a name or drain funds from this contract.

There are two reasons for making this contract Ownable:

  1. OpenEthereum's name registry might be needed for other OpenEthereum related system contracts later: e.g. service transaction checkerarrow-up-right, or auto updaterarrow-up-right.

  2. We will have the official system set up on the chain, so this contract is only needed for internal purposes and will not be used publicly.

The name registry is a placeholder for now. The contract can be found in our repo:

hashtag
Interacting with the Name Registry Contract

hashtag
Contract Address and ABI

hashtag
Callable Functions

Returns an unsigned integer data value from an entry, given its key.

getOwner(bytes32)

Returns the owner of an entry.

hasReverse(bytes32)

Returns true if entry has a reverse address registered.

getReverse(bytes32)

Returns reverse address of an entry.

canReverse(address)

Returns true if address can have a reverse.

reverse(address)

Returns the reverse value of an address.

reserved(bytes32)

Returns true if the name (its sha3 hash) is already reserved.

Contract

Address

JSON ABI

SimpleRegistry

0x1204700000000000000000000000000000000006

https://gist.github.com/ngyam/255a461e2241085a6530d455f7c15529arrow-up-right

Function

Description

entries(bytes32)

Returns an entry based on the sha3 hash of the name registered.

reverse(address)

Reverse resolution of an address.

fee()

Returns the fee for reserving a name (not really relevant to public).

getData(bytes32,string)

Returns a string data value from an entry, given its key.

getAddress(bytes32,string)

Returns an address data value from an entry, given its key.

Ethereum Name Servicearrow-up-right
https://github.com/energywebfoundation/ewc-system-contracts/tree/master/contracts/registryarrow-up-right

getUint(bytes32,string)

Proof-of-Authority Consensus Mechanism

hashtag
Blockchain Consensus

In a centralized system, such as a bank or a broker, a designated authority or central operating system would be in charge of adding transactions or information to the system, making sure that each transaction is trustworthy, up to date with the whole system, and does not duplicate previous transactions.

In contrast, public blockchains are decentralized, peer-to-peer systems that have no central authority or oversight like this. Designated actors are responsible for processing transactions, creating new blocks and maintaining the integrity and history of previous blocks.

The system for determining these actors and how they are selected is called a . These mechanisms determine the process of who can confirm transactions and create new blocks on the blockchain and the protocol for how they do so. Because there is no central oversight, consensus needs to be designed in a way that prevents or disincentivizes malicious or uninformed actors from corrupting the integrity of the chain.

There are many consensus algorithms. You may have heard of some widely used ones like or . Each mechanism has its own way of determining who is eligible to process transactions and create new blocks, and how how actors are selected to do so.

The Energy Web Chain uses the Proof-of-Authority (PoA) consensus mechanism.

All consensus mechanisms have disadvantages and advantages and are chosen based on the purpose and use case of the blockchain it will be serving.

hashtag

The Proof-of-Authority (PoA) consensus mechanism has a defined set of actors that validate transactions and propagate new blocks to the chain. Rather than competing or staking for a chance to add blocks, they take turns creating new blocks in a round-robin style. These actors are called validators.

Energy Web validators participate by of the blockchain using . Smart contracts called Validator-Set contracts have the functionality to add or remove validators. Anyone can run a full node of the blockchain, but only addresses that are included in the Validator-Set contracts can validate transactions and seal blocks. You can read about the Energy Web Chain's Validator Set Contracts .

The Energy Web Chain uses a specific type of PoA called . The AuRa Proof-of-Authority consensus mechanism can be used by blockchains that run the OpenEthereum client.

circle-info

For more in-depth information on Proof-of-Authority, read the

hashtag
Energy Web Chain Validators

In other consensus mechanisms, such as Proof-of-Work or Proof-of-Stake, miners can remain anonymous. So long as they meet the proof-of-work or staking requirements, they can process transactions on the blockchain and in many cases do so anonymously.

Validators are not anonymous. They have applied to become a validator and have undergone a a KYC (“Know Your Customer”) process as part of their application. Our validators are well-known members of the energy community, and the to become a validator, and they have a vested interest in the Energy Web Chain’s performance. You can see a full list of Energy Web Chain validators

hashtag
Validator Functions

  1. Validators create blocks: The fundamental role of the validator is to validate, compile valid transactions into and propagate new blocks to the network.

  2. Validators provide network security: By storing the current and historical state of the Energy Web Chain, each validator contributes to the overall integrity and security of the network. Since at least 51% of validators are required to sign each block before it is finalized on the chain, validators provide checks and balances against any erroneous or malicious attempts to publish falsified transactions or alter historical data. Physical decentralization of validator nodes provides redundancy in the event that one or more validators is unavailable due to technical reasons or otherwise compromised.

hashtag
Why Proof-of-Authority?

Energy Web uses Proof-of-Authority consensus for three primary reasons that benefit the Energy Web’s digital infrastructure, the energy sector that will use the technology, and the environment as a whole.

  1. To enable transaction capacity on the order of hundreds to thousands of transactions per second: we estimate that the Energy Web Chain has the ability to achieve 30x greater throughput capacity than the Ethereum Mainnet;

  2. To minimize resource (i.e. electricity and computation) consumption, and subsequently, transaction costs: Eliminating competitive Proof-of-Work results in 54,000x less energy consumption and 350x lower network costs (i.e. costs incurred by organizations hosting validator nodes) which translates into lower and more stable transaction costs;

  3. To improve compliance with relevant regulations and business requirements in the energy sector: substituting fully anonymous miners for vetted validators enhances the ability of decentralized applications to comply with various regulations, including data-protection regulations like

To improve compliance with relevant regulations and business requirements in the energy sector: substituting fully anonymous miners for vetted validators enhances the ability of decentralized applications to comply with various regulations, including data-protection regulations like , and increases the likelihood of widespread user and enterprise adoption.

hashtag
Proof-of-Authority Process

At a high level, the PoA mechanism works as follows:

  1. All validator nodes maintain a complete list of the validators, identified by public keys. This list changes as validators are added or removed. In addition to storing the current and historical state of the network, all validators maintain essential information about the network (such as synchronized timing information and current data processing limits).

  2. For a defined time window, one validator is assigned as the primary validator via the PoA algorithm. During this time, they are responsible for collecting the broadcasted transactions and proposing the new block. Only one validator is designated as primary at a time–based on a calculation derived from the timestamp on synchronized clocks among the validator nodes in the network and the number of validators–in order to prevent validators from arbitrarily creating blocks at irregular intervals.

hashtag
Additional Resources

Validators participate in the: Validators will be asked to offer opinions and contribute to technical and non-technical decisions relating to modifications of the Energy Web client, protocol and validator set.
, and increases the likelihood of widespread user and enterprise adoption.
If a validator fails to create a block when it is selected (e.g., because of hardware problems on the side of the validator) or its block fails to be validated by the pool of nodes (e.g., because of network connectivity problems), the next validator proceeds to create a block with whatever transactions haven’t been processed.
  • The remaining validator nodes verify that the transactions in each block are legitimate for that time window, sign the block with their private keys, and propagate the signed block to the network.

  • Once a simple majority of validators have authored a block on top of a given signed block, finality is achieved for that given block, and the block is confirmed by the network and added to the chain.

  • consensus mechanismarrow-up-right
    Proof-of-Workarrow-up-right
    Proof-of-Stakearrow-up-right
    You can read more about why Energy Web employs the Proof-of-Authority mechanisms below.
    Proof-of-Authority Consensusarrow-up-right
    running full nodes
    OpenEthereum client softwarearrow-up-right
    here
    Authority Roundtable (AuRa)arrow-up-right
    You can read more about the validator process below.
    Authority Roundtable Proof-of-Authority white paperarrow-up-right
    meet the eligibility requirementsarrow-up-right
    hardware/software installation specificationsarrow-up-right
    here.arrow-up-right
    Proof-of-Authorityarrow-up-right
    transactionsarrow-up-right
    blocksarrow-up-right
    GDPRarrow-up-right
    AuRa Proof-of-Authority white paperarrow-up-right
    “What is "proof of work" and "proof of stake"? On CoinBasearrow-up-right
    “Blockchain Consensus: A Simple Explanation Anyone Can Understand” on Blockgeeksarrow-up-right
    the Energy Web Chain's governancearrow-up-right
    GDPRarrow-up-right

    Block Reward Contract

    hashtag
    Overview

    The Block Reward contract manages block reward payouts to validators. Block rewards are issued as native Energy Web tokens that are minted by the engine.

    Two entities are rewarded by each created block:

    1. The block author (validator)

    hashtag
    Documentation and Source Code

    hashtag
    Block Reward Payouts

    hashtag
    Block Authors

    Block authors are rewarded each time they seal a block. The amount issued to block authors decreases over time, as depicted by the Discreet S Curve.

    Calculator:

    hashtag
    Energy Web Community Fund

    A portion of block rewards goes to the Community Fund. Unlike the amount awarded to block authors, the amount that goes to the Community Fund remains constant over time.

    The amount is chosen to add up to roughly 37.9 million tokens over a 10 year period. The community fund can change its own address and set a payout address too.

    With 5 second step size: Payout-per-block = 600900558100000000 wei

    Visual representation of the community reward distribution is depicted below in Fig. 3.

    hashtag
    Interaction with Block Reward Contract

    hashtag
    Contract Address and ABI

    hashtag
    Callable functions

    Validator Node Architecture

    Components for running a validator node and monitoring validator behavior

    The system architecture of a validator node on the Energy Web Chain is made up of two components:

    Together these two components allow validators to run a local node of the chain, validate transactions, seal blocks, and monitor validator behavior and metrics.

    Holding Contract

    hashtag
    Overview

    The Holding Contract holds tokens for initial investors. These tokens are "pre-mined", and do not enter the pool through block validation. Tokens are held for affiliates until a specific point of time that is specified in the contract, at which point they can be released to the specified address. The constructor of the holding contract and its initial balance is part of the chainspec file. This allows the investors' tokens to be locked at the first block.

    The mapping between the account address and the token amount is hard coded into the contract and cannot be changed after deployment. After a block that has a later timestamp than the holding timestamp of an address is created, the tokens for that address can be transferred to the address by calling the realeaseFunds method. This method can be called by anyone, not only by the address that holds that balance.

    Returns how much was minted for a certain account in a certain block in wei

    communityFundAmount()

    Returns the constant payout for the community per block in wei

    communityFund()

    Returns community fund address

    payoutAddresses(address)

    Returns an address' payout address

    setPayoutAddress(address)

    Sets payout address for sender

    resetPayoutAddress()

    Resets payout address for sender

    getBlockReward(uint256)

    Returns blockreward amount for a certain block number

    checkRewardPeriodEnded()

    Returns true if blockreward period has ended (based on blocknumber), false otherwise. The blockreward period right now ends after 10 years. After that no blockrewards or community fund payouts are minted.

    Name

    Address

    JSON ABI

    RewardContract

    0x1204700000000000000000000000000000000002

    https://gist.github.com/ngyam/07d34631fa0e899e5896303b5ec92a3carrow-up-right

    Function Name

    Description

    mintedTotally()

    Returns the token amount that was minted totally in wei

    mintedForCommunity()

    Return the token amount that was totally minted for the community fund in wei

    mintedForCommunityForAccount(address)

    Returns the total token amount that was minted for a certain address for the community so far in wei

    mintedForAccount(address)

    Return how much was minted for an account so far in wei

    mintedInBlock(uint256)

    Returns how much was minted in certain block in wei

    The community fundarrow-up-right
    Energy Web Block Reward Contractarrow-up-right
    OpenEthereum documentation on Block Reward Contractarrow-up-right
    https://github.com/energywebfoundation/discrete-scurve-calculatorarrow-up-right
    Interaction graph for the block reward contract
    Fig. 2.: Discrete inverse S curve use for block rewards. Calculated for a 5 second step size, 10 million ethers total payout over 10 years
    Fig. 3.: Community reward distribution.

    mintedForAccountInBlock(address, uint256)

    hashtag
    OpenEthereum Client

    A client is software that allows you to run a local node on your machine and interact directly with the blockchain. Every validator must run a full node in order to participate in validation.

    Remember that the Energy Web Chain is derived from the Ethereum blockchain. Because of this we use an Ethereum client to connect with the chain called OpenEthereumarrow-up-right. Anyone can create a client, as long as it implements the protocols laid out in Ethereum’s yellow paperarrow-up-right, and there are a number of Ethereum clients to choose from.

    Energy Web uses the OpenEthereum client because it supports the Authority Roundtable (AuRa)arrow-up-right, which is a consensus algorithm specifically for Proof-ofAuthority blockchains. OpenEthereum allows validators to connect to the chain, collect transactions and seal blocks according the AuRa consensus algorithm.

    To read more about OpenEthereum, you can visit their wiki.arrow-up-right

    To read more about Ethereum clients, see the Ethereum documentation.arrow-up-right

    hashtag
    Telemetry Monitoring system

    The monitoring system collects comprehensive, real-time data and metrics on validator performance and provides a user interface for viewing the data. It is important to gather as much data about the validator nodes as possible in order to ensure a secure and performant blockchain. To do so, we rely on well established industry solutions to transfer these metrics off the validator node to protect the sensitive nature of the data.

    The use of the telemetry monitoring system is opt-in. Validators can disable it if they have their own monitoring system in place that allows for real time tracking of all relevant metrics.

    hashtag
    Telemetry Architecture

    There are four components involved in the data collection process:

    • OpenEthereumarrow-up-right client - monitors validator node behavior

    • Telegrafarrow-up-right: open-source server agent that collects data from the OpenEthereum client

    • InfluxDBarrow-up-right - open source database that stores the data collected from Telegraf

    • - data visualization tool that queries the InfluxDB for data and provides graphical interface for data visualization

    All components are run in separate docker containers managed by docker compose. For additional information on docker visit: https://docs.docker.com/arrow-up-right and https://docs.docker.com/compose/arrow-up-right.

    hashtag
    Data Collection Process Overview

    1. The OpenEthereum client collects data on the validator node. Collected data includes:

      • CPU usage

      • Memory usage

      • Disk usage

      • Number of connected peers

      • List of visible P2P peers

      • Current block

      • Network latency to 3 different and major locations (e.g. cloudflare, google, amazon)

      • Network throughput

      • Network error rate

      • Number of SSH keys

      • Service status for SSH, docker and the parity container

      • SHA256 hashes of key system components/binaries

      • Current chain specification file (or hash)

    2. Telegraf collects relevant metrics from the host machine and the custom-built OpenEthereum metrics collector. The metrics collector allows Telegraf to receive the metrics from the OpenEthereum client

    3. The collected metrics are stored in an InfluxDB database and can be visualized using Grafana

    The OpenEthereum Client
    Telemetry monitoring system
    Interaction with Holding Contract

    hashtag
    Documentation and Source Code

    • Energy Web Holding Contract arrow-up-right

    hashtag
    Check a Balance and Withdraw Funds

    If you're an investor and want to see your balance, you can use the Balance Viewer interface: http://balance.energyweb.org/arrow-up-right.arrow-up-right

    You will need MetaMask pointed to a local or a remote node

    • To learn how to connect via remote RPC, go here

    • To learn how to run a local node go here

    1. Enter your address in the lookup field to see your holding balance

    2. If the release period has ended, press the "Withdraw" button to release the funds to the address it belongs to. Make sure you trigger the withdraw function with an account that has some ethers to cover transaction costs

    Holding Contract User Interface

    hashtag
    Mapping Between Address and Tokens

    The mapping between addresses and tokens/release timestamp is kept in the storage of this contract. This mapping data structure was filled at the deploy time of the contract and cannot be changed.

    hashtag
    Interacting with the Holding Contract

    hashtag
    Contract Address and ABI

    Contract

    Address

    JSON ABI

    Holding

    0x1204700000000000000000000000000000000004

    hashtag
    Callable Functions

    Function Name

    Description

    releaseFunds(address)

    Releases funds for a holding address if it is present in the contract and the holding period is over

    holders(address)

    Returns the holding data for an address, the available amount and the holding-period-end blocktimestamp

    TARGET_AMOUNT()

    Returns the total amount initially held by the contract

    Validator-Set Contracts

    hashtag
    Overview

    Validator Set contracts provide information on current validators and private functionality to add and remove validators.

    Validator set components

    hashtag
    Documentation and Source Code

    hashtag
    Components

    For upgradeability purposes, the contracts are divided into 2 parts. See below Fig. 1.

    hashtag
    RelaySet Contract

    This contract implements the required interface expected by the engine and it is the contract defined in the chainspec seen by the engine. It relays most of the function calls to the RelayedSet contract, which holds the actual logic. The logic contract can be replaced (upgraded), so it is possible to change the behavior of validator management without conducting a hard fork.

    hashtag
    RelayedSet Contract

    This contract implements the logic and manages the validator list. The owner of the validator set interacts with this contract for managing the validators. This contract maintains two validator sets:

    1. The current validator set (the validators who are actively sealing)

    2. The migration validator set, which is the new set we migrate to in case of a change (validator addition or removal).

    hashtag
    Validator States

    Validators and potential validators have four states in these contracts:

    1. Active validator: Validator is in the active validator set, sealing new blocks

    2. Not a validator: The address nothing has to do with validation.

    3. Pending To Be Added Validator: Validator is already added by the owner and their acceptance is pending, but not active yet until it is finalized. This implies that the validator cannot report, be reported, or produce blocks yet.

    hashtag
    Reporting

    The RelayedSet contract logs malicious or benign reports by emitting corresponding log events that can be seen by anyone. Reporting can only be on and about active sealing validators.

    The events contain the reporter- and reported address, and the block number which the validator was reported on.

    hashtag
    Interaction with RelayedSet (logic) Contract

    hashtag
    Callable functions

    hashtag
    Events you can listen to, in addition to report events:

    hashtag
    Interaction with Relay Contract

    hashtag
    Callable functions

    hashtag
    Events you can listen to:

    mapping (address => Holder) public holders;
    
    // -- snip --
    
    struct Holder {
        uint256 availableAmount;
        uint256 lockedUntilBlocktimestamp;
    }
    
    // -- snip --
    
    // in the constructor
    addHolding(0x120470000000000000000000000000000000000a, 10000000000000000000000000, 1564509540);

    Pending To Be Removed Validator: Validator is pending to be removed (removed by the owner), but it is not finalized, and so is still active as a validator. This implies that as long as the removal is not finalized, the validator is actively producing blocks, can report and can be reported on.

    Returns the number of currently active validators

    isPendingToBeAdded(address)

    Returns true if address is pending to be added to the active list.

    isPendingToBeRemoved(address)

    Returns true if address is pending to be removed from the active list.

    isPending(address)

    Returns true if address is pending to be added or removed.

    isActiveValidator(address)

    Returns true if address is an active validator, meaning it partakes in producing new blocks. Note that a validator who is pending to be removed is still active.

    isFinalizedValidator(address)

    Returns true if address is a finalized validator, meaning it is active and NOT pending to be removed either.

    Name

    Address

    JSON ABI

    ValidatorSetRelayed

    0x1204700000000000000000000000000000000001

    https://gist.github.com/ngyam/62a6702dc32edbad9b4421179cfaad30arrow-up-right

    Function

    Description

    finalized()

    Returns true if there are ongoing changes to the active set, false otherwise. If true, implies that current validators list equals migration validators list.

    addressStatus(address)

    Returns the state of an address, two integers: an integer representing the validator state, and an index value. The index is the position of the validator address in the currentValidators array. It is only relevant if the address is an active validator, should be ignored otherwise.

    The validator state mappings are:

    • NonValidator: 0

    • Finalized: 1

    • PendingToBeAdded: 2

    • PendingToBeRemoved: 3

    getValidators()

    Returns currently active block producing validators

    getMigrationValidators()

    Returns the migration validator set. If there are no changes, it returns the same list as getValidators().

    getUnion()

    Returns the union of current and migration sets. Useful for tracking the statuses of all affected validators in case of an ongoing change

    Function Name

    Description

    getSystemAddress()

    Returns the system address

    getValidators()

    Same as RelayedSet getValidators()

    relayedSet()

    Returns the address of the Relayed contract

    Energy Web Validator Set Contractsarrow-up-right
    OpenEthereum documentation on Validator Set contractsarrow-up-right
    reporting ValidatorSetarrow-up-right

    getValidatorsNum()

    Grafanaarrow-up-right
    https://gist.github.com/ngyam/4393eb96ada896b62afc922b760c6802arrow-up-right

    System Contracts

    System contracts are the Energy Web Chain's smart contractsarrow-up-right that implement OpenEthereum's protocols for Aura Proof-of-Authority consensus mechanismarrow-up-right.

    Energy Web's smart contracts are open-sourced, and you can see them on github here. arrow-up-right

    • Validator Set Contracts - manage validator permissioning and behavior

    • - manages validator block rewards

    • - manages the initial disbursement of pre-mined energy web tokens

    hashtag
    Implementing Client Protocol

    System contracts are the Energy Web Chain’s smart contracts that implement . These protocols determine what actions can be taken on the network.

    In order to adhere to the expected protocol, the Energy Web Chain’s system contracts must implement the interfaces that are expected by the AuRa consensus engine, so that it can conform to the client’s protocols.

    Let’s take contract as an example.

    The OpenEthereum documentation specifies that “A simple validator contract has to have the following interface”

    Now let’s look at Energy Web’s .

    You can see that this smart contract implements all of the functions of the Validator-Set protocol interface that was specified above.

    hashtag
    Energy Web System Contracts

    • - manage validator behavior

    • - manages validator block rewards

    • - manages the initial disbursement of pre-mined energy web tokens to a group of initial supporting affiliates

    event ReportedMalicious(address indexed reporter, address indexed reported, uint indexed blocknum);
    event ReportedBenign(address indexed reporter, address indexed reported, uint indexed blocknum);
    event ChangeFinalized(address[] validatorSet);
    event NewRelay(address indexed relay);
    event NewRelayed(address indexed old, address indexed current);
    Reward Contract
    Holding Contract
    OpenEthereum’s permissioning protocolsarrow-up-right
    OpenEthereum's Validator-Setarrow-up-right
    ValidatorSetRelay smart contractarrow-up-right
    Validator Set Contracts
    Reward Contract
    Holding Contract
    [
        {
            "constant": false,
            "inputs": [],
            "name": "finalizeChange",
            "outputs": [],
            "payable": false,
            "type": "function"
        },
        {
            "constant": true,
            "inputs": [],
            "name": "getValidators",
            "outputs": [
                {
                    "name": "_validators",
                    "type": "address[]"
                }
            ],
            "payable": false,
            "type": "function"
        },
        {
            "anonymous": false,
            "inputs": [
                {
                    "indexed": true,
                    "name": "_parent_hash",
                    "type": "bytes32"
                },
                {
                    "indexed": false,
                    "name": "_new_set",
                    "type": "address[]"
                }
            ],
            "name": "InitiateChange",
            "type": "event"
        }
    ]
    pragma solidity 0.5.8;
    
    import "../misc/Ownable.sol";
    import "../interfaces/IValidatorSetRelay.sol";
    import "../interfaces/IValidatorSet.sol";
    import "../interfaces/IValidatorSetRelayed.sol";
    
    
    /// @title Validator Set Relay contract
    /// @notice This owned contract is present in the chainspec file. The Relay contract
    /// relays the function calls to a logic contract called Relayed for upgradeability
    contract ValidatorSetRelay is IValidatorSet, IValidatorSetRelay, Ownable {
    
        /// System address, used by the block sealer
        /// Not constant cause it is changed for testing
        address public systemAddress = 0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE;
        
        /// Address of the inner validator set contract
        IValidatorSetRelayed public relayedSet;
    
        /// Emitted in case a new Relayed contract is set
        event NewRelayed(address indexed old, address indexed current);
    
        modifier nonDefaultAddress(address _address) {
            require(_address != address(0), "Address cannot be 0x0");
            _;
        }
    
        modifier onlySystem() {
            require(msg.sender == systemAddress, "Sender is not system");
            _;
        }
    
        modifier onlyRelayed() {
            require(msg.sender == address(relayedSet), "Sender is not the Relayed contract");
            _;
        }
    
        constructor(address _owner, address _relayedSet)
            public
        {
            _transferOwnership(_owner);
            _setRelayed(_relayedSet);
        }
    
        /// @notice This function is used by the Relayed logic contract
        /// to iniate a change in the active validator set
        /// @dev emits `InitiateChange` which is listened by the Parity client
        /// @param _parentHash Blockhash of the parent block
        /// @param _newSet List of addresses of the desired active validator set
        /// @return True if event was emitted
        function callbackInitiateChange(bytes32 _parentHash, address[] calldata _newSet)
            external
            onlyRelayed
            returns (bool)
        {
            emit InitiateChange(_parentHash, _newSet);
            return true;
        }
    
        /// @notice Finalizes changes of the active validator set.
        /// Called by SYSTEM
        function finalizeChange()
            external
            onlySystem
        {
            relayedSet.finalizeChange();
        }
    
        /// @notice This function is used by validators to submit Benign reports
        /// on other validators. Can only be called by the validator who submits
        /// the report
        /// @dev emits `ReportedBenign` event in the Relayed logic contract
        /// @param _validator The validator to report
        /// @param _blockNumber The blocknumber to report on
        function reportBenign(address _validator, uint256 _blockNumber)
            external
        {
            relayedSet.reportBenign(
                msg.sender,
                _validator,
                _blockNumber
            );
        }
    
        /// @notice This function is used by validators to submit Malicious reports
        /// on other validators. Can only be called by the validator who submits
        /// the report
        /// @dev emits `ReportedMalicious` event in the Relayed logic contract
        /// @param _validator The validator to report
        /// @param _blockNumber The blocknumber to report on
        /// @param _proof Proof to submit. Right now it is not used for anything
        function reportMalicious(address _validator, uint256 _blockNumber, bytes calldata _proof)
            external
        {
            relayedSet.reportMalicious(
                msg.sender,
                _validator,
                _blockNumber,
                _proof
            );
        }
    
        /// @notice Sets the Relayed logic contract address. Only callable by the owner.
        /// The address is assumed to belong to a contract that implements the
        /// `IValidatorSetRelayed` interface
        /// @param _relayedSet The contract address
        function setRelayed(address _relayedSet)
            external
            onlyOwner
        {
            _setRelayed(_relayedSet);
        }
    
        /// @notice Returns the currently active validators
        /// @return The list of addresses of currently active validators
        function getValidators()
            external
            view
            returns (address[] memory)
        {
            return relayedSet.getValidators();
        }
    
        /// @dev The actual logic of setting the Relayed contract
        function _setRelayed(address _relayedSet)
            private
            nonDefaultAddress(_relayedSet)
        {
            require(
                _relayedSet != address(relayedSet),
                "New relayed contract address cannot be the same as the current one"
            );
            address oldRelayed = address(relayedSet);
            relayedSet = IValidatorSetRelayed(_relayedSet);
            emit NewRelayed(oldRelayed, _relayedSet);
        }
    }