github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/core/rawdb/accessors_chain.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 "bytes" 21 "encoding/binary" 22 "math/big" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/core/types" 26 "github.com/ethereum/go-ethereum/ethdb" 27 "github.com/ethereum/go-ethereum/log" 28 "github.com/ethereum/go-ethereum/params" 29 "github.com/ethereum/go-ethereum/rlp" 30 ) 31 32 // ReadCanonicalHash retrieves the hash assigned to a canonical block number. 33 func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash { 34 data, _ := db.Get(headerHashKey(number)) 35 if len(data) == 0 { 36 return common.Hash{} 37 } 38 return common.BytesToHash(data) 39 } 40 41 // WriteCanonicalHash stores the hash assigned to a canonical block number. 42 func WriteCanonicalHash(db ethdb.Writer, hash common.Hash, number uint64) { 43 if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil { 44 log.Crit("Failed to store number to hash mapping", "err", err) 45 } 46 } 47 48 // DeleteCanonicalHash removes the number to hash canonical mapping. 49 func DeleteCanonicalHash(db ethdb.Writer, number uint64) { 50 if err := db.Delete(headerHashKey(number)); err != nil { 51 log.Crit("Failed to delete number to hash mapping", "err", err) 52 } 53 } 54 55 // ReadHeaderNumber returns the header number assigned to a hash. 56 func ReadHeaderNumber(db ethdb.Reader, hash common.Hash) *uint64 { 57 data, _ := db.Get(headerNumberKey(hash)) 58 if len(data) != 8 { 59 return nil 60 } 61 number := binary.BigEndian.Uint64(data) 62 return &number 63 } 64 65 // ReadHeadHeaderHash retrieves the hash of the current canonical head header. 66 func ReadHeadHeaderHash(db ethdb.Reader) common.Hash { 67 data, _ := db.Get(headHeaderKey) 68 if len(data) == 0 { 69 return common.Hash{} 70 } 71 return common.BytesToHash(data) 72 } 73 74 // WriteHeadHeaderHash stores the hash of the current canonical head header. 75 func WriteHeadHeaderHash(db ethdb.Writer, hash common.Hash) { 76 if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { 77 log.Crit("Failed to store last header's hash", "err", err) 78 } 79 } 80 81 // ReadHeadBlockHash retrieves the hash of the current canonical head block. 82 func ReadHeadBlockHash(db ethdb.Reader) common.Hash { 83 data, _ := db.Get(headBlockKey) 84 if len(data) == 0 { 85 return common.Hash{} 86 } 87 return common.BytesToHash(data) 88 } 89 90 // WriteHeadBlockHash stores the head block's hash. 91 func WriteHeadBlockHash(db ethdb.Writer, hash common.Hash) { 92 if err := db.Put(headBlockKey, hash.Bytes()); err != nil { 93 log.Crit("Failed to store last block's hash", "err", err) 94 } 95 } 96 97 // ReadHeadFastBlockHash retrieves the hash of the current fast-sync head block. 98 func ReadHeadFastBlockHash(db ethdb.Reader) common.Hash { 99 data, _ := db.Get(headFastBlockKey) 100 if len(data) == 0 { 101 return common.Hash{} 102 } 103 return common.BytesToHash(data) 104 } 105 106 // WriteHeadFastBlockHash stores the hash of the current fast-sync head block. 107 func WriteHeadFastBlockHash(db ethdb.Writer, hash common.Hash) { 108 if err := db.Put(headFastBlockKey, hash.Bytes()); err != nil { 109 log.Crit("Failed to store last fast block's hash", "err", err) 110 } 111 } 112 113 // ReadFastTrieProgress retrieves the number of tries nodes fast synced to allow 114 // reporting correct numbers across restarts. 115 func ReadFastTrieProgress(db ethdb.Reader) uint64 { 116 data, _ := db.Get(fastTrieProgressKey) 117 if len(data) == 0 { 118 return 0 119 } 120 return new(big.Int).SetBytes(data).Uint64() 121 } 122 123 // WriteFastTrieProgress stores the fast sync trie process counter to support 124 // retrieving it across restarts. 125 func WriteFastTrieProgress(db ethdb.Writer, count uint64) { 126 if err := db.Put(fastTrieProgressKey, new(big.Int).SetUint64(count).Bytes()); err != nil { 127 log.Crit("Failed to store fast sync trie progress", "err", err) 128 } 129 } 130 131 // ReadHeaderRLP retrieves a block header in its raw RLP database encoding. 132 func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 133 data, _ := db.Get(headerKey(number, hash)) 134 return data 135 } 136 137 // HasHeader verifies the existence of a block header corresponding to the hash. 138 func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool { 139 if has, err := db.Has(headerKey(number, hash)); !has || err != nil { 140 return false 141 } 142 return true 143 } 144 145 // ReadHeader retrieves the block header corresponding to the hash. 146 func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header { 147 data := ReadHeaderRLP(db, hash, number) 148 if len(data) == 0 { 149 return nil 150 } 151 header := new(types.Header) 152 if err := rlp.Decode(bytes.NewReader(data), header); err != nil { 153 log.Error("Invalid block header RLP", "hash", hash, "err", err) 154 return nil 155 } 156 return header 157 } 158 159 // WriteHeader stores a block header into the database and also stores the hash- 160 // to-number mapping. 161 func WriteHeader(db ethdb.Writer, header *types.Header) { 162 // Write the hash -> number mapping 163 var ( 164 hash = header.Hash() 165 number = header.Number.Uint64() 166 encoded = encodeBlockNumber(number) 167 ) 168 key := headerNumberKey(hash) 169 if err := db.Put(key, encoded); err != nil { 170 log.Crit("Failed to store hash to number mapping", "err", err) 171 } 172 // Write the encoded header 173 data, err := rlp.EncodeToBytes(header) 174 if err != nil { 175 log.Crit("Failed to RLP encode header", "err", err) 176 } 177 key = headerKey(number, hash) 178 if err := db.Put(key, data); err != nil { 179 log.Crit("Failed to store header", "err", err) 180 } 181 } 182 183 // DeleteHeader removes all block header data associated with a hash. 184 func DeleteHeader(db ethdb.Writer, hash common.Hash, number uint64) { 185 deleteHeaderWithoutNumber(db, hash, number) 186 if err := db.Delete(headerNumberKey(hash)); err != nil { 187 log.Crit("Failed to delete hash to number mapping", "err", err) 188 } 189 } 190 191 // deleteHeaderWithoutNumber removes only the block header but does not remove 192 // the hash to number mapping. 193 func deleteHeaderWithoutNumber(db ethdb.Writer, hash common.Hash, number uint64) { 194 if err := db.Delete(headerKey(number, hash)); err != nil { 195 log.Crit("Failed to delete header", "err", err) 196 } 197 } 198 199 // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. 200 func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 201 data, _ := db.Get(blockBodyKey(number, hash)) 202 return data 203 } 204 205 // WriteBodyRLP stores an RLP encoded block body into the database. 206 func WriteBodyRLP(db ethdb.Writer, hash common.Hash, number uint64, rlp rlp.RawValue) { 207 if err := db.Put(blockBodyKey(number, hash), rlp); err != nil { 208 log.Crit("Failed to store block body", "err", err) 209 } 210 } 211 212 // HasBody verifies the existence of a block body corresponding to the hash. 213 func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool { 214 if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil { 215 return false 216 } 217 return true 218 } 219 220 // ReadBody retrieves the block body corresponding to the hash. 221 func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body { 222 data := ReadBodyRLP(db, hash, number) 223 if len(data) == 0 { 224 return nil 225 } 226 body := new(types.Body) 227 if err := rlp.Decode(bytes.NewReader(data), body); err != nil { 228 log.Error("Invalid block body RLP", "hash", hash, "err", err) 229 return nil 230 } 231 return body 232 } 233 234 // WriteBody storea a block body into the database. 235 func WriteBody(db ethdb.Writer, hash common.Hash, number uint64, body *types.Body) { 236 data, err := rlp.EncodeToBytes(body) 237 if err != nil { 238 log.Crit("Failed to RLP encode body", "err", err) 239 } 240 WriteBodyRLP(db, hash, number, data) 241 } 242 243 // DeleteBody removes all block body data associated with a hash. 244 func DeleteBody(db ethdb.Writer, hash common.Hash, number uint64) { 245 if err := db.Delete(blockBodyKey(number, hash)); err != nil { 246 log.Crit("Failed to delete block body", "err", err) 247 } 248 } 249 250 // ReadTdRLP retrieves a block's total difficulty corresponding to the hash in RLP encoding. 251 func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 252 data, _ := db.Get(headerTDKey(number, hash)) 253 return data 254 } 255 256 // ReadTd retrieves a block's total difficulty corresponding to the hash. 257 func ReadTd(db ethdb.Reader, hash common.Hash, number uint64) *big.Int { 258 data := ReadTdRLP(db, hash, number) 259 if len(data) == 0 { 260 return nil 261 } 262 td := new(big.Int) 263 if err := rlp.Decode(bytes.NewReader(data), td); err != nil { 264 log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err) 265 return nil 266 } 267 return td 268 } 269 270 // WriteTd stores the total difficulty of a block into the database. 271 func WriteTd(db ethdb.Writer, hash common.Hash, number uint64, td *big.Int) { 272 data, err := rlp.EncodeToBytes(td) 273 if err != nil { 274 log.Crit("Failed to RLP encode block total difficulty", "err", err) 275 } 276 if err := db.Put(headerTDKey(number, hash), data); err != nil { 277 log.Crit("Failed to store block total difficulty", "err", err) 278 } 279 } 280 281 // DeleteTd removes all block total difficulty data associated with a hash. 282 func DeleteTd(db ethdb.Writer, hash common.Hash, number uint64) { 283 if err := db.Delete(headerTDKey(number, hash)); err != nil { 284 log.Crit("Failed to delete block total difficulty", "err", err) 285 } 286 } 287 288 // HasReceipts verifies the existence of all the transaction receipts belonging 289 // to a block. 290 func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool { 291 if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil { 292 return false 293 } 294 return true 295 } 296 297 // ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding. 298 func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 299 data, _ := db.Get(blockReceiptsKey(number, hash)) 300 return data 301 } 302 303 // ReadRawReceipts retrieves all the transaction receipts belonging to a block. 304 // The receipt metadata fields are not guaranteed to be populated, so they 305 // should not be used. Use ReadReceipts instead if the metadata is needed. 306 func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts { 307 // Retrieve the flattened receipt slice 308 data := ReadReceiptsRLP(db, hash, number) 309 if len(data) == 0 { 310 return nil 311 } 312 // Convert the receipts from their storage form to their internal representation 313 storageReceipts := []*types.ReceiptForStorage{} 314 if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { 315 log.Error("Invalid receipt array RLP", "hash", hash, "err", err) 316 return nil 317 } 318 receipts := make(types.Receipts, len(storageReceipts)) 319 for i, storageReceipt := range storageReceipts { 320 receipts[i] = (*types.Receipt)(storageReceipt) 321 } 322 return receipts 323 } 324 325 // ReadReceipts retrieves all the transaction receipts belonging to a block, including 326 // its correspoinding metadata fields. If it is unable to populate these metadata 327 // fields then nil is returned. 328 // 329 // The current implementation populates these metadata fields by reading the receipts' 330 // corresponding block body, so if the block body is not found it will return nil even 331 // if the receipt itself is stored. 332 func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts { 333 // We're deriving many fields from the block body, retrieve beside the receipt 334 receipts := ReadRawReceipts(db, hash, number) 335 if receipts == nil { 336 return nil 337 } 338 body := ReadBody(db, hash, number) 339 if body == nil { 340 log.Error("Missing body but have receipt", "hash", hash, "number", number) 341 return nil 342 } 343 if err := receipts.DeriveFields(config, hash, number, body.Transactions); err != nil { 344 log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err) 345 return nil 346 } 347 return receipts 348 } 349 350 // WriteReceipts stores all the transaction receipts belonging to a block. 351 func WriteReceipts(db ethdb.Writer, hash common.Hash, number uint64, receipts types.Receipts) { 352 // Convert the receipts into their storage form and serialize them 353 storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) 354 for i, receipt := range receipts { 355 storageReceipts[i] = (*types.ReceiptForStorage)(receipt) 356 } 357 bytes, err := rlp.EncodeToBytes(storageReceipts) 358 if err != nil { 359 log.Crit("Failed to encode block receipts", "err", err) 360 } 361 // Store the flattened receipt slice 362 if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil { 363 log.Crit("Failed to store block receipts", "err", err) 364 } 365 } 366 367 // DeleteReceipts removes all receipt data associated with a block hash. 368 func DeleteReceipts(db ethdb.Writer, hash common.Hash, number uint64) { 369 if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { 370 log.Crit("Failed to delete block receipts", "err", err) 371 } 372 } 373 374 // ReadBlock retrieves an entire block corresponding to the hash, assembling it 375 // back from the stored header and body. If either the header or body could not 376 // be retrieved nil is returned. 377 // 378 // Note, due to concurrent download of header and block body the header and thus 379 // canonical hash can be stored in the database but the body data not (yet). 380 func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block { 381 header := ReadHeader(db, hash, number) 382 if header == nil { 383 return nil 384 } 385 body := ReadBody(db, hash, number) 386 if body == nil { 387 return nil 388 } 389 return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles) 390 } 391 392 // WriteBlock serializes a block into the database, header and body separately. 393 func WriteBlock(db ethdb.Writer, block *types.Block) { 394 WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) 395 WriteHeader(db, block.Header()) 396 } 397 398 // DeleteBlock removes all block data associated with a hash. 399 func DeleteBlock(db ethdb.Writer, hash common.Hash, number uint64) { 400 DeleteReceipts(db, hash, number) 401 DeleteHeader(db, hash, number) 402 DeleteBody(db, hash, number) 403 DeleteTd(db, hash, number) 404 } 405 406 // deleteBlockWithoutNumber removes all block data associated with a hash, except 407 // the hash to number mapping. 408 func deleteBlockWithoutNumber(db ethdb.Writer, hash common.Hash, number uint64) { 409 DeleteReceipts(db, hash, number) 410 deleteHeaderWithoutNumber(db, hash, number) 411 DeleteBody(db, hash, number) 412 DeleteTd(db, hash, number) 413 } 414 415 // FindCommonAncestor returns the last common ancestor of two block headers 416 func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header { 417 for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { 418 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 419 if a == nil { 420 return nil 421 } 422 } 423 for an := a.Number.Uint64(); an < b.Number.Uint64(); { 424 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 425 if b == nil { 426 return nil 427 } 428 } 429 for a.Hash() != b.Hash() { 430 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 431 if a == nil { 432 return nil 433 } 434 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 435 if b == nil { 436 return nil 437 } 438 } 439 return a 440 }