github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/contract_comm/gasprice_minimum/gasprice_minimum.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 17 package gasprice_minimum 18 19 import ( 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/contract_comm" 26 "github.com/ethereum/go-ethereum/contract_comm/errors" 27 "github.com/ethereum/go-ethereum/core/types" 28 "github.com/ethereum/go-ethereum/core/vm" 29 "github.com/ethereum/go-ethereum/log" 30 "github.com/ethereum/go-ethereum/params" 31 ) 32 33 // TODO (jarmg 5/22/19): Store ABIs in a central location 34 const ( 35 gasPriceMinimumABIString = `[ 36 { 37 "constant": true, 38 "inputs": [ 39 { 40 "name": "_tokenAddress", 41 "type": "address" 42 } 43 ], 44 "name": "getGasPriceMinimum", 45 "outputs": [ 46 { 47 "name": "", 48 "type": "uint256" 49 } 50 ], 51 "payable": false, 52 "stateMutability": "view", 53 "type": "function" 54 }, 55 { 56 "constant": false, 57 "inputs": [ 58 { 59 "name": "_blockGasTotal", 60 "type": "uint256" 61 }, 62 { 63 "name": "_blockGasLimit", 64 "type": "uint256" 65 } 66 ], 67 "name": "updateGasPriceMinimum", 68 "outputs": [ 69 { 70 "name": "", 71 "type": "uint256" 72 } 73 ], 74 "payable": false, 75 "stateMutability": "nonpayable", 76 "type": "function" 77 } 78 79 ]` 80 ) 81 82 var ( 83 gasPriceMinimumABI, _ = abi.JSON(strings.NewReader(gasPriceMinimumABIString)) 84 FallbackGasPriceMinimum *big.Int = big.NewInt(0) // gas price minimum to return if unable to fetch from contract 85 suggestionMultiplier *big.Int = big.NewInt(5) // The multiplier that we apply to the minimum when suggesting gas price 86 ) 87 88 func GetGasPriceSuggestion(currency *common.Address, header *types.Header, state vm.StateDB) (*big.Int, error) { 89 gasPriceMinimum, err := GetGasPriceMinimum(currency, header, state) 90 return new(big.Int).Mul(gasPriceMinimum, suggestionMultiplier), err 91 } 92 93 func GetGasPriceMinimum(currency *common.Address, header *types.Header, state vm.StateDB) (*big.Int, error) { 94 var currencyAddress *common.Address 95 var err error 96 97 if currency == nil { 98 currencyAddress, err = contract_comm.GetRegisteredAddress(params.GoldTokenRegistryId, header, state) 99 100 if err == errors.ErrSmartContractNotDeployed || err == errors.ErrRegistryContractNotDeployed { 101 return FallbackGasPriceMinimum, nil 102 } 103 if err == errors.ErrNoInternalEvmHandlerSingleton { 104 log.Error(err.Error()) 105 return FallbackGasPriceMinimum, nil 106 } 107 if err != nil { 108 log.Error(err.Error()) 109 return FallbackGasPriceMinimum, err 110 } 111 } else { 112 currencyAddress = currency 113 } 114 115 var gasPriceMinimum *big.Int 116 _, err = contract_comm.MakeStaticCall( 117 params.GasPriceMinimumRegistryId, 118 gasPriceMinimumABI, 119 "getGasPriceMinimum", 120 []interface{}{currencyAddress}, 121 &gasPriceMinimum, 122 params.MaxGasForGetGasPriceMinimum, 123 header, 124 state, 125 ) 126 127 if err != nil { 128 return FallbackGasPriceMinimum, err 129 } 130 131 return gasPriceMinimum, err 132 } 133 134 func UpdateGasPriceMinimum(header *types.Header, state vm.StateDB) (*big.Int, error) { 135 var updatedGasPriceMinimum *big.Int 136 137 _, err := contract_comm.MakeCall( 138 params.GasPriceMinimumRegistryId, 139 gasPriceMinimumABI, 140 "updateGasPriceMinimum", 141 []interface{}{big.NewInt(int64(header.GasUsed)), 142 big.NewInt(int64(header.GasLimit))}, 143 &updatedGasPriceMinimum, 144 params.MaxGasForUpdateGasPriceMinimum, 145 big.NewInt(0), 146 header, 147 state, 148 false, 149 ) 150 if err != nil { 151 return nil, err 152 } 153 return updatedGasPriceMinimum, err 154 }