github.com/jimmyx0x/go-ethereum@v1.10.28/core/rawdb/ancient_utils.go (about)

     1  // Copyright 2022 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package rawdb
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"github.com/ethereum/go-ethereum/common"
    23  	"github.com/ethereum/go-ethereum/ethdb"
    24  )
    25  
    26  type tableSize struct {
    27  	name string
    28  	size common.StorageSize
    29  }
    30  
    31  // freezerInfo contains the basic information of the freezer.
    32  type freezerInfo struct {
    33  	name  string      // The identifier of freezer
    34  	head  uint64      // The number of last stored item in the freezer
    35  	tail  uint64      // The number of first stored item in the freezer
    36  	sizes []tableSize // The storage size per table
    37  }
    38  
    39  // count returns the number of stored items in the freezer.
    40  func (info *freezerInfo) count() uint64 {
    41  	return info.head - info.tail + 1
    42  }
    43  
    44  // size returns the storage size of the entire freezer.
    45  func (info *freezerInfo) size() common.StorageSize {
    46  	var total common.StorageSize
    47  	for _, table := range info.sizes {
    48  		total += table.size
    49  	}
    50  	return total
    51  }
    52  
    53  // inspectFreezers inspects all freezers registered in the system.
    54  func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) {
    55  	var infos []freezerInfo
    56  	for _, freezer := range freezers {
    57  		switch freezer {
    58  		case chainFreezerName:
    59  			// Chain ancient store is a bit special. It's always opened along
    60  			// with the key-value store, inspect the chain store directly.
    61  			info := freezerInfo{name: freezer}
    62  			// Retrieve storage size of every contained table.
    63  			for table := range chainFreezerNoSnappy {
    64  				size, err := db.AncientSize(table)
    65  				if err != nil {
    66  					return nil, err
    67  				}
    68  				info.sizes = append(info.sizes, tableSize{name: table, size: common.StorageSize(size)})
    69  			}
    70  			// Retrieve the number of last stored item
    71  			ancients, err := db.Ancients()
    72  			if err != nil {
    73  				return nil, err
    74  			}
    75  			info.head = ancients - 1
    76  
    77  			// Retrieve the number of first stored item
    78  			tail, err := db.Tail()
    79  			if err != nil {
    80  				return nil, err
    81  			}
    82  			info.tail = tail
    83  			infos = append(infos, info)
    84  
    85  		default:
    86  			return nil, fmt.Errorf("unknown freezer, supported ones: %v", freezers)
    87  		}
    88  	}
    89  	return infos, nil
    90  }
    91  
    92  // InspectFreezerTable dumps out the index of a specific freezer table. The passed
    93  // ancient indicates the path of root ancient directory where the chain freezer can
    94  // be opened. Start and end specify the range for dumping out indexes.
    95  // Note this function can only be used for debugging purposes.
    96  func InspectFreezerTable(ancient string, freezerName string, tableName string, start, end int64) error {
    97  	var (
    98  		path   string
    99  		tables map[string]bool
   100  	)
   101  	switch freezerName {
   102  	case chainFreezerName:
   103  		path, tables = resolveChainFreezerDir(ancient), chainFreezerNoSnappy
   104  	default:
   105  		return fmt.Errorf("unknown freezer, supported ones: %v", freezers)
   106  	}
   107  	noSnappy, exist := tables[tableName]
   108  	if !exist {
   109  		var names []string
   110  		for name := range tables {
   111  			names = append(names, name)
   112  		}
   113  		return fmt.Errorf("unknown table, supported ones: %v", names)
   114  	}
   115  	table, err := newFreezerTable(path, tableName, noSnappy, true)
   116  	if err != nil {
   117  		return err
   118  	}
   119  	table.dumpIndexStdout(start, end)
   120  	return nil
   121  }