github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/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 "path/filepath" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/ethdb" 25 ) 26 27 type tableSize struct { 28 name string 29 size common.StorageSize 30 } 31 32 // freezerInfo contains the basic information of the freezer. 33 type freezerInfo struct { 34 name string // The identifier of freezer 35 head uint64 // The number of last stored item in the freezer 36 tail uint64 // The number of first stored item in the freezer 37 sizes []tableSize // The storage size per table 38 } 39 40 // count returns the number of stored items in the freezer. 41 func (info *freezerInfo) count() uint64 { 42 return info.head - info.tail + 1 43 } 44 45 // size returns the storage size of the entire freezer. 46 func (info *freezerInfo) size() common.StorageSize { 47 var total common.StorageSize 48 for _, table := range info.sizes { 49 total += table.size 50 } 51 return total 52 } 53 54 func inspect(name string, order map[string]bool, reader ethdb.AncientReader) (freezerInfo, error) { 55 info := freezerInfo{name: name} 56 for t := range order { 57 size, err := reader.AncientSize(t) 58 if err != nil { 59 return freezerInfo{}, err 60 } 61 info.sizes = append(info.sizes, tableSize{name: t, size: common.StorageSize(size)}) 62 } 63 // Retrieve the number of last stored item 64 ancients, err := reader.Ancients() 65 if err != nil { 66 return freezerInfo{}, err 67 } 68 info.head = ancients - 1 69 70 // Retrieve the number of first stored item 71 tail, err := reader.Tail() 72 if err != nil { 73 return freezerInfo{}, err 74 } 75 info.tail = tail 76 return info, nil 77 } 78 79 // inspectFreezers inspects all freezers registered in the system. 80 func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) { 81 var infos []freezerInfo 82 for _, freezer := range freezers { 83 switch freezer { 84 case ChainFreezerName: 85 info, err := inspect(ChainFreezerName, chainFreezerNoSnappy, db) 86 if err != nil { 87 return nil, err 88 } 89 infos = append(infos, info) 90 91 case StateFreezerName: 92 datadir, err := db.AncientDatadir() 93 if err != nil { 94 return nil, err 95 } 96 f, err := NewStateFreezer(datadir, true) 97 if err != nil { 98 continue // might be possible the state freezer is not existent 99 } 100 defer f.Close() 101 102 info, err := inspect(freezer, stateFreezerNoSnappy, f) 103 if err != nil { 104 return nil, err 105 } 106 infos = append(infos, info) 107 108 default: 109 return nil, fmt.Errorf("unknown freezer, supported ones: %v", freezers) 110 } 111 } 112 return infos, nil 113 } 114 115 // InspectFreezerTable dumps out the index of a specific freezer table. The passed 116 // ancient indicates the path of root ancient directory where the chain freezer can 117 // be opened. Start and end specify the range for dumping out indexes. 118 // Note this function can only be used for debugging purposes. 119 func InspectFreezerTable(ancient string, freezerName string, tableName string, start, end int64) error { 120 var ( 121 path string 122 tables map[string]bool 123 ) 124 switch freezerName { 125 case ChainFreezerName: 126 path, tables = resolveChainFreezerDir(ancient), chainFreezerNoSnappy 127 case StateFreezerName: 128 path, tables = filepath.Join(ancient, freezerName), stateFreezerNoSnappy 129 default: 130 return fmt.Errorf("unknown freezer, supported ones: %v", freezers) 131 } 132 noSnappy, exist := tables[tableName] 133 if !exist { 134 var names []string 135 for name := range tables { 136 names = append(names, name) 137 } 138 return fmt.Errorf("unknown table, supported ones: %v", names) 139 } 140 table, err := newFreezerTable(path, tableName, noSnappy, true) 141 if err != nil { 142 return err 143 } 144 table.dumpIndexStdout(start, end) 145 return nil 146 }