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{}{}, ®Vals, 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{}{}, ®Vals, 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 }