func (s *Service) Prepare() error {
	var startErr error
	s.start.Do(func() {
		s.mx.RLock()
		defer s.mx.RUnlock()
		block, err := s.ew.BC().BlockNumber(s.ctx)
		if err != nil {
			s.logger.Error("failed to get current block", zap.Error(err))
			startErr = err
			return
		}
		for _, pool := range s.pools {
			// construct the pool contract bindings
			contract, err := sigmacore.NewSigmacore(common.HexToAddress(pool.ContractAddress), s.ew.BC())
			if err != nil {
				s.logger.Error("failed to get pool contract bindings")
				startErr = err
				return
			}
			// make sure the pool exists
			dPool, err := s.db.GetPool(pool.Name)
			if err != nil {
				s.logger.Info("creating fresh pool database entry", zap.String("pool", pool.Name))
				tokens, err := utils.PoolTokensFor(contract, s.ew.BC())
				if err != nil {
					s.logger.Error("failed to get pool tokens", zap.Error(err))
					return
				}
				balances, denormWeights, totalSupplies, err := s.GetBalancesWeightsAndSupplies(contract, block, pool.ContractAddress, tokens)
				if err != nil {
					s.logger.Error("GetBalancesWeightsAndSupplies call failed", zap.Error(err), zap.String("pool", pool.Name))
					startErr = err
					return
				}
				// gather decimal information
				decimals := make(map[string]interface{})
				for tok, addr := range tokens {
					erc20Contract, err := erc20.NewErc20(addr, s.ew.BC())
					if err != nil {
						s.logger.Error("failed to get erc20 contract binding", zap.Error(err), zap.String("pool", pool.Name), zap.String("token", tok))
						startErr = err
						return
					}
					udec, err := erc20Contract.Decimals(nil)
					if err != nil {
						s.logger.Error("failed to get token decimals", zap.Error(err), zap.String("pool", pool.Name), zap.String("token", tok))
						startErr = err
						return
					}
					decimals[strings.ToLower(tok)] = strconv.FormatUint(uint64(udec), 10)
				}
				// create the record
				if err := s.db.NewPool(
					pool.Name,
					pool.ContractAddress,
					block,
					balances,
					denormWeights,
					totalSupplies,
					decimals,
				); err != nil {
					s.logger.Error("failed to create pool db entry", zap.Error(err), zap.String("pool", pool.Name))
					startErr = err
					return
				}
				// no more processing needed so skip this pool
				continue
			}
			if block <= dPool.LastUpdateAt {
				// skip
				continue
			}
			s.logger.Info("updating pool database entry", zap.String("pool", pool.Name))
			if _, _, _, err := s.UpdateBalancesWeightsAndSupplies(block, pool, contract); err != nil {
				s.logger.Error("failed to update pool balance and weights", zap.Error(err), zap.String("pool", pool.Name))
				startErr = err
				return
			}
		}
	})
	if startErr != nil {
		s.logger.Error("failed to prepare service", zap.Error(startErr))
	} else {
		s.logger.Info("service preparation succeeded")
	}
	return startErr
}
// Prepare is used to prepare the service the primary responsibility of this function
// is to check the database and determine if we need to update the records. This will
// usually only happen during one of two conditions
//     1) the very first time the service is started on a fresh database
//     2) service starts up after being offline for 1 or more blocks since last run
Prepare is used to prepare the service the primary responsibility of this function
is to check the database and determine if we need to update the records. This will
usually only happen during one of two conditions
1) the very first time the service is started on a fresh database
2) service starts up after being offline for 1 or more blocks since last run
// Prepare is used to prepare the service the primary responsibility of this function // is to check the database and determine if we need to update the records . This will // usually only happen during one of two conditions // 1 ) the very first time the service is started on a fresh database // 2 ) service starts up after being offline for 1 or more blocks since last run
func (s *Service) Prepare() error {
	var startErr error
	s.start.Do(func() {
		s.mx.RLock()
		defer s.mx.RUnlock()
		block, err := s.ew.BC().BlockNumber(s.ctx)
		if err != nil {
			s.logger.Error("failed to get current block", zap.Error(err))
			startErr = err
			return
		}
		for _, pool := range s.pools {
			contract, err := sigmacore.NewSigmacore(common.HexToAddress(pool.ContractAddress), s.ew.BC())
			if err != nil {
				s.logger.Error("failed to get pool contract bindings")
				startErr = err
				return
			}
			dPool, err := s.db.GetPool(pool.Name)
			if err != nil {
				s.logger.Info("creating fresh pool database entry", zap.String("pool", pool.Name))
				tokens, err := utils.PoolTokensFor(contract, s.ew.BC())
				if err != nil {
					s.logger.Error("failed to get pool tokens", zap.Error(err))
					return
				}
				balances, denormWeights, totalSupplies, err := s.GetBalancesWeightsAndSupplies(contract, block, pool.ContractAddress, tokens)
				if err != nil {
					s.logger.Error("GetBalancesWeightsAndSupplies call failed", zap.Error(err), zap.String("pool", pool.Name))
					startErr = err
					return
				}
				decimals := make(map[string]interface{})
				for tok, addr := range tokens {
					erc20Contract, err := erc20.NewErc20(addr, s.ew.BC())
					if err != nil {
						s.logger.Error("failed to get erc20 contract binding", zap.Error(err), zap.String("pool", pool.Name), zap.String("token", tok))
						startErr = err
						return
					}
					udec, err := erc20Contract.Decimals(nil)
					if err != nil {
						s.logger.Error("failed to get token decimals", zap.Error(err), zap.String("pool", pool.Name), zap.String("token", tok))
						startErr = err
						return
					}
					decimals[strings.ToLower(tok)] = strconv.FormatUint(uint64(udec), 10)
				}
				if err := s.db.NewPool(
					pool.Name,
					pool.ContractAddress,
					block,
					balances,
					denormWeights,
					totalSupplies,
					decimals,
				); err != nil {
					s.logger.Error("failed to create pool db entry", zap.Error(err), zap.String("pool", pool.Name))
					startErr = err
					return
				}
				continue
			}
			if block <= dPool.LastUpdateAt {
				continue
			}
			s.logger.Info("updating pool database entry", zap.String("pool", pool.Name))
			if _, _, _, err := s.UpdateBalancesWeightsAndSupplies(block, pool, contract); err != nil {
				s.logger.Error("failed to update pool balance and weights", zap.Error(err), zap.String("pool", pool.Name))
				startErr = err
				return
			}
		}
	})
	if startErr != nil {
		s.logger.Error("failed to prepare service", zap.Error(startErr))
	} else {
		s.logger.Info("service preparation succeeded")
	}
	return startErr
}
func ( s * Service ) Prepare ( ) error { var startErr error s . start . Do ( func ( ) { s . mx . RLock ( ) defer s . mx . RUnlock ( ) block , err := s . ew . BC ( ) . BlockNumber ( s . ctx ) if err != nil { s . logger . Error ( " " , zap . Error ( err ) ) startErr = err return } for _ , pool := range s . pools { contract , err := sigmacore . NewSigmacore ( common . HexToAddress ( pool . ContractAddress ) , s . ew . BC ( ) ) if err != nil { s . logger . Error ( " " ) startErr = err return } dPool , err := s . db . GetPool ( pool . Name ) if err != nil { s . logger . Info ( " " , zap . String ( " " , pool . Name ) ) tokens , err := utils . PoolTokensFor ( contract , s . ew . BC ( ) ) if err != nil { s . logger . Error ( " " , zap . Error ( err ) ) return } balances , denormWeights , totalSupplies , err := s . GetBalancesWeightsAndSupplies ( contract , block , pool . ContractAddress , tokens ) if err != nil { s . logger . Error ( " " , zap . Error ( err ) , zap . String ( " " , pool . Name ) ) startErr = err return } decimals := make ( map [ string ] interface { } ) for tok , addr := range tokens { erc20Contract , err := erc20 . NewErc20 ( addr , s . ew . BC ( ) ) if err != nil { s . logger . Error ( " " , zap . Error ( err ) , zap . String ( " " , pool . Name ) , zap . String ( " " , tok ) ) startErr = err return } udec , err := erc20Contract . Decimals ( nil ) if err != nil { s . logger . Error ( " " , zap . Error ( err ) , zap . String ( " " , pool . Name ) , zap . String ( " " , tok ) ) startErr = err return } decimals [ strings . ToLower ( tok ) ] = strconv . FormatUint ( uint64 ( udec ) , 10 ) } if err := s . db . NewPool ( pool . Name , pool . ContractAddress , block , balances , denormWeights , totalSupplies , decimals , ) ; err != nil { s . logger . Error ( " " , zap . Error ( err ) , zap . String ( " " , pool . Name ) ) startErr = err return } continue } if block <= dPool . LastUpdateAt { continue } s . logger . Info ( " " , zap . String ( " " , pool . Name ) ) if _ , _ , _ , err := s . UpdateBalancesWeightsAndSupplies ( block , pool , contract ) ; err != nil { s . logger . Error ( " " , zap . Error ( err ) , zap . String ( " " , pool . Name ) ) startErr = err return } } } ) if startErr != nil { s . logger . Error ( " " , zap . Error ( startErr ) ) } else { s . logger . Info ( " " ) } return startErr }
Prepare is used to prepare the service the primary responsibility of this function
is to check the database and determine if we need to update the records.
Prepare is used to prepare the service the primary responsibility of this function is to check the database and determine if we need to update the records .
// construct the pool contract bindings // make sure the pool exists // gather decimal information // create the record // no more processing needed so skip this pool // skip