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