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