github.com/bcskill/bcschain/v3@v3.4.9-beta2/core/rawdb/accessors_metadata.go (about) 1 // Copyright 2018 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 "encoding/json" 21 "fmt" 22 23 "github.com/bcskill/bcschain/v3/common" 24 "github.com/bcskill/bcschain/v3/log" 25 "github.com/bcskill/bcschain/v3/metrics" 26 "github.com/bcskill/bcschain/v3/params" 27 "github.com/bcskill/bcschain/v3/rlp" 28 ) 29 30 var ( 31 preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) 32 preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) 33 ) 34 35 // ReadDatabaseVersion retrieves the version number of the database. 36 func ReadDatabaseVersion(db DatabaseReader) *uint64 { 37 var version uint64 38 39 var enc []byte 40 Must("get", func() (err error) { 41 enc, err = db.Get(databaseVersionKey) 42 if err == common.ErrNotFound { 43 err = nil 44 } 45 return 46 }) 47 if err := rlp.DecodeBytes(enc, &version); err != nil { 48 log.Error("Failed to decode database version", "encoded", enc) 49 return nil 50 } 51 return &version 52 } 53 54 // WriteDatabaseVersion stores the version number of the database 55 func WriteDatabaseVersion(db DatabaseWriter, version uint64) { 56 enc, err := rlp.EncodeToBytes(version) 57 if err != nil { 58 log.Error("Failed to encode database version", "version", version) 59 return 60 } 61 Must("put database version", func() error { 62 return db.Put(databaseVersionKey, enc) 63 }) 64 } 65 66 // ReadChainConfig retrieves the consensus settings based on the given genesis hash. 67 func ReadChainConfig(db DatabaseReader, hash common.Hash) *params.ChainConfig { 68 var data []byte 69 Must("get chain config", func() (err error) { 70 data, err = db.Get(configKey(hash)) 71 if err == common.ErrNotFound { 72 err = nil 73 } 74 return 75 }) 76 if len(data) == 0 { 77 return nil 78 } 79 var config params.ChainConfig 80 if err := json.Unmarshal(data, &config); err != nil { 81 log.Error("Invalid chain config JSON", "hash", hash, "err", err) 82 return nil 83 } 84 return &config 85 } 86 87 // WriteChainConfig writes the chain config settings to the database. 88 func WriteChainConfig(db DatabaseWriter, hash common.Hash, cfg *params.ChainConfig) { 89 if cfg == nil { 90 return 91 } 92 data, err := json.Marshal(cfg) 93 if err != nil { 94 log.Crit("Failed to JSON encode chain config", "err", err) 95 } 96 Must("put chain config", func() error { 97 return db.Put(configKey(hash), data) 98 }) 99 } 100 101 // ReadPreimage retrieves a single preimage of the provided hash. 102 func ReadPreimage(db DatabaseReader, hash common.Hash) []byte { 103 var data []byte 104 Must("get preimage", func() (err error) { 105 data, err = db.Get(preimageKey(hash)) 106 if err == common.ErrNotFound { 107 err = nil 108 } 109 return 110 }) 111 return data 112 } 113 114 // PreimageTablePrefixer returns a Table instance with the key prefix for preimage entries. 115 func PreimageTablePrefixer(tbl common.Table) common.Table { 116 return common.NewTablePrefixer(tbl, preimagePrefix) 117 } 118 119 // WritePreimages writes the provided set of preimages to the database. `number` is the 120 // current block number, and is used for debug messages only. 121 func WritePreimages(tbl common.Table, number uint64, preimages map[common.Hash][]byte) { 122 p := PreimageTablePrefixer(tbl) 123 batch := tbl.NewBatch() 124 hitCount := 0 125 op := fmt.Sprintf("add preimage %d to batch", number) 126 for hash, preimage := range preimages { 127 if _, err := p.Get(hash.Bytes()); err != nil { 128 Must(op, func() error { 129 return batch.Put(hash.Bytes(), preimage) 130 }) 131 hitCount++ 132 } 133 } 134 preimageCounter.Inc(int64(len(preimages))) 135 preimageHitCounter.Inc(int64(hitCount)) 136 if hitCount > 0 { 137 Must(fmt.Sprintf("write preimage %d batch", number), batch.Write) 138 } 139 }