github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/blocks/handle_count.go (about)

     1  // Copyright 2021 The TrueBlocks Authors. All rights reserved.
     2  // Use of this source code is governed by a license that can
     3  // be found in the LICENSE file.
     4  
     5  package blocksPkg
     6  
     7  import (
     8  	"errors"
     9  
    10  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output"
    11  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types"
    12  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/uniq"
    13  	"github.com/ethereum/go-ethereum"
    14  )
    15  
    16  func (opts *BlocksOptions) HandleCount(rCtx *output.RenderCtx) error {
    17  	chain := opts.Globals.Chain
    18  
    19  	fetchData := func(modelChan chan types.Modeler, errorChan chan error) {
    20  		for _, br := range opts.BlockIds {
    21  			blockNums, err := br.ResolveBlocks(chain)
    22  			if err != nil {
    23  				errorChan <- err
    24  				if errors.Is(err, ethereum.NotFound) {
    25  					continue
    26  				}
    27  				rCtx.Cancel()
    28  				return
    29  			}
    30  
    31  			for _, bn := range blockNums {
    32  				var block types.LightBlock
    33  				if block, err = opts.Conn.GetBlockHeaderByNumber(bn); err != nil {
    34  					errorChan <- err
    35  					if errors.Is(err, ethereum.NotFound) {
    36  						continue
    37  					}
    38  					rCtx.Cancel()
    39  					return
    40  				}
    41  
    42  				blockCount := types.BlockCount{
    43  					BlockNumber:     block.BlockNumber,
    44  					Timestamp:       block.Timestamp,
    45  					TransactionsCnt: uint64(len(block.Transactions)),
    46  					WithdrawalsCnt:  uint64(len(block.Withdrawals)),
    47  				}
    48  
    49  				if opts.Uncles {
    50  					if blockCount.UnclesCnt, err = opts.Conn.GetUnclesCountInBlock(bn); err != nil {
    51  						errorChan <- err
    52  						if errors.Is(err, ethereum.NotFound) {
    53  							continue
    54  						}
    55  						rCtx.Cancel()
    56  						return
    57  					}
    58  				}
    59  
    60  				if opts.Traces {
    61  					if blockCount.TracesCnt, err = opts.Conn.GetTracesCountInBlock(bn); err != nil {
    62  						errorChan <- err
    63  						if errors.Is(err, ethereum.NotFound) {
    64  							continue
    65  						}
    66  						rCtx.Cancel()
    67  						return
    68  					}
    69  				}
    70  
    71  				if opts.Logs {
    72  					if blockCount.LogsCnt, err = opts.Conn.GetLogsCountInBlock(bn, block.Timestamp); err != nil {
    73  						errorChan <- err
    74  						if errors.Is(err, ethereum.NotFound) {
    75  							continue
    76  						}
    77  						rCtx.Cancel()
    78  						return
    79  					}
    80  				}
    81  
    82  				if opts.Uniq {
    83  					countFunc := func(s *types.Appearance) error {
    84  						blockCount.AddressCnt++
    85  						return nil
    86  					}
    87  
    88  					if err := uniq.GetUniqAddressesInBlock(chain, opts.Flow, opts.Conn, countFunc, bn); err != nil {
    89  						errorChan <- err
    90  						if errors.Is(err, ethereum.NotFound) {
    91  							continue
    92  						}
    93  						rCtx.Cancel()
    94  						return
    95  					}
    96  				}
    97  
    98  				modelChan <- &blockCount
    99  			}
   100  		}
   101  	}
   102  
   103  	extraOpts := map[string]any{
   104  		"count":  opts.Count,
   105  		"uncles": opts.Uncles,
   106  		"logs":   opts.Logs,
   107  		"traces": opts.Traces,
   108  		"uniqs":  opts.Uniq,
   109  	}
   110  	return output.StreamMany(rCtx, fetchData, opts.Globals.OutputOptsWithExtra(extraOpts))
   111  }