github.com/klaytn/klaytn@v1.10.2/api/api_private_debug.go (about) 1 // Modifications Copyright 2019 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from internal/ethapi/api.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package api 22 23 import ( 24 "context" 25 "fmt" 26 "strings" 27 28 "github.com/davecgh/go-spew/spew" 29 "github.com/klaytn/klaytn/networks/rpc" 30 "github.com/syndtr/goleveldb/leveldb" 31 "github.com/syndtr/goleveldb/leveldb/util" 32 ) 33 34 // PrivateDebugAPI is the collection of Klaytn APIs exposed over the private 35 // debugging endpoint. 36 type PrivateDebugAPI struct { 37 b Backend 38 } 39 40 // NewPrivateDebugAPI creates a new API definition for the private debug methods 41 // of the Klaytn service. 42 func NewPrivateDebugAPI(b Backend) *PrivateDebugAPI { 43 return &PrivateDebugAPI{b: b} 44 } 45 46 // ChaindbProperty returns leveldb properties of the chain database. 47 func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) { 48 ldb, ok := api.b.ChainDB().(interface { 49 LDB() *leveldb.DB 50 }) 51 if !ok { 52 return "", fmt.Errorf("chaindbProperty does not work for memory databases") 53 } 54 if property == "" { 55 property = "leveldb.stats" 56 } else if !strings.HasPrefix(property, "leveldb.") { 57 property = "leveldb." + property 58 } 59 return ldb.LDB().GetProperty(property) 60 } 61 62 // ChaindbCompact compacts the chain database if successful, otherwise it returns nil. 63 func (api *PrivateDebugAPI) ChaindbCompact() error { 64 ldb, ok := api.b.ChainDB().(interface { 65 LDB() *leveldb.DB 66 }) 67 if !ok { 68 return fmt.Errorf("chaindbCompact does not work for memory databases") 69 } 70 for b := byte(0); b < 255; b++ { 71 logger.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1)) 72 err := ldb.LDB().CompactRange(util.Range{Start: []byte{b}, Limit: []byte{b + 1}}) 73 if err != nil { 74 logger.Error("Database compaction failed", "err", err) 75 return err 76 } 77 } 78 return nil 79 } 80 81 // SetHead rewinds the head of the blockchain to a previous block. 82 func (api *PrivateDebugAPI) SetHead(number rpc.BlockNumber) { 83 if number == rpc.PendingBlockNumber || number == rpc.LatestBlockNumber { 84 logger.Error("Cannot rewind to future") 85 return 86 } 87 api.b.SetHead(uint64(number)) 88 } 89 90 // PrintBlock retrieves a block and returns its pretty printed form. 91 func (api *PrivateDebugAPI) PrintBlock(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (string, error) { 92 block, _ := api.b.BlockByNumberOrHash(ctx, blockNrOrHash) 93 if block == nil { 94 blockNumberOrHashString, _ := blockNrOrHash.NumberOrHashString() 95 return "", fmt.Errorf("block %v not found", blockNumberOrHashString) 96 } 97 return spew.Sdump(block), nil 98 }