github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/contract_comm/validators/validators.go (about)

     1  // Copyright 2017 The Celo Authors
     2  // This file is part of the celo library.
     3  //
     4  // The celo library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The celo library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the celo library. If not, see <http://www.gnu.org/licenses/>.
    16  package validators
    17  
    18  import (
    19  	"fmt"
    20  	"math/big"
    21  	"strings"
    22  
    23  	"github.com/ethereum/go-ethereum/accounts/abi"
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/consensus/istanbul"
    26  	"github.com/ethereum/go-ethereum/contract_comm"
    27  	"github.com/ethereum/go-ethereum/core/types"
    28  	"github.com/ethereum/go-ethereum/core/vm"
    29  	blscrypto "github.com/ethereum/go-ethereum/crypto/bls"
    30  	"github.com/ethereum/go-ethereum/params"
    31  )
    32  
    33  // This is taken from celo-monorepo/packages/protocol/build/<env>/contracts/Validators.json
    34  const validatorsABIString string = `[
    35      {
    36          "constant": true,
    37          "inputs": [],
    38          "name": "getRegisteredValidatorSigners",
    39          "outputs": [
    40          {
    41              "name": "",
    42              "type": "address[]"
    43          }
    44          ],
    45          "payable": false,
    46          "stateMutability": "view",
    47          "type": "function"
    48      },
    49      {
    50        "constant": true,
    51        "inputs": [],
    52        "name": "getRegisteredValidators",
    53        "outputs": [
    54          {
    55            "name": "",
    56            "type": "address[]"
    57          }
    58        ],
    59        "payable": false,
    60        "stateMutability": "view",
    61        "type": "function"
    62      },
    63      {
    64        "constant": true,
    65        "inputs": [
    66          {
    67            "name": "signer",
    68            "type": "address"
    69          }
    70        ],
    71        "name": "getValidatorBlsPublicKeyFromSigner",
    72        "outputs": [
    73          {
    74            "name": "blsKey",
    75            "type": "bytes"
    76          }
    77        ],
    78        "payable": false,
    79        "stateMutability": "view",
    80        "type": "function"
    81      },
    82  	  {
    83        "constant": true,
    84        "inputs": [
    85          {
    86            "name": "account",
    87            "type": "address"
    88          }
    89        ],
    90        "name": "getValidator",
    91        "outputs": [
    92          {
    93            "name": "ecdsaPublicKey",
    94            "type": "bytes"
    95          },
    96          {
    97            "name": "blsPublicKey",
    98            "type": "bytes"
    99          },
   100          {
   101            "name": "affiliation",
   102            "type": "address"
   103          },
   104          {
   105            "name": "score",
   106            "type": "uint256"
   107          },
   108          {
   109            "name": "signer",
   110            "type": "address"
   111          }
   112        ],
   113        "payable": false,
   114        "stateMutability": "view",
   115        "type": "function"
   116      },
   117      {
   118        "constant": false,
   119        "inputs": [
   120          {
   121            "name": "validator",
   122            "type": "address"
   123          },
   124          {
   125            "name": "maxPayment",
   126            "type": "uint256"
   127          }
   128        ],
   129        "name": "distributeEpochPaymentsFromSigner",
   130        "outputs": [
   131          {
   132            "name": "",
   133            "type": "uint256"
   134          }
   135        ],
   136        "payable": false,
   137        "stateMutability": "nonpayable",
   138        "type": "function"
   139      },
   140      {
   141        "constant": false,
   142        "inputs": [
   143          {
   144            "name": "validator",
   145            "type": "address"
   146          },
   147          {
   148            "name": "uptime",
   149            "type": "uint256"
   150          }
   151        ],
   152        "name": "updateValidatorScoreFromSigner",
   153        "outputs": [],
   154        "payable": false,
   155        "stateMutability": "nonpayable",
   156        "type": "function"
   157      },
   158      {
   159        "constant": true,
   160        "inputs": [
   161          {
   162            "name": "account",
   163            "type": "address"
   164          }
   165        ],
   166        "name": "getMembershipInLastEpochFromSigner",
   167        "outputs": [
   168          {
   169            "name": "",
   170            "type": "address"
   171          }
   172        ],
   173        "payable": false,
   174        "stateMutability": "view",
   175        "type": "function"
   176      }
   177  ]`
   178  
   179  type ValidatorContractData struct {
   180  	EcdsaPublicKey []byte
   181  	BlsPublicKey   []byte
   182  	Affiliation    common.Address
   183  	Score          *big.Int
   184  	Signer         common.Address
   185  }
   186  
   187  var validatorsABI, _ = abi.JSON(strings.NewReader(validatorsABIString))
   188  
   189  func RetrieveRegisteredValidatorSigners(header *types.Header, state vm.StateDB) ([]common.Address, error) {
   190  	var regVals []common.Address
   191  
   192  	// Get the new epoch's validator signer set
   193  	if _, err := contract_comm.MakeStaticCall(params.ValidatorsRegistryId, validatorsABI, "getRegisteredValidatorSigners", []interface{}{}, &regVals, params.MaxGasForGetRegisteredValidators, header, state); err != nil {
   194  		return nil, err
   195  	}
   196  
   197  	return regVals, nil
   198  }
   199  
   200  func RetrieveRegisteredValidators(header *types.Header, state vm.StateDB) ([]common.Address, error) {
   201  	var regVals []common.Address
   202  
   203  	// Get the new epoch's validator set
   204  	if _, err := contract_comm.MakeStaticCall(params.ValidatorsRegistryId, validatorsABI, "getRegisteredValidators", []interface{}{}, &regVals, params.MaxGasForGetRegisteredValidators, header, state); err != nil {
   205  		return nil, err
   206  	}
   207  
   208  	return regVals, nil
   209  }
   210  
   211  func GetValidator(header *types.Header, state vm.StateDB, validatorAddress common.Address) (ValidatorContractData, error) {
   212  	var validator ValidatorContractData
   213  	_, err := contract_comm.MakeStaticCall(
   214  		params.ValidatorsRegistryId,
   215  		validatorsABI,
   216  		"getValidator",
   217  		[]interface{}{validatorAddress},
   218  		&validator,
   219  		params.MaxGasForGetValidator,
   220  		header,
   221  		state,
   222  	)
   223  	if err != nil {
   224  		return validator, err
   225  	}
   226  	if len(validator.BlsPublicKey) != blscrypto.PUBLICKEYBYTES {
   227  		return validator, fmt.Errorf("length of bls public key incorrect. Expected %d, got %d", blscrypto.PUBLICKEYBYTES, len(validator.BlsPublicKey))
   228  	}
   229  	return validator, nil
   230  }
   231  
   232  func GetValidatorData(header *types.Header, state vm.StateDB, validatorAddresses []common.Address) ([]istanbul.ValidatorData, error) {
   233  	var validatorData []istanbul.ValidatorData
   234  	for _, addr := range validatorAddresses {
   235  		var blsKey []byte
   236  		_, err := contract_comm.MakeStaticCall(params.ValidatorsRegistryId, validatorsABI, "getValidatorBlsPublicKeyFromSigner", []interface{}{addr}, &blsKey, params.MaxGasForGetValidator, header, state)
   237  		if err != nil {
   238  			return nil, err
   239  		}
   240  
   241  		if len(blsKey) != blscrypto.PUBLICKEYBYTES {
   242  			return nil, fmt.Errorf("length of bls public key incorrect. Expected %d, got %d", blscrypto.PUBLICKEYBYTES, len(blsKey))
   243  		}
   244  		blsKeyFixedSize := blscrypto.SerializedPublicKey{}
   245  		copy(blsKeyFixedSize[:], blsKey)
   246  		validator := istanbul.ValidatorData{
   247  			addr,
   248  			blsKeyFixedSize,
   249  		}
   250  		validatorData = append(validatorData, validator)
   251  	}
   252  	return validatorData, nil
   253  }
   254  
   255  func UpdateValidatorScore(header *types.Header, state vm.StateDB, address common.Address, uptime *big.Int) error {
   256  	_, err := contract_comm.MakeCall(
   257  		params.ValidatorsRegistryId,
   258  		validatorsABI,
   259  		"updateValidatorScoreFromSigner",
   260  		[]interface{}{address, uptime},
   261  		nil,
   262  		params.MaxGasForUpdateValidatorScore,
   263  		common.Big0,
   264  		header,
   265  		state,
   266  		false,
   267  	)
   268  	return err
   269  }
   270  
   271  func DistributeEpochPayment(header *types.Header, state vm.StateDB, address common.Address, maxPayment *big.Int) (*big.Int, error) {
   272  	var epochPayment *big.Int
   273  	_, err := contract_comm.MakeCall(
   274  		params.ValidatorsRegistryId,
   275  		validatorsABI,
   276  		"distributeEpochPaymentsFromSigner",
   277  		[]interface{}{address, maxPayment},
   278  		&epochPayment,
   279  		params.MaxGasForDistributeEpochPayment,
   280  		common.Big0,
   281  		header,
   282  		state,
   283  		false,
   284  	)
   285  	return epochPayment, err
   286  }
   287  
   288  func GetMembershipInLastEpoch(header *types.Header, state vm.StateDB, validator common.Address) (common.Address, error) {
   289  	var group common.Address
   290  	_, err := contract_comm.MakeStaticCall(params.ValidatorsRegistryId, validatorsABI, "getMembershipInLastEpochFromSigner", []interface{}{validator}, &group, params.MaxGasForGetMembershipInLastEpoch, header, state)
   291  	if err != nil {
   292  		return common.ZeroAddress, err
   293  	}
   294  	return group, nil
   295  }