github.com/MetalBlockchain/subnet-evm@v0.6.3/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 "math/big" 34 35 "github.com/MetalBlockchain/subnet-evm/consensus/misc/eip4844" 36 "github.com/MetalBlockchain/subnet-evm/core/types" 37 "github.com/MetalBlockchain/subnet-evm/params" 38 "github.com/ethereum/go-ethereum/common" 39 "github.com/ethereum/go-ethereum/ethdb" 40 "github.com/ethereum/go-ethereum/log" 41 "github.com/ethereum/go-ethereum/rlp" 42 ) 43 44 // ReadCanonicalHash retrieves the hash assigned to a canonical block number. 45 func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash { 46 data, _ := db.Get(headerHashKey(number)) 47 if len(data) == 0 { 48 return common.Hash{} 49 } 50 return common.BytesToHash(data) 51 } 52 53 // WriteCanonicalHash stores the hash assigned to a canonical block number. 54 func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 55 if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil { 56 log.Crit("Failed to store number to hash mapping", "err", err) 57 } 58 } 59 60 // DeleteCanonicalHash removes the number to hash canonical mapping. 61 func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) { 62 if err := db.Delete(headerHashKey(number)); err != nil { 63 log.Crit("Failed to delete number to hash mapping", "err", err) 64 } 65 } 66 67 // ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights, 68 // both canonical and reorged forks included. 69 func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash { 70 prefix := headerKeyPrefix(number) 71 72 hashes := make([]common.Hash, 0, 1) 73 it := db.NewIterator(prefix, nil) 74 defer it.Release() 75 76 for it.Next() { 77 if key := it.Key(); len(key) == len(prefix)+32 { 78 hashes = append(hashes, common.BytesToHash(key[len(key)-32:])) 79 } 80 } 81 return hashes 82 } 83 84 type NumberHash struct { 85 Number uint64 86 Hash common.Hash 87 } 88 89 // ReadAllHashesInRange retrieves all the hashes assigned to blocks at certain 90 // heights, both canonical and reorged forks included. 91 // This method considers both limits to be _inclusive_. 92 func ReadAllHashesInRange(db ethdb.Iteratee, first, last uint64) []*NumberHash { 93 var ( 94 start = encodeBlockNumber(first) 95 keyLength = len(headerPrefix) + 8 + 32 96 hashes = make([]*NumberHash, 0, 1+last-first) 97 it = db.NewIterator(headerPrefix, start) 98 ) 99 defer it.Release() 100 for it.Next() { 101 key := it.Key() 102 if len(key) != keyLength { 103 continue 104 } 105 num := binary.BigEndian.Uint64(key[len(headerPrefix) : len(headerPrefix)+8]) 106 if num > last { 107 break 108 } 109 hash := common.BytesToHash(key[len(key)-32:]) 110 hashes = append(hashes, &NumberHash{num, hash}) 111 } 112 return hashes 113 } 114 115 // ReadAllCanonicalHashes retrieves all canonical number and hash mappings at the 116 // certain chain range. If the accumulated entries reaches the given threshold, 117 // abort the iteration and return the semi-finish result. 118 func ReadAllCanonicalHashes(db ethdb.Iteratee, from uint64, to uint64, limit int) ([]uint64, []common.Hash) { 119 // Short circuit if the limit is 0. 120 if limit == 0 { 121 return nil, nil 122 } 123 var ( 124 numbers []uint64 125 hashes []common.Hash 126 ) 127 // Construct the key prefix of start point. 128 start, end := headerHashKey(from), headerHashKey(to) 129 it := db.NewIterator(nil, start) 130 defer it.Release() 131 132 for it.Next() { 133 if bytes.Compare(it.Key(), end) >= 0 { 134 break 135 } 136 if key := it.Key(); len(key) == len(headerPrefix)+8+1 && bytes.Equal(key[len(key)-1:], headerHashSuffix) { 137 numbers = append(numbers, binary.BigEndian.Uint64(key[len(headerPrefix):len(headerPrefix)+8])) 138 hashes = append(hashes, common.BytesToHash(it.Value())) 139 // If the accumulated entries reaches the limit threshold, return. 140 if len(numbers) >= limit { 141 break 142 } 143 } 144 } 145 return numbers, hashes 146 } 147 148 // ReadHeaderNumber returns the header number assigned to a hash. 149 func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 { 150 data, _ := db.Get(headerNumberKey(hash)) 151 if len(data) != 8 { 152 return nil 153 } 154 number := binary.BigEndian.Uint64(data) 155 return &number 156 } 157 158 // WriteHeaderNumber stores the hash->number mapping. 159 func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 160 key := headerNumberKey(hash) 161 enc := encodeBlockNumber(number) 162 if err := db.Put(key, enc); err != nil { 163 log.Crit("Failed to store hash to number mapping", "err", err) 164 } 165 } 166 167 // DeleteHeaderNumber removes hash->number mapping. 168 func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) { 169 if err := db.Delete(headerNumberKey(hash)); err != nil { 170 log.Crit("Failed to delete hash to number mapping", "err", err) 171 } 172 } 173 174 // ReadHeadHeaderHash retrieves the hash of the current canonical head header. 175 func ReadHeadHeaderHash(db ethdb.KeyValueReader) common.Hash { 176 data, _ := db.Get(headHeaderKey) 177 if len(data) == 0 { 178 return common.Hash{} 179 } 180 return common.BytesToHash(data) 181 } 182 183 // WriteHeadHeaderHash stores the hash of the current canonical head header. 184 func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) { 185 if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { 186 log.Crit("Failed to store last header's hash", "err", err) 187 } 188 } 189 190 // ReadHeadBlockHash retrieves the hash of the current canonical head block. 191 func ReadHeadBlockHash(db ethdb.KeyValueReader) common.Hash { 192 data, _ := db.Get(headBlockKey) 193 if len(data) == 0 { 194 return common.Hash{} 195 } 196 return common.BytesToHash(data) 197 } 198 199 // WriteHeadBlockHash stores the head block's hash. 200 func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) { 201 if err := db.Put(headBlockKey, hash.Bytes()); err != nil { 202 log.Crit("Failed to store last block's hash", "err", err) 203 } 204 } 205 206 // ReadHeaderRLP retrieves a block header in its raw RLP database encoding. 207 func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 208 data, _ := db.Get(headerKey(number, hash)) 209 if len(data) > 0 { 210 return data 211 } 212 return nil 213 } 214 215 // HasHeader verifies the existence of a block header corresponding to the hash. 216 func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool { 217 if has, err := db.Has(headerKey(number, hash)); !has || err != nil { 218 return false 219 } 220 return true 221 } 222 223 // ReadHeader retrieves the block header corresponding to the hash. 224 func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header { 225 data := ReadHeaderRLP(db, hash, number) 226 if len(data) == 0 { 227 return nil 228 } 229 header := new(types.Header) 230 if err := rlp.Decode(bytes.NewReader(data), header); err != nil { 231 log.Error("Invalid block header RLP", "hash", hash, "err", err) 232 return nil 233 } 234 return header 235 } 236 237 // WriteHeader stores a block header into the database and also stores the hash- 238 // to-number mapping. 239 func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) { 240 var ( 241 hash = header.Hash() 242 number = header.Number.Uint64() 243 ) 244 // Write the hash -> number mapping 245 WriteHeaderNumber(db, hash, number) 246 247 // Write the encoded header 248 data, err := rlp.EncodeToBytes(header) 249 if err != nil { 250 log.Crit("Failed to RLP encode header", "err", err) 251 } 252 key := headerKey(number, hash) 253 if err := db.Put(key, data); err != nil { 254 log.Crit("Failed to store header", "err", err) 255 } 256 } 257 258 // DeleteHeader removes all block header data associated with a hash. 259 func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 260 deleteHeaderWithoutNumber(db, hash, number) 261 if err := db.Delete(headerNumberKey(hash)); err != nil { 262 log.Crit("Failed to delete hash to number mapping", "err", err) 263 } 264 } 265 266 // deleteHeaderWithoutNumber removes only the block header but does not remove 267 // the hash to number mapping. 268 func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 269 if err := db.Delete(headerKey(number, hash)); err != nil { 270 log.Crit("Failed to delete header", "err", err) 271 } 272 } 273 274 // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. 275 func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 276 data, _ := db.Get(blockBodyKey(number, hash)) 277 if len(data) > 0 { 278 return data 279 } 280 return nil 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 data, _ := db.Get(blockReceiptsKey(number, hash)) 351 if len(data) > 0 { 352 return data 353 } 354 return nil 355 } 356 357 // ReadRawReceipts retrieves all the transaction receipts belonging to a block. 358 // The receipt metadata fields are not guaranteed to be populated, so they 359 // should not be used. Use ReadReceipts instead if the metadata is needed. 360 func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts { 361 // Retrieve the flattened receipt slice 362 data := ReadReceiptsRLP(db, hash, number) 363 if len(data) == 0 { 364 return nil 365 } 366 // Convert the receipts from their storage form to their internal representation 367 storageReceipts := []*types.ReceiptForStorage{} 368 if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { 369 log.Error("Invalid receipt array RLP", "hash", hash, "err", err) 370 return nil 371 } 372 receipts := make(types.Receipts, len(storageReceipts)) 373 for i, storageReceipt := range storageReceipts { 374 receipts[i] = (*types.Receipt)(storageReceipt) 375 } 376 return receipts 377 } 378 379 // ReadReceipts retrieves all the transaction receipts belonging to a block, including 380 // its corresponding metadata fields. If it is unable to populate these metadata 381 // fields then nil is returned. 382 // 383 // The current implementation populates these metadata fields by reading the receipts' 384 // corresponding block body, so if the block body is not found it will return nil even 385 // if the receipt itself is stored. 386 func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, time uint64, config *params.ChainConfig) types.Receipts { 387 // We're deriving many fields from the block body, retrieve beside the receipt 388 receipts := ReadRawReceipts(db, hash, number) 389 if receipts == nil { 390 return nil 391 } 392 body := ReadBody(db, hash, number) 393 if body == nil { 394 log.Error("Missing body but have receipt", "hash", hash, "number", number) 395 return nil 396 } 397 header := ReadHeader(db, hash, number) 398 399 var baseFee *big.Int 400 if header == nil { 401 baseFee = big.NewInt(0) 402 } else { 403 baseFee = header.BaseFee 404 } 405 // Compute effective blob gas price. 406 var blobGasPrice *big.Int 407 if header != nil && header.ExcessBlobGas != nil { 408 blobGasPrice = eip4844.CalcBlobFee(*header.ExcessBlobGas) 409 } 410 if err := receipts.DeriveFields(config, hash, number, time, baseFee, blobGasPrice, body.Transactions); err != nil { 411 log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err) 412 return nil 413 } 414 return receipts 415 } 416 417 // WriteReceipts stores all the transaction receipts belonging to a block. 418 func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) { 419 // Convert the receipts into their storage form and serialize them 420 storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) 421 for i, receipt := range receipts { 422 storageReceipts[i] = (*types.ReceiptForStorage)(receipt) 423 } 424 bytes, err := rlp.EncodeToBytes(storageReceipts) 425 if err != nil { 426 log.Crit("Failed to encode block receipts", "err", err) 427 } 428 // Store the flattened receipt slice 429 if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil { 430 log.Crit("Failed to store block receipts", "err", err) 431 } 432 } 433 434 // DeleteReceipts removes all receipt data associated with a block hash. 435 func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 436 if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { 437 log.Crit("Failed to delete block receipts", "err", err) 438 } 439 } 440 441 // storedReceiptRLP is the storage encoding of a receipt. 442 // Re-definition in core/types/receipt.go. 443 // TODO: Re-use the existing definition. 444 type storedReceiptRLP struct { 445 PostStateOrStatus []byte 446 CumulativeGasUsed uint64 447 Logs []*types.Log 448 } 449 450 // ReceiptLogs is a barebone version of ReceiptForStorage which only keeps 451 // the list of logs. When decoding a stored receipt into this object we 452 // avoid creating the bloom filter. 453 type receiptLogs struct { 454 Logs []*types.Log 455 } 456 457 // DecodeRLP implements rlp.Decoder. 458 func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error { 459 var stored storedReceiptRLP 460 if err := s.Decode(&stored); err != nil { 461 return err 462 } 463 r.Logs = stored.Logs 464 return nil 465 } 466 467 // DeriveLogFields fills the logs in receiptLogs with information such as block number, txhash, etc. 468 func deriveLogFields(receipts []*receiptLogs, hash common.Hash, number uint64, txs types.Transactions) error { 469 logIndex := uint(0) 470 if len(txs) != len(receipts) { 471 return errors.New("transaction and receipt count mismatch") 472 } 473 for i := 0; i < len(receipts); i++ { 474 txHash := txs[i].Hash() 475 // The derived log fields can simply be set from the block and transaction 476 for j := 0; j < len(receipts[i].Logs); j++ { 477 receipts[i].Logs[j].BlockNumber = number 478 receipts[i].Logs[j].BlockHash = hash 479 receipts[i].Logs[j].TxHash = txHash 480 receipts[i].Logs[j].TxIndex = uint(i) 481 receipts[i].Logs[j].Index = logIndex 482 logIndex++ 483 } 484 } 485 return nil 486 } 487 488 // ReadLogs retrieves the logs for all transactions in a block. In case 489 // receipts is not found, a nil is returned. 490 // Note: ReadLogs does not derive unstored log fields. 491 func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64) [][]*types.Log { 492 // Retrieve the flattened receipt slice 493 data := ReadReceiptsRLP(db, hash, number) 494 if len(data) == 0 { 495 return nil 496 } 497 receipts := []*receiptLogs{} 498 if err := rlp.DecodeBytes(data, &receipts); err != nil { 499 log.Error("Invalid receipt array RLP", "hash", hash, "err", err) 500 return nil 501 } 502 503 logs := make([][]*types.Log, len(receipts)) 504 for i, receipt := range receipts { 505 logs[i] = receipt.Logs 506 } 507 return logs 508 } 509 510 // ReadBlock retrieves an entire block corresponding to the hash, assembling it 511 // back from the stored header and body. If either the header or body could not 512 // be retrieved nil is returned. 513 // 514 // Note, due to concurrent download of header and block body the header and thus 515 // canonical hash can be stored in the database but the body data not (yet). 516 func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block { 517 header := ReadHeader(db, hash, number) 518 if header == nil { 519 return nil 520 } 521 body := ReadBody(db, hash, number) 522 if body == nil { 523 return nil 524 } 525 return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles) 526 } 527 528 // WriteBlock serializes a block into the database, header and body separately. 529 func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) { 530 WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) 531 WriteHeader(db, block.Header()) 532 } 533 534 // DeleteBlock removes all block data associated with a hash. 535 func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 536 DeleteReceipts(db, hash, number) 537 DeleteHeader(db, hash, number) 538 DeleteBody(db, hash, number) 539 } 540 541 // DeleteBlockWithoutNumber removes all block data associated with a hash, except 542 // the hash to number mapping. 543 func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 544 DeleteReceipts(db, hash, number) 545 deleteHeaderWithoutNumber(db, hash, number) 546 DeleteBody(db, hash, number) 547 } 548 549 // FindCommonAncestor returns the last common ancestor of two block headers 550 func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header { 551 for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { 552 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 553 if a == nil { 554 return nil 555 } 556 } 557 for an := a.Number.Uint64(); an < b.Number.Uint64(); { 558 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 559 if b == nil { 560 return nil 561 } 562 } 563 for a.Hash() != b.Hash() { 564 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 565 if a == nil { 566 return nil 567 } 568 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 569 if b == nil { 570 return nil 571 } 572 } 573 return a 574 } 575 576 // ReadHeadBlock returns the current canonical head block. 577 func ReadHeadBlock(db ethdb.Reader) *types.Block { 578 headBlockHash := ReadHeadBlockHash(db) 579 if headBlockHash == (common.Hash{}) { 580 return nil 581 } 582 headBlockNumber := ReadHeaderNumber(db, headBlockHash) 583 if headBlockNumber == nil { 584 return nil 585 } 586 return ReadBlock(db, headBlockHash, *headBlockNumber) 587 } 588 589 // ReadTxIndexTail retrieves the number of oldest indexed block 590 // whose transaction indices has been indexed. 591 func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 { 592 data, _ := db.Get(txIndexTailKey) 593 if len(data) != 8 { 594 return nil 595 } 596 number := binary.BigEndian.Uint64(data) 597 return &number 598 } 599 600 // WriteTxIndexTail stores the number of oldest indexed block 601 // into database. 602 func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) { 603 if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil { 604 log.Crit("Failed to store the transaction index tail", "err", err) 605 } 606 }