hermez-node/config/config.go
config/config.goRaw
1package config
2
3import (
4 "fmt"
5 "io/ioutil"
6 "math/big"
7 "time"
8
9 "github.com/BurntSushi/toml"
10 ethCommon "github.com/ethereum/go-ethereum/common"
11 "github.com/hermeznetwork/hermez-node/api/stateapiupdater"
12 "github.com/hermeznetwork/hermez-node/common"
13 "github.com/hermeznetwork/hermez-node/priceupdater"
14 "github.com/hermeznetwork/tracerr"
15 "github.com/iden3/go-iden3-crypto/babyjub"
16 "gopkg.in/go-playground/validator.v9"
17)
18
19// Duration is a wrapper type that parses time duration from text.
20type Duration struct {
21 time.Duration `validate:"required"`
22}
23
24// UnmarshalText unmarshalls time duration from text.
25func (d *Duration) UnmarshalText(data []byte) error {
26 duration, err := time.ParseDuration(string(data))
27 if err != nil {
28 return tracerr.Wrap(err)
29 }
30 d.Duration = duration
31 return nil
32}
33
34// ServerProof is the server proof configuration data.
35type ServerProof struct {
36 // URL is the server proof API URL
37 URL string `validate:"required"`
38}
39
40// ForgeBatchGasCost is the costs associated to a ForgeBatch transaction, split
41// into different parts to be used in a formula.
42type ForgeBatchGasCost struct {
43 Fixed uint64 `validate:"required"`
44 L1UserTx uint64 `validate:"required"`
45 L1CoordTx uint64 `validate:"required"`
46 L2Tx uint64 `validate:"required"`
47}
48
49// CoordinatorAPI specifies the configuration parameters of the API in mode
50// coordinator
51type CoordinatorAPI struct {
52 // Coordinator enables the coordinator API endpoints
53 Coordinator bool
54}
55
56// Coordinator is the coordinator specific configuration.
57type Coordinator struct {
58 // ForgerAddress is the address under which this coordinator is forging
59 ForgerAddress ethCommon.Address `validate:"required"`
60 // MinimumForgeAddressBalance is the minimum balance the forger address
61 // needs to start the coordinator in wei. Of set to 0, the coordinator
62 // will not check the balance before starting.
63 MinimumForgeAddressBalance *big.Int
64 // FeeAccount is the Hermez account that the coordinator uses to receive fees
65 FeeAccount struct {
66 // Address is the ethereum address of the account to receive fees
67 Address ethCommon.Address `validate:"required"`
68 // BJJ is the baby jub jub public key of the account to receive fees
69 BJJ babyjub.PublicKeyComp `validate:"required"`
70 } `validate:"required"`
71 // ConfirmBlocks is the number of confirmation blocks to wait for sent
72 // ethereum transactions before forgetting about them
73 ConfirmBlocks int64 `validate:"required"`
74 // L1BatchTimeoutPerc is the portion of the range before the L1Batch
75 // timeout that will trigger a schedule to forge an L1Batch
76 L1BatchTimeoutPerc float64 `validate:"required"`
77 // StartSlotBlocksDelay is the number of blocks of delay to wait before
78 // starting the pipeline when we reach a slot in which we can forge.
79 StartSlotBlocksDelay int64
80 // ScheduleBatchBlocksAheadCheck is the number of blocks ahead in which
81 // the forger address is checked to be allowed to forge (apart from
82 // checking the next block), used to decide when to stop scheduling new
83 // batches (by stopping the pipeline).
84 // For example, if we are at block 10 and ScheduleBatchBlocksAheadCheck
85 // is 5, even though at block 11 we canForge, the pipeline will be
86 // stopped if we can't forge at block 15.
87 // This value should be the expected number of blocks it takes between
88 // scheduling a batch and having it mined.
89 ScheduleBatchBlocksAheadCheck int64
90 // SendBatchBlocksMarginCheck is the number of margin blocks ahead in
91 // which the coordinator is also checked to be allowed to forge, apart
92 // from the next block; used to decide when to stop sending batches to
93 // the smart contract.
94 // For example, if we are at block 10 and SendBatchBlocksMarginCheck is
95 // 5, even though at block 11 we canForge, the batch will be discarded
96 // if we can't forge at block 15.
97 SendBatchBlocksMarginCheck int64
98 // ProofServerPollInterval is the waiting interval between polling the
99 // ProofServer while waiting for a particular status
100 ProofServerPollInterval Duration `validate:"required"`
101 // ForgeRetryInterval is the waiting interval between calls forge a
102 // batch after an error
103 ForgeRetryInterval Duration `validate:"required"`
104 // ForgeDelay is the delay after which a batch is forged if the slot is
105 // already committed. If set to 0s, the coordinator will continuously
106 // forge at the maximum rate.
107 ForgeDelay Duration `validate:"-"`
108 // ForgeNoTxsDelay is the delay after which a batch is forged even if
109 // there are no txs to forge if the slot is already committed. If set
110 // to 0s, the coordinator will continuously forge even if the batches
111 // are empty.
112 ForgeNoTxsDelay Duration `validate:"-"`
113 // MustForgeAtSlotDeadline enables the coordinator to forge slots if
114 // the empty slots reach the slot deadline.
115 MustForgeAtSlotDeadline bool
116 // IgnoreSlotCommitment disables forcing the coordinator to forge a
117 // slot immediately when the slot is not committed. If set to false,
118 // the coordinator will immediately forge a batch at the beginning of a
119 // slot if it's the slot winner.
120 IgnoreSlotCommitment bool
121 // ForgeOncePerSlotIfTxs will make the coordinator forge at most one
122 // batch per slot, only if there are included txs in that batch, or
123 // pending l1UserTxs in the smart contract. Setting this parameter
124 // overrides `ForgeDelay`, `ForgeNoTxsDelay`, `MustForgeAtSlotDeadline`
125 // and `IgnoreSlotCommitment`.
126 ForgeOncePerSlotIfTxs bool
127 // SyncRetryInterval is the waiting interval between calls to the main
128 // handler of a synced block after an error
129 SyncRetryInterval Duration `validate:"required"`
130 // PurgeByExtDelInterval is the waiting interval between calls
131 // to the PurgeByExternalDelete function of the l2db which deletes
132 // pending txs externally marked by the column `external_delete`
133 PurgeByExtDelInterval Duration `validate:"required"`
134 // L2DB is the DB that holds the pool of L2Txs
135 L2DB struct {
136 // SafetyPeriod is the number of batches after which
137 // non-pending L2Txs are deleted from the pool
138 SafetyPeriod common.BatchNum `validate:"required"`
139 // MaxTxs is the maximum number of pending L2Txs that can be
140 // stored in the pool. Once this number of pending L2Txs is
141 // reached, inserts to the pool will be denied until some of
142 // the pending txs are forged.
143 MaxTxs uint32 `validate:"required"`
144 // MinFeeUSD is the minimum fee in USD that a tx must pay in
145 // order to be accepted into the pool. Txs with lower than
146 // minimum fee will be rejected at the API level.
147 MinFeeUSD float64
148 // MaxFeeUSD is the maximum fee in USD that a tx must pay in
149 // order to be accepted into the pool. Txs with greater than
150 // maximum fee will be rejected at the API level.
151 MaxFeeUSD float64 `validate:"required"`
152 // TTL is the Time To Live for L2Txs in the pool. Once MaxTxs
153 // L2Txs is reached, L2Txs older than TTL will be deleted.
154 TTL Duration `validate:"required"`
155 // PurgeBatchDelay is the delay between batches to purge
156 // outdated transactions. Outdated L2Txs are those that have
157 // been forged or marked as invalid for longer than the
158 // SafetyPeriod and pending L2Txs that have been in the pool
159 // for longer than TTL once there are MaxTxs.
160 PurgeBatchDelay int64 `validate:"required"`
161 // InvalidateBatchDelay is the delay between batches to mark
162 // invalid transactions due to nonce lower than the account
163 // nonce.
164 InvalidateBatchDelay int64 `validate:"required"`
165 // PurgeBlockDelay is the delay between blocks to purge
166 // outdated transactions. Outdated L2Txs are those that have
167 // been forged or marked as invalid for longer than the
168 // SafetyPeriod and pending L2Txs that have been in the pool
169 // for longer than TTL once there are MaxTxs.
170 PurgeBlockDelay int64 `validate:"required"`
171 // InvalidateBlockDelay is the delay between blocks to mark
172 // invalid transactions due to nonce lower than the account
173 // nonce.
174 InvalidateBlockDelay int64 `validate:"required"`
175 } `validate:"required"`
176 TxSelector struct {
177 // Path where the TxSelector StateDB is stored
178 Path string `validate:"required"`
179 } `validate:"required"`
180 BatchBuilder struct {
181 // Path where the BatchBuilder StateDB is stored
182 Path string `validate:"required"`
183 } `validate:"required"`
184 ServerProofs []ServerProof `validate:"required"`
185 Circuit struct {
186 // MaxTx is the maximum number of txs supported by the circuit
187 MaxTx int64 `validate:"required"`
188 // NLevels is the maximum number of merkle tree levels
189 // supported by the circuit
190 NLevels int64 `validate:"required"`
191 } `validate:"required"`
192 EthClient struct {
193 // MaxGasPrice is the maximum gas price allowed for ethereum
194 // transactions
195 MaxGasPrice *big.Int `validate:"required"`
196 // GasPriceIncPerc is the percentage increase of gas price set
197 // in an ethereum transaction from the suggested gas price by
198 // the ethereum node
199 GasPriceIncPerc int64
200 // CheckLoopInterval is the waiting interval between receipt
201 // checks of ethereum transactions in the TxManager
202 CheckLoopInterval Duration `validate:"required"`
203 // Attempts is the number of attempts to do an eth client RPC
204 // call before giving up
205 Attempts int `validate:"required"`
206 // AttemptsDelay is delay between attempts do do an eth client
207 // RPC call
208 AttemptsDelay Duration `validate:"required"`
209 // TxResendTimeout is the timeout after which a non-mined
210 // ethereum transaction will be resent (reusing the nonce) with
211 // a newly calculated gas price
212 TxResendTimeout Duration `validate:"required"`
213 // NoReuseNonce disables reusing nonces of pending transactions for
214 // new replacement transactions
215 NoReuseNonce bool
216 // Keystore is the ethereum keystore where private keys are kept
217 Keystore struct {
218 // Path to the keystore
219 Path string `validate:"required"`
220 // Password used to decrypt the keys in the keystore
221 Password string `validate:"required"`
222 } `validate:"required"`
223 // ForgeBatchGasCost contains the cost of each action in the
224 // ForgeBatch transaction.
225 ForgeBatchGasCost ForgeBatchGasCost `validate:"required"`
226 } `validate:"required"`
227 API CoordinatorAPI `validate:"required"`
228 Debug struct {
229 // BatchPath if set, specifies the path where batchInfo is stored
230 // in JSON in every step/update of the pipeline
231 BatchPath string
232 // LightScrypt if set, uses light parameters for the ethereum
233 // keystore encryption algorithm.
234 LightScrypt bool
235 // RollupVerifierIndex is the index of the verifier to use in
236 // the Rollup smart contract. The verifier chosen by index
237 // must match with the Circuit parameters.
238 RollupVerifierIndex *int
239 }
240}
241
242// PostgreSQL is the postgreSQL configuration parameters. It's possible to use
243// diferentiated SQL connections for read/write. If the read configuration is
244// not provided, the write one it's going to be used for both reads and writes
245type PostgreSQL struct {
246 // Port of the PostgreSQL write server
247 PortWrite int `validate:"required"`
248 // Host of the PostgreSQL write server
249 HostWrite string `validate:"required"`
250 // User of the PostgreSQL write server
251 UserWrite string `validate:"required"`
252 // Password of the PostgreSQL write server
253 PasswordWrite string `validate:"required"`
254 // Name of the PostgreSQL write server database
255 NameWrite string `validate:"required"`
256 // Port of the PostgreSQL read server
257 PortRead int
258 // Host of the PostgreSQL read server
259 HostRead string
260 // User of the PostgreSQL read server
261 UserRead string
262 // Password of the PostgreSQL read server
263 PasswordRead string
264 // Name of the PostgreSQL read server database
265 NameRead string
266}
267
268// NodeDebug specifies debug configuration parameters
269type NodeDebug struct {
270 // APIAddress is the address where the debugAPI will listen if
271 // set
272 APIAddress string
273 // MeddlerLogs enables meddler debug mode, where unused columns and struct
274 // fields will be logged
275 MeddlerLogs bool
276 // GinDebugMode sets Gin-Gonic (the web framework) to run in
277 // debug mode
278 GinDebugMode bool
279}
280
281// Node is the hermez node configuration.
282type Node struct {
283 PriceUpdater struct {
284 // Interval between price updater calls
285 Interval Duration `validate:"required"`
286 // URLBitfinexV2 is the URL of bitfinex V2 API
287 URLBitfinexV2 string `validate:"required"`
288 // URLCoinGeckoV3 is the URL of coingecko V3 API
289 URLCoinGeckoV3 string `validate:"required"`
290 // DefaultUpdateMethod to get token prices
291 DefaultUpdateMethod priceupdater.UpdateMethodType `validate:"required"`
292 // TokensConfig to specify how each token get it's price updated
293 TokensConfig []priceupdater.TokenConfig
294 } `validate:"required"`
295 StateDB struct {
296 // Path where the synchronizer StateDB is stored
297 Path string `validate:"required"`
298 // Keep is the number of checkpoints to keep
299 Keep int `validate:"required"`
300 } `validate:"required"`
301 PostgreSQL PostgreSQL `validate:"required"`
302 Web3 struct {
303 // URL is the URL of the web3 ethereum-node RPC server. Only
304 // geth is officially supported.
305 URL string `validate:"required"`
306 } `validate:"required"`
307 Synchronizer struct {
308 // SyncLoopInterval is the interval between attempts to
309 // synchronize a new block from an ethereum node
310 SyncLoopInterval Duration `validate:"required"`
311 // StatsRefreshPeriod is the interval between updates of the
312 // synchronizer state Eth parameters (`Eth.LastBlock` and
313 // `Eth.LastBatch`). This value only affects the reported % of
314 // synchronization of blocks and batches, nothing else.
315 StatsRefreshPeriod Duration `validate:"required"`
316 } `validate:"required"`
317 SmartContracts struct {
318 // Rollup is the address of the Hermez.sol smart contract
319 Rollup ethCommon.Address `validate:"required"`
320 // Rollup is the address of the HermezAuctionProtocol.sol smart
321 // contract
322 Auction ethCommon.Address `validate:"required"`
323 // WDelayer is the address of the WithdrawalDelayer.sol smart
324 // contract
325 WDelayer ethCommon.Address `validate:"required"`
326 // TokenHEZ is the address of the HEZTokenFull.sol smart
327 // contract
328 TokenHEZ ethCommon.Address `validate:"required"`
329 // TokenHEZName is the name of the HEZ token deployed at
330 // TokenHEZ address
331 TokenHEZName string `validate:"required"`
332 } `validate:"required"`
333 // API specifies the configuration parameters of the API
334 API struct {
335 // Address where the API will listen if set
336 Address string
337 // Explorer enables the Explorer API endpoints
338 Explorer bool
339 // UpdateMetricsInterval is the interval between updates of the
340 // API metrics
341 UpdateMetricsInterval Duration
342 // UpdateRecommendedFeeInterval is the interval between updates of the
343 // recommended fees
344 UpdateRecommendedFeeInterval Duration
345 // Maximum concurrent connections allowed between API and SQL
346 MaxSQLConnections int `validate:"required"`
347 // SQLConnectionTimeout is the maximum amount of time that an API request
348 // can wait to stablish a SQL connection
349 SQLConnectionTimeout Duration
350 } `validate:"required"`
351 RecommendedFeePolicy stateapiupdater.RecommendedFeePolicy `validate:"required"`
352 Debug NodeDebug `validate:"required"`
353 Coordinator Coordinator `validate:"-"`
354}
355
356// APIServer is the api server configuration parameters
357type APIServer struct {
358 // NodeAPI specifies the configuration parameters of the API
359 API struct {
360 // Address where the API will listen if set
361 Address string `validate:"required"`
362 // Explorer enables the Explorer API endpoints
363 Explorer bool
364 // Maximum concurrent connections allowed between API and SQL
365 MaxSQLConnections int `validate:"required"`
366 // SQLConnectionTimeout is the maximum amount of time that an API request
367 // can wait to stablish a SQL connection
368 SQLConnectionTimeout Duration
369 } `validate:"required"`
370 PostgreSQL PostgreSQL `validate:"required"`
371 Coordinator struct {
372 API struct {
373 // Coordinator enables the coordinator API endpoints
374 Coordinator bool
375 } `validate:"required"`
376 L2DB struct {
377 // MaxTxs is the maximum number of pending L2Txs that can be
378 // stored in the pool. Once this number of pending L2Txs is
379 // reached, inserts to the pool will be denied until some of
380 // the pending txs are forged.
381 MaxTxs uint32 `validate:"required"`
382 // MinFeeUSD is the minimum fee in USD that a tx must pay in
383 // order to be accepted into the pool. Txs with lower than
384 // minimum fee will be rejected at the API level.
385 MinFeeUSD float64
386 // MaxFeeUSD is the maximum fee in USD that a tx must pay in
387 // order to be accepted into the pool. Txs with greater than
388 // maximum fee will be rejected at the API level.
389 MaxFeeUSD float64 `validate:"required"`
390 } `validate:"required"`
391 }
392 Debug NodeDebug `validate:"required"`
393}
394
395// Load loads a generic config.
396func Load(path string, cfg interface{}) error {
397 bs, err := ioutil.ReadFile(path) //nolint:gosec
398 if err != nil {
399 return tracerr.Wrap(err)
400 }
401 cfgToml := string(bs)
402 if _, err := toml.Decode(cfgToml, cfg); err != nil {
403 return tracerr.Wrap(err)
404 }
405 return nil
406}
407
408// LoadNode loads the Node configuration from path.
409func LoadNode(path string, coordinator bool) (*Node, error) {
410 var cfg Node
411 if err := Load(path, &cfg); err != nil {
412 return nil, tracerr.Wrap(fmt.Errorf("error loading node configuration file: %w", err))
413 }
414 validate := validator.New()
415 if err := validate.Struct(cfg); err != nil {
416 return nil, tracerr.Wrap(fmt.Errorf("error validating configuration file: %w", err))
417 }
418 if coordinator {
419 if err := validate.Struct(cfg.Coordinator); err != nil {
420 return nil, tracerr.Wrap(fmt.Errorf("error validating configuration file: %w", err))
421 }
422 }
423 return &cfg, nil
424}
425
426// LoadAPIServer loads the APIServer configuration from path.
427func LoadAPIServer(path string, coordinator bool) (*APIServer, error) {
428 var cfg APIServer
429 if err := Load(path, &cfg); err != nil {
430 return nil, tracerr.Wrap(fmt.Errorf("error loading apiServer configuration file: %w", err))
431 }
432 validate := validator.New()
433 if err := validate.Struct(cfg); err != nil {
434 return nil, tracerr.Wrap(fmt.Errorf("error validating configuration file: %w", err))
435 }
436 if coordinator {
437 if err := validate.Struct(cfg.Coordinator); err != nil {
438 return nil, tracerr.Wrap(fmt.Errorf("error validating configuration file: %w", err))
439 }
440 }
441 return &cfg, nil
442}