github.com/MetalBlockchain/subnet-evm@v0.4.9/core/rawdb/accessors_chain.go (about) 1 // (c) 2019-2020, Ava Labs, Inc. 2 // 3 // This file is a derived work, based on the go-ethereum library whose original 4 // notices appear below. 5 // 6 // It is distributed under a license compatible with the licensing terms of the 7 // original code from which it is derived. 8 // 9 // Much love to the original authors for their work. 10 // ********** 11 // Copyright 2018 The go-ethereum Authors 12 // This file is part of the go-ethereum library. 13 // 14 // The go-ethereum library is free software: you can redistribute it and/or modify 15 // it under the terms of the GNU Lesser General Public License as published by 16 // the Free Software Foundation, either version 3 of the License, or 17 // (at your option) any later version. 18 // 19 // The go-ethereum library is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 // GNU Lesser General Public License for more details. 23 // 24 // You should have received a copy of the GNU Lesser General Public License 25 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 26 27 package rawdb 28 29 import ( 30 "bytes" 31 "encoding/binary" 32 "errors" 33 34 "github.com/MetalBlockchain/subnet-evm/core/types" 35 "github.com/MetalBlockchain/subnet-evm/ethdb" 36 "github.com/MetalBlockchain/subnet-evm/params" 37 "github.com/ethereum/go-ethereum/common" 38 "github.com/ethereum/go-ethereum/log" 39 "github.com/ethereum/go-ethereum/rlp" 40 ) 41 42 // ReadCanonicalHash retrieves the hash assigned to a canonical block number. 43 func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash { 44 data, _ := db.Get(headerHashKey(number)) 45 if len(data) == 0 { 46 return common.Hash{} 47 } 48 return common.BytesToHash(data) 49 } 50 51 // WriteCanonicalHash stores the hash assigned to a canonical block number. 52 func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 53 if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil { 54 log.Crit("Failed to store number to hash mapping", "err", err) 55 } 56 } 57 58 // DeleteCanonicalHash removes the number to hash canonical mapping. 59 func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) { 60 if err := db.Delete(headerHashKey(number)); err != nil { 61 log.Crit("Failed to delete number to hash mapping", "err", err) 62 } 63 } 64 65 // ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights, 66 // both canonical and reorged forks included. 67 func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash { 68 prefix := headerKeyPrefix(number) 69 70 hashes := make([]common.Hash, 0, 1) 71 it := db.NewIterator(prefix, nil) 72 defer it.Release() 73 74 for it.Next() { 75 if key := it.Key(); len(key) == len(prefix)+32 { 76 hashes = append(hashes, common.BytesToHash(key[len(key)-32:])) 77 } 78 } 79 return hashes 80 } 81 82 type NumberHash struct { 83 Number uint64 84 Hash common.Hash 85 } 86 87 // ReadAllHashesInRange retrieves all the hashes assigned to blocks at a certain 88 // heights, both canonical and reorged forks included. 89 // This method considers both limits to be _inclusive_. 90 func ReadAllHashesInRange(db ethdb.Iteratee, first, last uint64) []*NumberHash { 91 var ( 92 start = encodeBlockNumber(first) 93 keyLength = len(headerPrefix) + 8 + 32 94 hashes = make([]*NumberHash, 0, 1+last-first) 95 it = db.NewIterator(headerPrefix, start) 96 ) 97 defer it.Release() 98 for it.Next() { 99 key := it.Key() 100 if len(key) != keyLength { 101 continue 102 } 103 num := binary.BigEndian.Uint64(key[len(headerPrefix) : len(headerPrefix)+8]) 104 if num > last { 105 break 106 } 107 hash := common.BytesToHash(key[len(key)-32:]) 108 hashes = append(hashes, &NumberHash{num, hash}) 109 } 110 return hashes 111 } 112 113 // ReadAllCanonicalHashes retrieves all canonical number and hash mappings at the 114 // certain chain range. If the accumulated entries reaches the given threshold, 115 // abort the iteration and return the semi-finish result. 116 func ReadAllCanonicalHashes(db ethdb.Iteratee, from uint64, to uint64, limit int) ([]uint64, []common.Hash) { 117 // Short circuit if the limit is 0. 118 if limit == 0 { 119 return nil, nil 120 } 121 var ( 122 numbers []uint64 123 hashes []common.Hash 124 ) 125 // Construct the key prefix of start point. 126 start, end := headerHashKey(from), headerHashKey(to) 127 it := db.NewIterator(nil, start) 128 defer it.Release() 129 130 for it.Next() { 131 if bytes.Compare(it.Key(), end) >= 0 { 132 break 133 } 134 if key := it.Key(); len(key) == len(headerPrefix)+8+1 && bytes.Equal(key[len(key)-1:], headerHashSuffix) { 135 numbers = append(numbers, binary.BigEndian.Uint64(key[len(headerPrefix):len(headerPrefix)+8])) 136 hashes = append(hashes, common.BytesToHash(it.Value())) 137 // If the accumulated entries reaches the limit threshold, return. 138 if len(numbers) >= limit { 139 break 140 } 141 } 142 } 143 return numbers, hashes 144 } 145 146 // ReadHeaderNumber returns the header number assigned to a hash. 147 func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 { 148 data, _ := db.Get(headerNumberKey(hash)) 149 if len(data) != 8 { 150 return nil 151 } 152 number := binary.BigEndian.Uint64(data) 153 return &number 154 } 155 156 // WriteHeaderNumber stores the hash->number mapping. 157 func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 158 key := headerNumberKey(hash) 159 enc := encodeBlockNumber(number) 160 if err := db.Put(key, enc); err != nil { 161 log.Crit("Failed to store hash to number mapping", "err", err) 162 } 163 } 164 165 // DeleteHeaderNumber removes hash->number mapping. 166 func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) { 167 if err := db.Delete(headerNumberKey(hash)); err != nil { 168 log.Crit("Failed to delete hash to number mapping", "err", err) 169 } 170 } 171 172 // ReadHeadHeaderHash retrieves the hash of the current canonical head header. 173 func ReadHeadHeaderHash(db ethdb.KeyValueReader) common.Hash { 174 data, _ := db.Get(headHeaderKey) 175 if len(data) == 0 { 176 return common.Hash{} 177 } 178 return common.BytesToHash(data) 179 } 180 181 // WriteHeadHeaderHash stores the hash of the current canonical head header. 182 func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) { 183 if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { 184 log.Crit("Failed to store last header's hash", "err", err) 185 } 186 } 187 188 // ReadHeadBlockHash retrieves the hash of the current canonical head block. 189 func ReadHeadBlockHash(db ethdb.KeyValueReader) common.Hash { 190 data, _ := db.Get(headBlockKey) 191 if len(data) == 0 { 192 return common.Hash{} 193 } 194 return common.BytesToHash(data) 195 } 196 197 // WriteHeadBlockHash stores the head block's hash. 198 func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) { 199 if err := db.Put(headBlockKey, hash.Bytes()); err != nil { 200 log.Crit("Failed to store last block's hash", "err", err) 201 } 202 } 203 204 // ReadHeaderRLP retrieves a block header in its raw RLP database encoding. 205 func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 206 // Then try to look up the data in leveldb. 207 data, _ := db.Get(headerKey(number, hash)) 208 if len(data) > 0 { 209 return data 210 } 211 return nil // Can't find the data anywhere. 212 } 213 214 // HasHeader verifies the existence of a block header corresponding to the hash. 215 func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool { 216 if has, err := db.Has(headerKey(number, hash)); !has || err != nil { 217 return false 218 } 219 return true 220 } 221 222 // ReadHeader retrieves the block header corresponding to the hash. 223 func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header { 224 data := ReadHeaderRLP(db, hash, number) 225 if len(data) == 0 { 226 return nil 227 } 228 header := new(types.Header) 229 if err := rlp.Decode(bytes.NewReader(data), header); err != nil { 230 log.Error("Invalid block header RLP", "hash", hash, "err", err) 231 return nil 232 } 233 return header 234 } 235 236 // WriteHeader stores a block header into the database and also stores the hash- 237 // to-number mapping. 238 func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) { 239 var ( 240 hash = header.Hash() 241 number = header.Number.Uint64() 242 ) 243 // Write the hash -> number mapping 244 WriteHeaderNumber(db, hash, number) 245 246 // Write the encoded header 247 data, err := rlp.EncodeToBytes(header) 248 if err != nil { 249 log.Crit("Failed to RLP encode header", "err", err) 250 } 251 key := headerKey(number, hash) 252 if err := db.Put(key, data); err != nil { 253 log.Crit("Failed to store header", "err", err) 254 } 255 } 256 257 // DeleteHeader removes all block header data associated with a hash. 258 func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 259 deleteHeaderWithoutNumber(db, hash, number) 260 if err := db.Delete(headerNumberKey(hash)); err != nil { 261 log.Crit("Failed to delete hash to number mapping", "err", err) 262 } 263 } 264 265 // deleteHeaderWithoutNumber removes only the block header but does not remove 266 // the hash to number mapping. 267 func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 268 if err := db.Delete(headerKey(number, hash)); err != nil { 269 log.Crit("Failed to delete header", "err", err) 270 } 271 } 272 273 // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. 274 func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 275 // Then try to look up the data in leveldb. 276 data, _ := db.Get(blockBodyKey(number, hash)) 277 if len(data) > 0 { 278 return data 279 } 280 return nil // Can't find the data anywhere. 281 } 282 283 // ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the canonical 284 // block at number, in RLP encoding. 285 func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64) rlp.RawValue { 286 // Need to get the hash 287 data, _ := db.Get(blockBodyKey(number, ReadCanonicalHash(db, number))) 288 if len(data) > 0 { 289 return data 290 } 291 return nil 292 } 293 294 // WriteBodyRLP stores an RLP encoded block body into the database. 295 func WriteBodyRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp rlp.RawValue) { 296 if err := db.Put(blockBodyKey(number, hash), rlp); err != nil { 297 log.Crit("Failed to store block body", "err", err) 298 } 299 } 300 301 // HasBody verifies the existence of a block body corresponding to the hash. 302 func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool { 303 if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil { 304 return false 305 } 306 return true 307 } 308 309 // ReadBody retrieves the block body corresponding to the hash. 310 func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body { 311 data := ReadBodyRLP(db, hash, number) 312 if len(data) == 0 { 313 return nil 314 } 315 body := new(types.Body) 316 if err := rlp.Decode(bytes.NewReader(data), body); err != nil { 317 log.Error("Invalid block body RLP", "hash", hash, "err", err) 318 return nil 319 } 320 return body 321 } 322 323 // WriteBody stores a block body into the database. 324 func WriteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64, body *types.Body) { 325 data, err := rlp.EncodeToBytes(body) 326 if err != nil { 327 log.Crit("Failed to RLP encode body", "err", err) 328 } 329 WriteBodyRLP(db, hash, number, data) 330 } 331 332 // DeleteBody removes all block body data associated with a hash. 333 func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 334 if err := db.Delete(blockBodyKey(number, hash)); err != nil { 335 log.Crit("Failed to delete block body", "err", err) 336 } 337 } 338 339 // HasReceipts verifies the existence of all the transaction receipts belonging 340 // to a block. 341 func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool { 342 if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil { 343 return false 344 } 345 return true 346 } 347 348 // ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding. 349 func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 350 // Then try to look up the data in leveldb. 351 data, _ := db.Get(blockReceiptsKey(number, hash)) 352 if len(data) > 0 { 353 return data 354 } 355 return nil // Can't find the data anywhere. 356 } 357 358 // ReadRawReceipts retrieves all the transaction receipts belonging to a block. 359 // The receipt metadata fields are not guaranteed to be populated, so they 360 // should not be used. Use ReadReceipts instead if the metadata is needed. 361 func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts { 362 // Retrieve the flattened receipt slice 363 data := ReadReceiptsRLP(db, hash, number) 364 if len(data) == 0 { 365 return nil 366 } 367 // Convert the receipts from their storage form to their internal representation 368 storageReceipts := []*types.ReceiptForStorage{} 369 if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { 370 log.Error("Invalid receipt array RLP", "hash", hash, "err", err) 371 return nil 372 } 373 receipts := make(types.Receipts, len(storageReceipts)) 374 for i, storageReceipt := range storageReceipts { 375 receipts[i] = (*types.Receipt)(storageReceipt) 376 } 377 return receipts 378 } 379 380 // ReadReceipts retrieves all the transaction receipts belonging to a block, including 381 // its corresponding metadata fields. If it is unable to populate these metadata 382 // fields then nil is returned. 383 // 384 // The current implementation populates these metadata fields by reading the receipts' 385 // corresponding block body, so if the block body is not found it will return nil even 386 // if the receipt itself is stored. 387 func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts { 388 // We're deriving many fields from the block body, retrieve beside the receipt 389 receipts := ReadRawReceipts(db, hash, number) 390 if receipts == nil { 391 return nil 392 } 393 header := ReadHeader(db, hash, number) 394 if header == nil { 395 return nil 396 } 397 body := ReadBody(db, hash, number) 398 if body == nil { 399 log.Error("Missing body but have receipt", "hash", hash, "number", number) 400 return nil 401 } 402 if err := receipts.DeriveFields(config, hash, number, header.Time, body.Transactions); err != nil { 403 log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err) 404 return nil 405 } 406 return receipts 407 } 408 409 // WriteReceipts stores all the transaction receipts belonging to a block. 410 func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) { 411 // Convert the receipts into their storage form and serialize them 412 storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) 413 for i, receipt := range receipts { 414 storageReceipts[i] = (*types.ReceiptForStorage)(receipt) 415 } 416 bytes, err := rlp.EncodeToBytes(storageReceipts) 417 if err != nil { 418 log.Crit("Failed to encode block receipts", "err", err) 419 } 420 // Store the flattened receipt slice 421 if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil { 422 log.Crit("Failed to store block receipts", "err", err) 423 } 424 } 425 426 // DeleteReceipts removes all receipt data associated with a block hash. 427 func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 428 if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { 429 log.Crit("Failed to delete block receipts", "err", err) 430 } 431 } 432 433 // storedReceiptRLP is the storage encoding of a receipt. 434 // Re-definition in core/types/receipt.go. 435 type storedReceiptRLP struct { 436 PostStateOrStatus []byte 437 CumulativeGasUsed uint64 438 Logs []*types.LogForStorage 439 } 440 441 // ReceiptLogs is a barebone version of ReceiptForStorage which only keeps 442 // the list of logs. When decoding a stored receipt into this object we 443 // avoid creating the bloom filter. 444 type receiptLogs struct { 445 Logs []*types.Log 446 } 447 448 // DecodeRLP implements rlp.Decoder. 449 func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error { 450 var stored storedReceiptRLP 451 if err := s.Decode(&stored); err != nil { 452 return err 453 } 454 r.Logs = make([]*types.Log, len(stored.Logs)) 455 for i, log := range stored.Logs { 456 r.Logs[i] = (*types.Log)(log) 457 } 458 return nil 459 } 460 461 // DeriveLogFields fills the logs in receiptLogs with information such as block number, txhash, etc. 462 func deriveLogFields(receipts []*receiptLogs, hash common.Hash, number uint64, txs types.Transactions) error { 463 logIndex := uint(0) 464 if len(txs) != len(receipts) { 465 return errors.New("transaction and receipt count mismatch") 466 } 467 for i := 0; i < len(receipts); i++ { 468 txHash := txs[i].Hash() 469 // The derived log fields can simply be set from the block and transaction 470 for j := 0; j < len(receipts[i].Logs); j++ { 471 receipts[i].Logs[j].BlockNumber = number 472 receipts[i].Logs[j].BlockHash = hash 473 receipts[i].Logs[j].TxHash = txHash 474 receipts[i].Logs[j].TxIndex = uint(i) 475 receipts[i].Logs[j].Index = logIndex 476 logIndex++ 477 } 478 } 479 return nil 480 } 481 482 // ReadLogs retrieves the logs for all transactions in a block. The log fields 483 // are populated with metadata. In case the receipts or the block body 484 // are not found, a nil is returned. 485 func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64) [][]*types.Log { 486 // Retrieve the flattened receipt slice 487 data := ReadReceiptsRLP(db, hash, number) 488 if len(data) == 0 { 489 return nil 490 } 491 receipts := []*receiptLogs{} 492 if err := rlp.DecodeBytes(data, &receipts); err != nil { 493 log.Error("Invalid receipt array RLP", "hash", hash, "err", err) 494 return nil 495 } 496 497 body := ReadBody(db, hash, number) 498 if body == nil { 499 log.Error("Missing body but have receipt", "hash", hash, "number", number) 500 return nil 501 } 502 if err := deriveLogFields(receipts, hash, number, body.Transactions); err != nil { 503 log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err) 504 return nil 505 } 506 logs := make([][]*types.Log, len(receipts)) 507 for i, receipt := range receipts { 508 logs[i] = receipt.Logs 509 } 510 return logs 511 } 512 513 // ReadBlock retrieves an entire block corresponding to the hash, assembling it 514 // back from the stored header and body. If either the header or body could not 515 // be retrieved nil is returned. 516 // 517 // Note, due to concurrent download of header and block body the header and thus 518 // canonical hash can be stored in the database but the body data not (yet). 519 func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block { 520 header := ReadHeader(db, hash, number) 521 if header == nil { 522 return nil 523 } 524 body := ReadBody(db, hash, number) 525 if body == nil { 526 return nil 527 } 528 return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles) 529 } 530 531 // WriteBlock serializes a block into the database, header and body separately. 532 func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) { 533 WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) 534 WriteHeader(db, block.Header()) 535 } 536 537 // DeleteBlock removes all block data associated with a hash. 538 func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 539 DeleteReceipts(db, hash, number) 540 DeleteHeader(db, hash, number) 541 DeleteBody(db, hash, number) 542 } 543 544 // DeleteBlockWithoutNumber removes all block data associated with a hash, except 545 // the hash to number mapping. 546 func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 547 DeleteReceipts(db, hash, number) 548 deleteHeaderWithoutNumber(db, hash, number) 549 DeleteBody(db, hash, number) 550 } 551 552 // FindCommonAncestor returns the last common ancestor of two block headers 553 func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header { 554 for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { 555 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 556 if a == nil { 557 return nil 558 } 559 } 560 for an := a.Number.Uint64(); an < b.Number.Uint64(); { 561 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 562 if b == nil { 563 return nil 564 } 565 } 566 for a.Hash() != b.Hash() { 567 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 568 if a == nil { 569 return nil 570 } 571 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 572 if b == nil { 573 return nil 574 } 575 } 576 return a 577 } 578 579 // ReadHeadBlock returns the current canonical head block. 580 func ReadHeadBlock(db ethdb.Reader) *types.Block { 581 headBlockHash := ReadHeadBlockHash(db) 582 if headBlockHash == (common.Hash{}) { 583 return nil 584 } 585 headBlockNumber := ReadHeaderNumber(db, headBlockHash) 586 if headBlockNumber == nil { 587 return nil 588 } 589 return ReadBlock(db, headBlockHash, *headBlockNumber) 590 } 591 592 // ReadTxIndexTail retrieves the number of oldest indexed block 593 // whose transaction indices has been indexed. If the corresponding entry 594 // is non-existent in database it means the indexing has been finished. 595 func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 { 596 data, _ := db.Get(txIndexTailKey) 597 if len(data) != 8 { 598 return nil 599 } 600 number := binary.BigEndian.Uint64(data) 601 return &number 602 } 603 604 // WriteTxIndexTail stores the number of oldest indexed block 605 // into database. 606 func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) { 607 if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil { 608 log.Crit("Failed to store the transaction index tail", "err", err) 609 } 610 }