This repository has been archived by the owner on Feb 27, 2024. It is now read-only.
forked from celo-org/celo-blockchain
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblockchain_parameters.go
153 lines (133 loc) · 5.64 KB
/
blockchain_parameters.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright 2017 The Celo Authors
// This file is part of the celo library.
//
// The celo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The celo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the celo library. If not, see <http://www.gnu.org/licenses/>.
package blockchain_parameters
import (
"math/big"
"time"
"github.com/celo-org/celo-blockchain/common/hexutil"
"github.com/celo-org/celo-blockchain/contracts"
"github.com/celo-org/celo-blockchain/contracts/abis"
"github.com/celo-org/celo-blockchain/core/vm"
"github.com/celo-org/celo-blockchain/log"
"github.com/celo-org/celo-blockchain/params"
)
var (
getMinimumClientVersionMethod = contracts.NewRegisteredContractMethod(params.BlockchainParametersRegistryId, abis.BlockchainParameters, "getMinimumClientVersion", params.MaxGasForReadBlockchainParameter)
intrinsicGasForAlternativeFeeCurrencyMethod = contracts.NewRegisteredContractMethod(params.BlockchainParametersRegistryId, abis.BlockchainParameters, "intrinsicGasForAlternativeFeeCurrency", params.MaxGasForReadBlockchainParameter)
blockGasLimitMethod = contracts.NewRegisteredContractMethod(params.BlockchainParametersRegistryId, abis.BlockchainParameters, "blockGasLimit", params.MaxGasForReadBlockchainParameter)
getUptimeLookbackWindowMethod = contracts.NewRegisteredContractMethod(params.BlockchainParametersRegistryId, abis.BlockchainParameters, "getUptimeLookbackWindow", params.MaxGasForReadBlockchainParameter)
)
// getMinimumVersion retrieves the client required minimum version
// If a node is running a version smaller than this, it should exit/stop
func getMinimumVersion(vmRunner vm.EVMRunner) (*params.VersionInfo, error) {
version := [3]*big.Int{big.NewInt(0), big.NewInt(0), big.NewInt(0)}
err := getMinimumClientVersionMethod.Query(vmRunner, &version)
if err != nil {
return nil, err
}
return ¶ms.VersionInfo{
Major: version[0].Uint64(),
Minor: version[1].Uint64(),
Patch: version[2].Uint64(),
}, nil
}
// GetIntrinsicGasForAlternativeFeeCurrencyOrDefault retrieves the intrisic gas for transactions that pay gas in
// with an alternative currency (not CELO).
// In case of error, it returns the default value
func GetIntrinsicGasForAlternativeFeeCurrencyOrDefault(vmRunner vm.EVMRunner) uint64 {
gas, err := getIntrinsicGasForAlternativeFeeCurrency(vmRunner)
if err != nil {
log.Trace("Default gas", "gas", params.IntrinsicGasForAlternativeFeeCurrency, "method", "intrinsicGasForAlternativeFeeCurrency")
return params.IntrinsicGasForAlternativeFeeCurrency
}
log.Trace("Reading gas", "gas", gas)
return gas
}
// getIntrinsicGasForAlternativeFeeCurrency retrieves the intrisic gas for transactions that pay gas in
// with an alternative currency (not CELO)
func getIntrinsicGasForAlternativeFeeCurrency(vmRunner vm.EVMRunner) (uint64, error) {
var gas *big.Int
err := intrinsicGasForAlternativeFeeCurrencyMethod.Query(vmRunner, &gas)
if err != nil {
return 0, err
}
return gas.Uint64(), nil
}
// GetBlockGasLimitOrDefault retrieves the block max gas limit
// In case of error, it returns the default value
func GetBlockGasLimitOrDefault(vmRunner vm.EVMRunner) uint64 {
val, err := GetBlockGasLimit(vmRunner)
if err != nil {
logError("blockGasLimit", err)
return params.DefaultGasLimit
}
return val
}
// GetBlockGasLimit retrieves the block max gas limit
func GetBlockGasLimit(vmRunner vm.EVMRunner) (uint64, error) {
var gasLimit *big.Int
err := blockGasLimitMethod.Query(vmRunner, &gasLimit)
if err != nil {
return 0, err
}
return gasLimit.Uint64(), nil
}
// GetLookbackWindow retrieves the lookback window parameter to be used
// for uptime score computations
func GetLookbackWindow(vmRunner vm.EVMRunner) (uint64, error) {
var lookbackWindow *big.Int
err := getUptimeLookbackWindowMethod.Query(vmRunner, &lookbackWindow)
if err != nil {
logError("getUptimeLookbackWindow", err)
return 0, err
}
return lookbackWindow.Uint64(), nil
}
// checkMinimumVersion performs a check on the client's minimum version
// In case of not passing hte check it will exit the node
func checkMinimumVersion(vmRunner vm.EVMRunner) {
version, err := getMinimumVersion(vmRunner)
if err != nil {
logError("getMinimumClientVersion", err)
return
}
if params.CurrentVersionInfo.Cmp(version) == -1 {
time.Sleep(10 * time.Second)
// TODO this should exist gracefully, not like this
log.Crit("Client version older than required", "current", params.Version, "required", version)
}
}
func logError(method string, err error) {
if err == contracts.ErrRegistryContractNotDeployed {
log.Debug("Error calling "+method, "err", err, "contract", hexutil.Encode(params.BlockchainParametersRegistryId[:]))
} else {
log.Warn("Error calling "+method, "err", err, "contract", hexutil.Encode(params.BlockchainParametersRegistryId[:]))
}
}
// SpawnCheck starts a goroutine that will periodically check the client's minimun version
// In case of not passing hte check it will exit the node
func SpawnCheck(runnerFactory func() (vm.EVMRunner, error)) {
go func() {
for {
time.Sleep(60 * time.Second)
vmRunner, err := runnerFactory()
if err != nil {
continue
}
checkMinimumVersion(vmRunner)
}
}()
}