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