github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/consensus/istanbul/validator.go (about)

     1  // Copyright 2017 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package istanbul
    18  
    19  import (
    20  	"bytes"
    21  	"errors"
    22  	"fmt"
    23  	blscrypto "github.com/ethereum/go-ethereum/crypto/bls"
    24  	"math/big"
    25  
    26  	"github.com/ethereum/go-ethereum/common"
    27  )
    28  
    29  var (
    30  	errInvalidValidatorSetDiffSize = errors.New("istanbul extra validator set data has different size")
    31  )
    32  
    33  type ValidatorData struct {
    34  	Address      common.Address
    35  	BLSPublicKey blscrypto.SerializedPublicKey
    36  }
    37  
    38  type Validator interface {
    39  	fmt.Stringer
    40  
    41  	// Address returns address
    42  	Address() common.Address
    43  
    44  	BLSPublicKey() blscrypto.SerializedPublicKey
    45  
    46  	// Serialize returns binary reprenstation of the Validator
    47  	// can be use used to instantiate a validator with DeserializeValidator()
    48  	Serialize() ([]byte, error)
    49  
    50  	// AsData returns Validator representation as ValidatorData
    51  	AsData() *ValidatorData
    52  }
    53  
    54  // MapValidatorsToAddresses maps a slice of validator to a slice of addresses
    55  func MapValidatorsToAddresses(validators []Validator) []common.Address {
    56  	returnList := make([]common.Address, len(validators))
    57  
    58  	for i, val := range validators {
    59  		returnList[i] = val.Address()
    60  	}
    61  
    62  	return returnList
    63  }
    64  
    65  // ----------------------------------------------------------------------------
    66  
    67  type ValidatorsDataByAddress []ValidatorData
    68  
    69  func (a ValidatorsDataByAddress) Len() int      { return len(a) }
    70  func (a ValidatorsDataByAddress) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
    71  func (a ValidatorsDataByAddress) Less(i, j int) bool {
    72  	return bytes.Compare(a[i].Address[:], a[j].Address[:]) < 0
    73  }
    74  
    75  // ----------------------------------------------------------------------------
    76  
    77  type ValidatorSet interface {
    78  	// Sets the randomness for use in the proposer policy.
    79  	// This is injected into the ValidatorSet when we call `getOrderedValidators`
    80  	SetRandomness(seed common.Hash)
    81  	// Sets the randomness for use in the proposer policy
    82  	GetRandomness() common.Hash
    83  
    84  	// Return the validator size
    85  	Size() int
    86  	// Get the maximum number of faulty nodes
    87  	F() int
    88  	// Get the minimum quorum size
    89  	MinQuorumSize() int
    90  
    91  	// List returns all the validators
    92  	List() []Validator
    93  	// Return the validator index
    94  	GetIndex(addr common.Address) int
    95  	// Get validator by index
    96  	GetByIndex(i uint64) Validator
    97  	// Get validator by given address
    98  	GetByAddress(addr common.Address) (int, Validator)
    99  	// CointainByAddress indicates if a validator with the given address is present
   100  	ContainsByAddress(add common.Address) bool
   101  
   102  	// Add validators
   103  	AddValidators(validators []ValidatorData) bool
   104  	// Remove validators
   105  	RemoveValidators(removedValidators *big.Int) bool
   106  	// Copy validator set
   107  	Copy() ValidatorSet
   108  
   109  	// Serialize returns binary reprentation of the ValidatorSet
   110  	// can be use used to instantiate a validator with DeserializeValidatorSet()
   111  	Serialize() ([]byte, error)
   112  }
   113  
   114  type ValidatorSetData struct {
   115  	Validators []ValidatorData
   116  	Randomness common.Hash
   117  }
   118  
   119  // ----------------------------------------------------------------------------
   120  
   121  // ProposerSelector returns the block proposer for a round given the last proposer, round number, and randomness.
   122  type ProposerSelector func(validatorSet ValidatorSet, lastBlockProposer common.Address, currentRound uint64) Validator
   123  
   124  // ----------------------------------------------------------------------------
   125  
   126  func CombineIstanbulExtraToValidatorData(addrs []common.Address, blsPublicKeys []blscrypto.SerializedPublicKey) ([]ValidatorData, error) {
   127  	if len(addrs) != len(blsPublicKeys) {
   128  		return nil, errInvalidValidatorSetDiffSize
   129  	}
   130  	validators := []ValidatorData{}
   131  	for i := range addrs {
   132  		validators = append(validators, ValidatorData{
   133  			Address:      addrs[i],
   134  			BLSPublicKey: blsPublicKeys[i],
   135  		})
   136  	}
   137  
   138  	return validators, nil
   139  }
   140  
   141  func SeparateValidatorDataIntoIstanbulExtra(validators []ValidatorData) ([]common.Address, []blscrypto.SerializedPublicKey) {
   142  	addrs := []common.Address{}
   143  	pubKeys := []blscrypto.SerializedPublicKey{}
   144  	for i := range validators {
   145  		addrs = append(addrs, validators[i].Address)
   146  		pubKeys = append(pubKeys, validators[i].BLSPublicKey)
   147  	}
   148  
   149  	return addrs, pubKeys
   150  }