github.com/dominant-strategies/go-quai@v0.28.2/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 "errors" 23 "math/big" 24 "sort" 25 26 "github.com/dominant-strategies/go-quai/common" 27 "github.com/dominant-strategies/go-quai/core/types" 28 "github.com/dominant-strategies/go-quai/crypto" 29 "github.com/dominant-strategies/go-quai/ethdb" 30 "github.com/dominant-strategies/go-quai/log" 31 "github.com/dominant-strategies/go-quai/params" 32 "github.com/dominant-strategies/go-quai/rlp" 33 ) 34 35 // ReadCanonicalHash retrieves the hash assigned to a canonical block number. 36 func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash { 37 data, _ := db.Get(headerHashKey(number)) 38 39 if len(data) == 0 { 40 return common.Hash{} 41 } 42 return common.BytesToHash(data) 43 } 44 45 // WriteCanonicalHash stores the hash assigned to a canonical block number. 46 func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 47 if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil { 48 log.Fatal("Failed to store number to hash mapping", "err", err) 49 } 50 } 51 52 // DeleteCanonicalHash removes the number to hash canonical mapping. 53 func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) { 54 if err := db.Delete(headerHashKey(number)); err != nil { 55 log.Fatal("Failed to delete number to hash mapping", "err", err) 56 } 57 } 58 59 // ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights, 60 // both canonical and reorged forks included. 61 func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash { 62 prefix := headerKeyPrefix(number) 63 64 hashes := make([]common.Hash, 0, 1) 65 it := db.NewIterator(prefix, nil) 66 defer it.Release() 67 68 for it.Next() { 69 if key := it.Key(); len(key) == len(prefix)+32 { 70 hashes = append(hashes, common.BytesToHash(key[len(key)-32:])) 71 } 72 } 73 return hashes 74 } 75 76 // ReadAllCanonicalHashes retrieves all canonical number and hash mappings at the 77 // certain chain range. If the accumulated entries reaches the given threshold, 78 // abort the iteration and return the semi-finish result. 79 func ReadAllCanonicalHashes(db ethdb.Iteratee, from uint64, to uint64, limit int) ([]uint64, []common.Hash) { 80 // Short circuit if the limit is 0. 81 if limit == 0 { 82 return nil, nil 83 } 84 var ( 85 numbers []uint64 86 hashes []common.Hash 87 ) 88 // Construct the key prefix of start point. 89 start, end := headerHashKey(from), headerHashKey(to) 90 it := db.NewIterator(nil, start) 91 defer it.Release() 92 93 for it.Next() { 94 if bytes.Compare(it.Key(), end) >= 0 { 95 break 96 } 97 if key := it.Key(); len(key) == len(headerPrefix)+8+1 && bytes.Equal(key[len(key)-1:], headerHashSuffix) { 98 numbers = append(numbers, binary.BigEndian.Uint64(key[len(headerPrefix):len(headerPrefix)+8])) 99 hashes = append(hashes, common.BytesToHash(it.Value())) 100 // If the accumulated entries reaches the limit threshold, return. 101 if len(numbers) >= limit { 102 break 103 } 104 } 105 } 106 return numbers, hashes 107 } 108 109 // ReadHeaderNumber returns the header number assigned to a hash. 110 func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 { 111 data, _ := db.Get(headerNumberKey(hash)) 112 if len(data) != 8 { 113 return nil 114 } 115 number := binary.BigEndian.Uint64(data) 116 return &number 117 } 118 119 // WriteHeaderNumber stores the hash->number mapping. 120 func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 121 key := headerNumberKey(hash) 122 enc := encodeBlockNumber(number) 123 if err := db.Put(key, enc); err != nil { 124 log.Fatal("Failed to store hash to number mapping", "err", err) 125 } 126 } 127 128 // DeleteHeaderNumber removes hash->number mapping. 129 func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) { 130 if err := db.Delete(headerNumberKey(hash)); err != nil { 131 log.Fatal("Failed to delete hash to number mapping", "err", err) 132 } 133 } 134 135 // ReadHeadHeaderHash retrieves the hash of the current canonical head header. 136 func ReadHeadHeaderHash(db ethdb.KeyValueReader) common.Hash { 137 data, _ := db.Get(headHeaderKey) 138 if len(data) == 0 { 139 return common.Hash{} 140 } 141 return common.BytesToHash(data) 142 } 143 144 // WriteHeadHeaderHash stores the hash of the current canonical head header. 145 func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) { 146 if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { 147 log.Fatal("Failed to store last header's hash", "err", err) 148 } 149 } 150 151 // ReadHeadBlockHash retrieves the hash of the current canonical head block. 152 func ReadHeadBlockHash(db ethdb.KeyValueReader) common.Hash { 153 data, _ := db.Get(headBlockKey) 154 if len(data) == 0 { 155 return common.Hash{} 156 } 157 return common.BytesToHash(data) 158 } 159 160 // WriteHeadBlockHash stores the head block's hash. 161 func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) { 162 if err := db.Put(headBlockKey, hash.Bytes()); err != nil { 163 log.Fatal("Failed to store last block's hash", "err", err) 164 } 165 } 166 167 // ReadLastPivotNumber retrieves the number of the last pivot block. If the node 168 // full synced, the last pivot will always be nil. 169 func ReadLastPivotNumber(db ethdb.KeyValueReader) *uint64 { 170 data, _ := db.Get(lastPivotKey) 171 if len(data) == 0 { 172 return nil 173 } 174 var pivot uint64 175 if err := rlp.DecodeBytes(data, &pivot); err != nil { 176 log.Error("Invalid pivot block number in database", "err", err) 177 return nil 178 } 179 return &pivot 180 } 181 182 // WriteLastPivotNumber stores the number of the last pivot block. 183 func WriteLastPivotNumber(db ethdb.KeyValueWriter, pivot uint64) { 184 enc, err := rlp.EncodeToBytes(pivot) 185 if err != nil { 186 log.Fatal("Failed to encode pivot block number", "err", err) 187 } 188 if err := db.Put(lastPivotKey, enc); err != nil { 189 log.Fatal("Failed to store pivot block number", "err", err) 190 } 191 } 192 193 // ReadFastTrieProgress retrieves the number of tries nodes fast synced to allow 194 // reporting correct numbers across restarts. 195 func ReadFastTrieProgress(db ethdb.KeyValueReader) uint64 { 196 data, _ := db.Get(fastTrieProgressKey) 197 if len(data) == 0 { 198 return 0 199 } 200 return new(big.Int).SetBytes(data).Uint64() 201 } 202 203 // WriteFastTrieProgress stores the fast sync trie process counter to support 204 // retrieving it across restarts. 205 func WriteFastTrieProgress(db ethdb.KeyValueWriter, count uint64) { 206 if err := db.Put(fastTrieProgressKey, new(big.Int).SetUint64(count).Bytes()); err != nil { 207 log.Fatal("Failed to store fast sync trie progress", "err", err) 208 } 209 } 210 211 // ReadTxIndexTail retrieves the number of oldest indexed block 212 // whose transaction indices has been indexed. If the corresponding entry 213 // is non-existent in database it means the indexing has been finished. 214 func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 { 215 data, _ := db.Get(txIndexTailKey) 216 if len(data) != 8 { 217 return nil 218 } 219 number := binary.BigEndian.Uint64(data) 220 return &number 221 } 222 223 // WriteTxIndexTail stores the number of oldest indexed block 224 // into database. 225 func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) { 226 if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil { 227 log.Fatal("Failed to store the transaction index tail", "err", err) 228 } 229 } 230 231 // ReadFastTxLookupLimit retrieves the tx lookup limit used in fast sync. 232 func ReadFastTxLookupLimit(db ethdb.KeyValueReader) *uint64 { 233 data, _ := db.Get(fastTxLookupLimitKey) 234 if len(data) != 8 { 235 return nil 236 } 237 number := binary.BigEndian.Uint64(data) 238 return &number 239 } 240 241 // WriteFastTxLookupLimit stores the txlookup limit used in fast sync into database. 242 func WriteFastTxLookupLimit(db ethdb.KeyValueWriter, number uint64) { 243 if err := db.Put(fastTxLookupLimitKey, encodeBlockNumber(number)); err != nil { 244 log.Fatal("Failed to store transaction lookup limit for fast sync", "err", err) 245 } 246 } 247 248 // ReadHeaderRLP retrieves a block header in its raw RLP database encoding. 249 func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 250 // First try to look up the data in ancient database. Extra hash 251 // comparison is necessary since ancient database only maintains 252 // the canonical data. 253 data, _ := db.Ancient(freezerHeaderTable, number) 254 if len(data) > 0 && crypto.Keccak256Hash(data) == hash { 255 return data 256 } 257 // Then try to look up the data in leveldb. 258 data, _ = db.Get(headerKey(number, hash)) 259 if len(data) > 0 { 260 return data 261 } 262 // In the background freezer is moving data from leveldb to flatten files. 263 // So during the first check for ancient db, the data is not yet in there, 264 // but when we reach into leveldb, the data was already moved. That would 265 // result in a not found error. 266 data, _ = db.Ancient(freezerHeaderTable, number) 267 if len(data) > 0 && crypto.Keccak256Hash(data) == hash { 268 return data 269 } 270 return nil // Can't find the data anywhere. 271 } 272 273 // HasHeader verifies the existence of a block header corresponding to the hash. 274 func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool { 275 if has, err := db.Ancient(freezerHashTable, number); err == nil && common.BytesToHash(has) == hash { 276 return true 277 } 278 if has, err := db.Has(headerKey(number, hash)); !has || err != nil { 279 return false 280 } 281 return true 282 } 283 284 // ReadHeader retrieves the block header corresponding to the hash. 285 func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header { 286 data := ReadHeaderRLP(db, hash, number) 287 if len(data) == 0 { 288 return nil 289 } 290 header := new(types.Header) 291 if err := rlp.Decode(bytes.NewReader(data), header); err != nil { 292 log.Error("Invalid block header RLP", "hash", hash, "err", err) 293 return nil 294 } 295 return header 296 } 297 298 // WriteHeader stores a block header into the database and also stores the hash- 299 // to-number mapping. 300 func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) { 301 var ( 302 hash = header.Hash() 303 number = header.NumberU64() 304 ) 305 // Write the hash -> number mapping 306 WriteHeaderNumber(db, hash, number) 307 308 // Write the encoded header 309 data, err := rlp.EncodeToBytes(header) 310 if err != nil { 311 log.Fatal("Failed to RLP encode header", "err", err) 312 } 313 key := headerKey(number, hash) 314 if err := db.Put(key, data); err != nil { 315 log.Fatal("Failed to store header", "err", err) 316 } 317 } 318 319 // DeleteHeader removes all block header data associated with a hash. 320 func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 321 deleteHeaderWithoutNumber(db, hash, number) 322 if err := db.Delete(headerNumberKey(hash)); err != nil { 323 log.Fatal("Failed to delete hash to number mapping", "err", err) 324 } 325 } 326 327 // deleteHeaderWithoutNumber removes only the block header but does not remove 328 // the hash to number mapping. 329 func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 330 if err := db.Delete(headerKey(number, hash)); err != nil { 331 log.Fatal("Failed to delete header", "err", err) 332 } 333 } 334 335 // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. 336 func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 337 // First try to look up the data in ancient database. Extra hash 338 // comparison is necessary since ancient database only maintains 339 // the canonical data. 340 data, _ := db.Ancient(freezerBodiesTable, number) 341 if len(data) > 0 { 342 h, _ := db.Ancient(freezerHashTable, number) 343 if common.BytesToHash(h) == hash { 344 return data 345 } 346 } 347 // Then try to look up the data in leveldb. 348 data, _ = db.Get(blockBodyKey(number, hash)) 349 if len(data) > 0 { 350 return data 351 } 352 // In the background freezer is moving data from leveldb to flatten files. 353 // So during the first check for ancient db, the data is not yet in there, 354 // but when we reach into leveldb, the data was already moved. That would 355 // result in a not found error. 356 data, _ = db.Ancient(freezerBodiesTable, number) 357 if len(data) > 0 { 358 h, _ := db.Ancient(freezerHashTable, number) 359 if common.BytesToHash(h) == hash { 360 return data 361 } 362 } 363 return nil // Can't find the data anywhere. 364 } 365 366 // ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the canonical 367 // block at number, in RLP encoding. 368 func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64) rlp.RawValue { 369 // If it's an ancient one, we don't need the canonical hash 370 data, _ := db.Ancient(freezerBodiesTable, number) 371 if len(data) == 0 { 372 // Need to get the hash 373 data, _ = db.Get(blockBodyKey(number, ReadCanonicalHash(db, number))) 374 // In the background freezer is moving data from leveldb to flatten files. 375 // So during the first check for ancient db, the data is not yet in there, 376 // but when we reach into leveldb, the data was already moved. That would 377 // result in a not found error. 378 if len(data) == 0 { 379 data, _ = db.Ancient(freezerBodiesTable, number) 380 } 381 } 382 return data 383 } 384 385 // WriteBodyRLP stores an RLP encoded block body into the database. 386 func WriteBodyRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp rlp.RawValue) { 387 if err := db.Put(blockBodyKey(number, hash), rlp); err != nil { 388 log.Fatal("Failed to store block body", "err", err) 389 } 390 } 391 392 // HasBody verifies the existence of a block body corresponding to the hash. 393 func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool { 394 if has, err := db.Ancient(freezerHashTable, number); err == nil && common.BytesToHash(has) == hash { 395 return true 396 } 397 if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil { 398 return false 399 } 400 return true 401 } 402 403 // ReadBody retrieves the block body corresponding to the hash. 404 func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body { 405 data := ReadBodyRLP(db, hash, number) 406 if len(data) == 0 { 407 return nil 408 } 409 body := new(types.Body) 410 if err := rlp.Decode(bytes.NewReader(data), body); err != nil { 411 log.Error("Invalid block body RLP", "hash", hash, "err", err) 412 return nil 413 } 414 return body 415 } 416 417 // WriteBody stores a block body into the database. 418 func WriteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64, body *types.Body) { 419 data, err := rlp.EncodeToBytes(body) 420 if err != nil { 421 log.Fatal("Failed to RLP encode body", "err", err) 422 } 423 WriteBodyRLP(db, hash, number, data) 424 } 425 426 // DeleteBody removes all block body data associated with a hash. 427 func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 428 if err := db.Delete(blockBodyKey(number, hash)); err != nil { 429 log.Fatal("Failed to delete block body", "err", err) 430 } 431 } 432 433 // ReadPbCacheBody retrieves the block body corresponding to the hash. 434 func ReadPbCacheBody(db ethdb.Reader, hash common.Hash) *types.Body { 435 data, err := db.Get(pbBodyKey(hash)) 436 if err != nil { 437 log.Error("Failed to read block body", "hash", hash, "err", err) 438 return nil 439 } 440 if len(data) == 0 { 441 return nil 442 } 443 body := new(types.Body) 444 if err := rlp.Decode(bytes.NewReader(data), body); err != nil { 445 log.Error("Invalid pending block body RLP", "hash", hash, "err", err) 446 return nil 447 } 448 return body 449 } 450 451 // WritePbCacheBody stores a block body into the database. 452 func WritePbCacheBody(db ethdb.KeyValueWriter, hash common.Hash, body *types.Body) { 453 data, err := rlp.EncodeToBytes(body) 454 if err != nil { 455 log.Fatal("Failed to RLP encode body", "err", err) 456 } 457 if err := db.Put(pbBodyKey(hash), data); err != nil { 458 log.Fatal("Failed to write pbBodyKey", "err", err) 459 } 460 } 461 462 // DeletePbCacheBody removes all block body data associated with a hash. 463 func DeletePbCacheBody(db ethdb.KeyValueWriter, hash common.Hash) { 464 if err := db.Delete(pbBodyKey(hash)); err != nil { 465 log.Fatal("Failed to delete pb cache body", "err", err) 466 } 467 } 468 469 // ReadPbBodyKeys retreive's the phBodyKeys of the worker 470 func ReadPbBodyKeys(db ethdb.Reader) []common.Hash { 471 key := pbBodyHashKey() 472 data, err := db.Get(key) 473 if err != nil { 474 log.Error("Error in Reading pbBodyKeys", "err", err) 475 return nil 476 } 477 if len(data) == 0 { 478 return []common.Hash{} 479 } 480 keys := []common.Hash{} 481 if err := rlp.DecodeBytes(data, &keys); err != nil { 482 return []common.Hash{} 483 } 484 return keys 485 } 486 487 // WritePbBodyKeys writes the workers pendingHeaderBody keys to the db 488 func WritePbBodyKeys(db ethdb.KeyValueWriter, hashes []common.Hash) { 489 key := pbBodyHashKey() 490 data, err := rlp.EncodeToBytes(hashes) 491 if err != nil { 492 log.Fatal("Failed to RLP encode pending block body keys", "err", err) 493 } 494 if err := db.Put(key, data); err != nil { 495 log.Fatal("Failed to store pending block body keys", "err", err) 496 } 497 } 498 499 // DeleteAllPbBodyKeys delete the pendingHeaderBody keys to the db 500 func DeleteAllPbBodyKeys(db ethdb.KeyValueWriter) { 501 key := pbBodyHashKey() 502 503 if err := db.Delete(key); err != nil { 504 log.Fatal("Failed to delete pending block body keys", "err", err) 505 } 506 } 507 508 // ReadHeadsHashes retreive's the heads hashes of the blockchain. 509 func ReadTermini(db ethdb.Reader, hash common.Hash) *types.Termini { 510 key := terminiKey(hash) 511 data, _ := db.Get(key) 512 if len(data) == 0 { 513 return nil 514 } 515 var termini types.Termini 516 if err := rlp.DecodeBytes(data, &termini); err != nil { 517 return nil 518 } 519 return &termini 520 } 521 522 // WriteTermini writes the heads hashes of the blockchain. 523 func WriteTermini(db ethdb.KeyValueWriter, index common.Hash, hashes types.Termini) { 524 key := terminiKey(index) 525 data, err := rlp.EncodeToBytes(hashes) 526 if err != nil { 527 log.Fatal("Failed to RLP encode termini", "err", err) 528 } 529 if err := db.Put(key, data); err != nil { 530 log.Fatal("Failed to store last block's termini", "err", err) 531 } 532 } 533 534 // DeleteTermini writes the heads hashes of the blockchain. 535 func DeleteTermini(db ethdb.KeyValueWriter, hash common.Hash) { 536 key := terminiKey(hash) 537 538 if err := db.Delete(key); err != nil { 539 log.Fatal("Failed to delete termini ", "err", err) 540 } 541 } 542 543 // ReadPendingHeader retreive's the pending header stored in hash. 544 func ReadPendingHeader(db ethdb.Reader, hash common.Hash) *types.PendingHeader { 545 key := pendingHeaderKey(hash) 546 data, _ := db.Get(key) 547 if len(data) == 0 { 548 log.Debug("Pending Header is nil", "Key", key) 549 return nil 550 } 551 552 pendingHeader := new(types.PendingHeader) 553 if err := rlp.Decode(bytes.NewReader(data), pendingHeader); err != nil { 554 log.Error("Invalid pendingHeader RLP", "Err", err) 555 return nil 556 } 557 return pendingHeader 558 } 559 560 // WritePendingHeader writes the pending header of the terminus hash. 561 func WritePendingHeader(db ethdb.KeyValueWriter, hash common.Hash, pendingHeader types.PendingHeader) { 562 key := pendingHeaderKey(hash) 563 564 // Write the encoded pending header 565 data, err := rlp.EncodeToBytes(pendingHeader) 566 if err != nil { 567 log.Fatal("Failed to RLP encode pending header", "err", err) 568 } 569 570 if err := db.Put(key, data); err != nil { 571 log.Fatal("Failed to store header", "err", err) 572 } 573 } 574 575 // DeletePendingHeader deletes the pending header stored for the header hash. 576 func DeletePendingHeader(db ethdb.KeyValueWriter, hash common.Hash) { 577 key := pendingHeaderKey(hash) 578 if err := db.Delete(key); err != nil { 579 log.Fatal("Failed to delete slice pending header ", "err", err) 580 } 581 } 582 583 // ReadBestPhKey retreive's the bestPhKey of the blockchain 584 func ReadBestPhKey(db ethdb.Reader) common.Hash { 585 data, _ := db.Get(phHeadKey) 586 // get the ph cache keys. 587 if len(data) == 0 { 588 return common.Hash{} 589 } 590 bestPhKey := common.Hash{} 591 if err := rlp.DecodeBytes(data, &bestPhKey); err != nil { 592 return common.Hash{} 593 } 594 return bestPhKey 595 } 596 597 // WriteBestPhKey writes the bestPhKey of the blockchain 598 func WriteBestPhKey(db ethdb.KeyValueWriter, bestPhKey common.Hash) { 599 data, err := rlp.EncodeToBytes(bestPhKey) 600 if err != nil { 601 log.Fatal("Failed to RLP encode write best ph key", "err", err) 602 } 603 if err := db.Put(phHeadKey, data); err != nil { 604 log.Fatal("Failed to store last block's hash", "err", err) 605 } 606 } 607 608 // DeleteBestPhKey delete the bestPhKey of the blockchain 609 func DeleteBestPhKey(db ethdb.KeyValueWriter) { 610 if err := db.Delete(phHeadKey); err != nil { 611 log.Fatal("Failed to delete ph head", "err", err) 612 } 613 } 614 615 // ReadHeadsHashes retreive's the heads hashes of the blockchain. 616 func ReadHeadsHashes(db ethdb.Reader) []common.Hash { 617 data, _ := db.Get(headsHashesKey) 618 if len(data) == 0 { 619 return []common.Hash{} 620 } 621 hashes := []common.Hash{} 622 if err := rlp.DecodeBytes(data, &hashes); err != nil { 623 return []common.Hash{} 624 } 625 return hashes 626 } 627 628 // WriteHeadsHashes writes the heads hashes of the blockchain. 629 func WriteHeadsHashes(db ethdb.KeyValueWriter, hashes []common.Hash) { 630 data, err := rlp.EncodeToBytes(hashes) 631 if err != nil { 632 log.Fatal("Failed to RLP encode block total difficulty", "err", err) 633 } 634 if err := db.Put(headsHashesKey, data); err != nil { 635 log.Fatal("Failed to store last block's hash", "err", err) 636 } 637 } 638 639 // DeleteAllHeadsHashes writes the heads hashes of the blockchain. 640 func DeleteAllHeadsHashes(db ethdb.KeyValueWriter) { 641 if err := db.Delete(headsHashesKey); err != nil { 642 log.Fatal("Failed to delete block total difficulty", "err", err) 643 } 644 } 645 646 // HasReceipts verifies the existence of all the transaction receipts belonging 647 // to a block. 648 func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool { 649 if has, err := db.Ancient(freezerHashTable, number); err == nil && common.BytesToHash(has) == hash { 650 return true 651 } 652 if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil { 653 return false 654 } 655 return true 656 } 657 658 // ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding. 659 func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 660 // First try to look up the data in ancient database. Extra hash 661 // comparison is necessary since ancient database only maintains 662 // the canonical data. 663 data, _ := db.Ancient(freezerReceiptTable, number) 664 if len(data) > 0 { 665 h, _ := db.Ancient(freezerHashTable, number) 666 if common.BytesToHash(h) == hash { 667 return data 668 } 669 } 670 // Then try to look up the data in leveldb. 671 data, _ = db.Get(blockReceiptsKey(number, hash)) 672 if len(data) > 0 { 673 return data 674 } 675 // In the background freezer is moving data from leveldb to flatten files. 676 // So during the first check for ancient db, the data is not yet in there, 677 // but when we reach into leveldb, the data was already moved. That would 678 // result in a not found error. 679 data, _ = db.Ancient(freezerReceiptTable, number) 680 if len(data) > 0 { 681 h, _ := db.Ancient(freezerHashTable, number) 682 if common.BytesToHash(h) == hash { 683 return data 684 } 685 } 686 return nil // Can't find the data anywhere. 687 } 688 689 // ReadRawReceipts retrieves all the transaction receipts belonging to a block. 690 // The receipt metadata fields are not guaranteed to be populated, so they 691 // should not be used. Use ReadReceipts instead if the metadata is needed. 692 func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts { 693 // Retrieve the flattened receipt slice 694 data := ReadReceiptsRLP(db, hash, number) 695 if len(data) == 0 { 696 return nil 697 } 698 // Convert the receipts from their storage form to their internal representation 699 storageReceipts := []*types.ReceiptForStorage{} 700 if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { 701 log.Error("Invalid receipt array RLP", "hash", hash, "err", err) 702 return nil 703 } 704 receipts := make(types.Receipts, len(storageReceipts)) 705 for i, storageReceipt := range storageReceipts { 706 receipts[i] = (*types.Receipt)(storageReceipt) 707 } 708 return receipts 709 } 710 711 // ReadReceipts retrieves all the transaction receipts belonging to a block, including 712 // its correspoinding metadata fields. If it is unable to populate these metadata 713 // fields then nil is returned. 714 // 715 // The current implementation populates these metadata fields by reading the receipts' 716 // corresponding block body, so if the block body is not found it will return nil even 717 // if the receipt itself is stored. 718 func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts { 719 // We're deriving many fields from the block body, retrieve beside the receipt 720 receipts := ReadRawReceipts(db, hash, number) 721 if receipts == nil { 722 return nil 723 } 724 body := ReadBody(db, hash, number) 725 if body == nil { 726 log.Error("Missing body but have receipt", "hash", hash, "number", number) 727 return nil 728 } 729 if err := receipts.DeriveFields(config, hash, number, body.Transactions); err != nil { 730 log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err) 731 return nil 732 } 733 return receipts 734 } 735 736 // WriteReceipts stores all the transaction receipts belonging to a block. 737 func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) { 738 // Convert the receipts into their storage form and serialize them 739 storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) 740 for i, receipt := range receipts { 741 storageReceipts[i] = (*types.ReceiptForStorage)(receipt) 742 } 743 bytes, err := rlp.EncodeToBytes(storageReceipts) 744 if err != nil { 745 log.Fatal("Failed to encode block receipts", "err", err) 746 } 747 // Store the flattened receipt slice 748 if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil { 749 log.Fatal("Failed to store block receipts", "err", err) 750 } 751 } 752 753 // DeleteReceipts removes all receipt data associated with a block hash. 754 func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 755 if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { 756 log.Fatal("Failed to delete block receipts", "err", err) 757 } 758 } 759 760 // storedReceiptRLP is the storage encoding of a receipt. 761 // Re-definition in core/types/receipt.go. 762 type storedReceiptRLP struct { 763 PostStateOrStatus []byte 764 CumulativeGasUsed uint64 765 Logs []*types.LogForStorage 766 } 767 768 // ReceiptLogs is a barebone version of ReceiptForStorage which only keeps 769 // the list of logs. When decoding a stored receipt into this object we 770 // avoid creating the bloom filter. 771 type receiptLogs struct { 772 Logs []*types.Log 773 } 774 775 // DecodeRLP implements rlp.Decoder. 776 func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error { 777 var stored storedReceiptRLP 778 if err := s.Decode(&stored); err != nil { 779 return err 780 } 781 r.Logs = make([]*types.Log, len(stored.Logs)) 782 for i, log := range stored.Logs { 783 r.Logs[i] = (*types.Log)(log) 784 } 785 return nil 786 } 787 788 // DeriveLogFields fills the logs in receiptLogs with information such as block number, txhash, etc. 789 func deriveLogFields(receipts []*receiptLogs, hash common.Hash, number uint64, txs types.Transactions) error { 790 logIndex := uint(0) 791 if len(txs) != len(receipts) { 792 return errors.New("transaction and receipt count mismatch") 793 } 794 for i := 0; i < len(receipts); i++ { 795 txHash := txs[i].Hash() 796 // The derived log fields can simply be set from the block and transaction 797 for j := 0; j < len(receipts[i].Logs); j++ { 798 receipts[i].Logs[j].BlockNumber = number 799 receipts[i].Logs[j].BlockHash = hash 800 receipts[i].Logs[j].TxHash = txHash 801 receipts[i].Logs[j].TxIndex = uint(i) 802 receipts[i].Logs[j].Index = logIndex 803 logIndex++ 804 } 805 } 806 return nil 807 } 808 809 // ReadLogs retrieves the logs for all transactions in a block. The log fields 810 // are populated with metadata. In case the receipts or the block body 811 // are not found, a nil is returned. 812 func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64) [][]*types.Log { 813 // Retrieve the flattened receipt slice 814 data := ReadReceiptsRLP(db, hash, number) 815 if len(data) == 0 { 816 return nil 817 } 818 receipts := []*receiptLogs{} 819 if err := rlp.DecodeBytes(data, &receipts); err != nil { 820 log.Error("Invalid receipt array RLP", "hash", hash, "err", err) 821 return nil 822 } 823 824 body := ReadBody(db, hash, number) 825 if body == nil { 826 log.Error("Missing body but have receipt", "hash", hash, "number", number) 827 return nil 828 } 829 if err := deriveLogFields(receipts, hash, number, body.Transactions); err != nil { 830 log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err) 831 return nil 832 } 833 logs := make([][]*types.Log, len(receipts)) 834 for i, receipt := range receipts { 835 logs[i] = receipt.Logs 836 } 837 return logs 838 } 839 840 // ReadBlock retrieves an entire block corresponding to the hash, assembling it 841 // back from the stored header and body. If either the header or body could not 842 // be retrieved nil is returned. 843 // 844 // Note, due to concurrent download of header and block body the header and thus 845 // canonical hash can be stored in the database but the body data not (yet). 846 func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block { 847 header := ReadHeader(db, hash, number) 848 if header == nil { 849 return nil 850 } 851 body := ReadBody(db, hash, number) 852 if body == nil { 853 return nil 854 } 855 return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles, body.ExtTransactions, body.SubManifest) 856 } 857 858 // WriteBlock serializes a block into the database, header and body separately. 859 func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) { 860 WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) 861 WriteHeader(db, block.Header()) 862 } 863 864 // DeleteBlock removes all block data associated with a hash. 865 func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 866 DeleteReceipts(db, hash, number) 867 DeleteHeader(db, hash, number) 868 DeleteBody(db, hash, number) 869 } 870 871 // DeleteBlockWithoutNumber removes all block data associated with a hash, except 872 // the hash to number mapping. 873 func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 874 DeleteReceipts(db, hash, number) 875 deleteHeaderWithoutNumber(db, hash, number) 876 DeleteBody(db, hash, number) 877 } 878 879 const badBlockToKeep = 10 880 881 type badBlock struct { 882 Header *types.Header 883 Body *types.Body 884 } 885 886 // badBlockList implements the sort interface to allow sorting a list of 887 // bad blocks by their number in the reverse order. 888 type badBlockList []*badBlock 889 890 func (s badBlockList) Len() int { return len(s) } 891 func (s badBlockList) Less(i, j int) bool { 892 return s[i].Header.NumberU64() < s[j].Header.NumberU64() 893 } 894 func (s badBlockList) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 895 896 // ReadBadBlock retrieves the bad block with the corresponding block hash. 897 func ReadBadBlock(db ethdb.Reader, hash common.Hash) *types.Block { 898 blob, err := db.Get(badBlockKey) 899 if err != nil { 900 return nil 901 } 902 var badBlocks badBlockList 903 if err := rlp.DecodeBytes(blob, &badBlocks); err != nil { 904 return nil 905 } 906 for _, bad := range badBlocks { 907 if bad.Header.Hash() == hash { 908 return types.NewBlockWithHeader(bad.Header).WithBody(bad.Body.Transactions, bad.Body.Uncles, bad.Body.ExtTransactions, bad.Body.SubManifest) 909 } 910 } 911 return nil 912 } 913 914 // ReadAllBadBlocks retrieves all the bad blocks in the database. 915 // All returned blocks are sorted in reverse order by number. 916 func ReadAllBadBlocks(db ethdb.Reader) []*types.Block { 917 blob, err := db.Get(badBlockKey) 918 if err != nil { 919 return nil 920 } 921 var badBlocks badBlockList 922 if err := rlp.DecodeBytes(blob, &badBlocks); err != nil { 923 return nil 924 } 925 var blocks []*types.Block 926 for _, bad := range badBlocks { 927 blocks = append(blocks, types.NewBlockWithHeader(bad.Header).WithBody(bad.Body.Transactions, bad.Body.Uncles, bad.Body.ExtTransactions, bad.Body.SubManifest)) 928 } 929 return blocks 930 } 931 932 // WriteBadBlock serializes the bad block into the database. If the cumulated 933 // bad blocks exceeds the limitation, the oldest will be dropped. 934 func WriteBadBlock(db ethdb.KeyValueStore, block *types.Block) { 935 blob, err := db.Get(badBlockKey) 936 if err != nil { 937 log.Warn("Failed to load old bad blocks", "error", err) 938 } 939 var badBlocks badBlockList 940 if len(blob) > 0 { 941 if err := rlp.DecodeBytes(blob, &badBlocks); err != nil { 942 log.Fatal("Failed to decode old bad blocks", "error", err) 943 } 944 } 945 for _, b := range badBlocks { 946 if b.Header.NumberU64() == block.NumberU64() && b.Header.Hash() == block.Hash() { 947 log.Info("Skip duplicated bad block", "number", block.NumberU64(), "hash", block.Hash()) 948 return 949 } 950 } 951 badBlocks = append(badBlocks, &badBlock{ 952 Header: block.Header(), 953 Body: block.Body(), 954 }) 955 sort.Sort(sort.Reverse(badBlocks)) 956 if len(badBlocks) > badBlockToKeep { 957 badBlocks = badBlocks[:badBlockToKeep] 958 } 959 data, err := rlp.EncodeToBytes(badBlocks) 960 if err != nil { 961 log.Fatal("Failed to encode bad blocks", "err", err) 962 } 963 if err := db.Put(badBlockKey, data); err != nil { 964 log.Fatal("Failed to write bad blocks", "err", err) 965 } 966 } 967 968 // DeleteBadBlocks deletes all the bad blocks from the database 969 func DeleteBadBlocks(db ethdb.KeyValueWriter) { 970 if err := db.Delete(badBlockKey); err != nil { 971 log.Fatal("Failed to delete bad blocks", "err", err) 972 } 973 } 974 975 // FindCommonAncestor returns the last common ancestor of two block headers 976 func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header { 977 for bn := b.NumberU64(); a.NumberU64() > bn; { 978 a = ReadHeader(db, a.ParentHash(), a.NumberU64()-1) 979 if a == nil { 980 return nil 981 } 982 } 983 for an := a.NumberU64(); an < b.NumberU64(); { 984 b = ReadHeader(db, b.ParentHash(), b.NumberU64()-1) 985 if b == nil { 986 return nil 987 } 988 } 989 for a.Hash() != b.Hash() { 990 a = ReadHeader(db, a.ParentHash(), a.NumberU64()-1) 991 if a == nil { 992 return nil 993 } 994 b = ReadHeader(db, b.ParentHash(), b.NumberU64()-1) 995 if b == nil { 996 return nil 997 } 998 } 999 return a 1000 } 1001 1002 // ReadHeadHeader returns the current canonical head header. 1003 func ReadHeadHeader(db ethdb.Reader) *types.Header { 1004 headHeaderHash := ReadHeadHeaderHash(db) 1005 if headHeaderHash == (common.Hash{}) { 1006 return nil 1007 } 1008 headHeaderNumber := ReadHeaderNumber(db, headHeaderHash) 1009 if headHeaderNumber == nil { 1010 return nil 1011 } 1012 return ReadHeader(db, headHeaderHash, *headHeaderNumber) 1013 } 1014 1015 // ReadHeadBlock returns the current canonical head block. 1016 func ReadHeadBlock(db ethdb.Reader) *types.Block { 1017 headBlockHash := ReadHeadBlockHash(db) 1018 if headBlockHash == (common.Hash{}) { 1019 return nil 1020 } 1021 headBlockNumber := ReadHeaderNumber(db, headBlockHash) 1022 if headBlockNumber == nil { 1023 return nil 1024 } 1025 return ReadBlock(db, headBlockHash, *headBlockNumber) 1026 } 1027 1028 // ReadEtxSetRLP retrieves the EtxSet corresponding to a given block, in RLP encoding. 1029 func ReadEtxSetRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { 1030 // First try to look up the data in ancient database. Extra hash 1031 // comparison is necessary since ancient database only maintains 1032 // the canonical data. 1033 data, _ := db.Ancient(freezerEtxSetsTable, number) 1034 if len(data) > 0 { 1035 h, _ := db.Ancient(freezerHashTable, number) 1036 if common.BytesToHash(h) == hash { 1037 return data 1038 } 1039 } 1040 // Then try to look up the data in leveldb. 1041 data, _ = db.Get(etxSetKey(number, hash)) 1042 if len(data) > 0 { 1043 return data 1044 } 1045 // In the background freezer is moving data from leveldb to flatten files. 1046 // So during the first check for ancient db, the data is not yet in there, 1047 // but when we reach into leveldb, the data was already moved. That would 1048 // result in a not found error. 1049 data, _ = db.Ancient(freezerEtxSetsTable, number) 1050 if len(data) > 0 { 1051 h, _ := db.Ancient(freezerHashTable, number) 1052 if common.BytesToHash(h) == hash { 1053 return data 1054 } 1055 } 1056 return nil // Can't find the data anywhere. 1057 } 1058 1059 // WriteEtxSetRLP stores the EtxSet corresponding to a given block, in RLP encoding. 1060 func WriteEtxSetRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp rlp.RawValue) { 1061 if err := db.Put(etxSetKey(number, hash), rlp); err != nil { 1062 log.Fatal("Failed to store etx set", "err", err) 1063 } 1064 } 1065 1066 type EtxSetEntry struct { 1067 EtxHash common.Hash 1068 EtxHeight uint64 1069 Etx types.Transaction 1070 } 1071 1072 // ReadEtxSet retreives the EtxSet corresponding to a given block 1073 func ReadEtxSet(db ethdb.Reader, hash common.Hash, number uint64) types.EtxSet { 1074 data := ReadEtxSetRLP(db, hash, number) 1075 if len(data) == 0 { 1076 return nil 1077 } 1078 var entries []EtxSetEntry 1079 if err := rlp.Decode(bytes.NewReader(data), &entries); err != nil { 1080 log.Error("Invalid etx set RLP", "hash", hash, "err", err) 1081 return nil 1082 } 1083 etxSet := make(types.EtxSet) 1084 for _, entry := range entries { 1085 etxSet[entry.EtxHash] = types.EtxSetEntry{Height: entry.EtxHeight, ETX: entry.Etx} 1086 } 1087 return etxSet 1088 } 1089 1090 // WriteEtxSet stores the EtxSet corresponding to a given block 1091 func WriteEtxSet(db ethdb.KeyValueWriter, hash common.Hash, number uint64, etxSet types.EtxSet) { 1092 var entries []EtxSetEntry 1093 for etxHash, entry := range etxSet { 1094 entry := EtxSetEntry{EtxHash: etxHash, EtxHeight: entry.Height, Etx: entry.ETX} 1095 entries = append(entries, entry) 1096 } 1097 data, err := rlp.EncodeToBytes(entries) 1098 if err != nil { 1099 log.Fatal("Failed to RLP encode etx set", "err", err) 1100 } 1101 WriteEtxSetRLP(db, hash, number, data) 1102 } 1103 1104 // DeleteEtxSet removes all EtxSet data associated with a block. 1105 func DeleteEtxSet(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 1106 if err := db.Delete(etxSetKey(number, hash)); err != nil { 1107 log.Fatal("Failed to delete etx set", "err", err) 1108 } 1109 } 1110 1111 // ReadPendingEtxsRLP retrieves the set of pending ETXs for the given block, in RLP encoding 1112 func ReadPendingEtxsRLP(db ethdb.Reader, hash common.Hash) rlp.RawValue { 1113 // Try to look up the data in leveldb. 1114 data, _ := db.Get(pendingEtxsKey(hash)) 1115 if len(data) > 0 { 1116 return data 1117 } 1118 return nil // Can't find the data anywhere. 1119 } 1120 1121 // WritePendingEtxsRLP stores the pending ETXs corresponding to a given block, in RLP encoding. 1122 func WritePendingEtxsRLP(db ethdb.KeyValueWriter, hash common.Hash, rlp rlp.RawValue) { 1123 if err := db.Put(pendingEtxsKey(hash), rlp); err != nil { 1124 log.Fatal("Failed to store pending etxs", "err", err) 1125 } 1126 } 1127 1128 // ReadPendingEtxs retreives the pending ETXs corresponding to a given block 1129 func ReadPendingEtxs(db ethdb.Reader, hash common.Hash) *types.PendingEtxs { 1130 data := ReadPendingEtxsRLP(db, hash) 1131 if len(data) == 0 { 1132 return nil 1133 } 1134 pendingEtxs := types.PendingEtxs{} 1135 if err := rlp.Decode(bytes.NewReader(data), &pendingEtxs); err != nil { 1136 log.Error("Invalid pending etxs RLP", "hash", hash, "err", err) 1137 return nil 1138 } 1139 return &pendingEtxs 1140 } 1141 1142 // WritePendingEtxs stores the pending ETXs corresponding to a given block 1143 func WritePendingEtxs(db ethdb.KeyValueWriter, pendingEtxs types.PendingEtxs) { 1144 data, err := rlp.EncodeToBytes(pendingEtxs) 1145 if err != nil { 1146 log.Fatal("Failed to RLP encode pending etxs", "err", err) 1147 } 1148 WritePendingEtxsRLP(db, pendingEtxs.Header.Hash(), data) 1149 } 1150 1151 // DeletePendingEtxs removes all pending ETX data associated with a block. 1152 func DeletePendingEtxs(db ethdb.KeyValueWriter, hash common.Hash) { 1153 if err := db.Delete(pendingEtxsKey(hash)); err != nil { 1154 log.Fatal("Failed to delete pending etxs", "err", err) 1155 } 1156 } 1157 1158 // ReadPendingEtxsRollup retreives the pending ETXs rollup corresponding to a given block 1159 func ReadPendingEtxsRollup(db ethdb.Reader, hash common.Hash) *types.PendingEtxsRollup { 1160 // Try to look up the data in leveldb. 1161 data, _ := db.Get(pendingEtxsRollupKey(hash)) 1162 if len(data) == 0 { 1163 return nil 1164 } 1165 pendingEtxsRollup := types.PendingEtxsRollup{} 1166 if err := rlp.Decode(bytes.NewReader(data), &pendingEtxsRollup); err != nil { 1167 log.Error("Invalid pending etxs rollup rlp", "hash", hash, "err", err) 1168 return nil 1169 } 1170 return &pendingEtxsRollup 1171 } 1172 1173 // WritePendingEtxsRollup stores the pending ETXs rollup corresponding to a given block 1174 func WritePendingEtxsRollup(db ethdb.KeyValueWriter, pendingEtxsRollup types.PendingEtxsRollup) { 1175 data, err := rlp.EncodeToBytes(pendingEtxsRollup) 1176 if err != nil { 1177 log.Fatal("Failed to RLP encode pending etxs rollup", "err", err) 1178 } 1179 if err := db.Put(pendingEtxsRollupKey(pendingEtxsRollup.Header.Hash()), data); err != nil { 1180 log.Fatal("Failed to store pending etxs rollup", "err", err) 1181 } 1182 } 1183 1184 // DeletePendingEtxsRollup removes all pending ETX rollup data associated with a block. 1185 func DeletePendingEtxsRollup(db ethdb.KeyValueWriter, hash common.Hash) { 1186 if err := db.Delete(pendingEtxsRollupKey(hash)); err != nil { 1187 log.Fatal("Failed to delete pending etxs rollup", "err", err) 1188 } 1189 } 1190 1191 // ReadManifest retreives the manifest corresponding to a given block 1192 func ReadManifest(db ethdb.Reader, hash common.Hash) types.BlockManifest { 1193 // Try to look up the data in leveldb. 1194 data, _ := db.Get(manifestKey(hash)) 1195 if len(data) == 0 { 1196 return nil 1197 } 1198 manifest := types.BlockManifest{} 1199 if err := rlp.Decode(bytes.NewReader(data), &manifest); err != nil { 1200 log.Error("Invalid manifest rlp", "hash", hash, "err", err) 1201 return nil 1202 } 1203 return manifest 1204 } 1205 1206 // WriteManifest stores the manifest corresponding to a given block 1207 func WriteManifest(db ethdb.KeyValueWriter, hash common.Hash, manifest types.BlockManifest) { 1208 data, err := rlp.EncodeToBytes(manifest) 1209 if err != nil { 1210 log.Fatal("Failed to RLP encode manifest", "err", err) 1211 } 1212 if err := db.Put(manifestKey(hash), data); err != nil { 1213 log.Fatal("Failed to store manifest", "err", err) 1214 } 1215 } 1216 1217 // DeleteManifest removes manifest data associated with a block. 1218 func DeleteManifest(db ethdb.KeyValueWriter, hash common.Hash) { 1219 if err := db.Delete(manifestKey(hash)); err != nil { 1220 log.Fatal("Failed to delete manifest", "err", err) 1221 } 1222 } 1223 1224 // ReadBloomRLP retrieves the bloom for the given block, in RLP encoding 1225 func ReadBloomRLP(db ethdb.Reader, hash common.Hash) rlp.RawValue { 1226 // Try to look up the data in leveldb. 1227 data, _ := db.Get(bloomKey(hash)) 1228 if len(data) > 0 { 1229 return data 1230 } 1231 return nil // Can't find the data anywhere. 1232 } 1233 1234 // WriteBloomRLP stores the bloom corresponding to a given block, in RLP encoding. 1235 func WriteBloomRLP(db ethdb.KeyValueWriter, hash common.Hash, rlp rlp.RawValue) { 1236 if err := db.Put(bloomKey(hash), rlp); err != nil { 1237 log.Fatal("Failed to store block bloom filter", "err", err) 1238 } 1239 } 1240 1241 // ReadBloom retreives the bloom corresponding to a given block 1242 func ReadBloom(db ethdb.Reader, hash common.Hash) *types.Bloom { 1243 data := ReadBloomRLP(db, hash) 1244 if len(data) == 0 { 1245 return nil 1246 } 1247 bloom := types.Bloom{} 1248 if err := rlp.Decode(bytes.NewReader(data), &bloom); err != nil { 1249 log.Error("Invalid bloom RLP", "hash", hash, "err", err) 1250 return nil 1251 } 1252 return &bloom 1253 } 1254 1255 // WriteBloom stores the bloom corresponding to a given block 1256 func WriteBloom(db ethdb.KeyValueWriter, hash common.Hash, bloom types.Bloom) { 1257 data, err := rlp.EncodeToBytes(bloom) 1258 if err != nil { 1259 log.Fatal("Failed to RLP encode pending etxs", "err", err) 1260 } 1261 WriteBloomRLP(db, hash, data) 1262 } 1263 1264 // DeleteBloom removes all bloom data associated with a block. 1265 func DeleteBloom(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { 1266 if err := db.Delete(bloomKey(hash)); err != nil { 1267 log.Fatal("Failed to delete bloom", "err", err) 1268 } 1269 } 1270 1271 // ReadBadHashesList retreives the bad hashes corresponding to the recent fork 1272 func ReadBadHashesList(db ethdb.Reader) types.BlockManifest { 1273 // Try to look up the data in leveldb. 1274 data, _ := db.Get(badHashesListPrefix) 1275 if len(data) == 0 { 1276 return nil 1277 } 1278 badHashes := []common.Hash{} 1279 if err := rlp.Decode(bytes.NewReader(data), &badHashes); err != nil { 1280 log.Error("Invalid badHashesList rlp") 1281 return nil 1282 } 1283 return badHashes 1284 } 1285 1286 // WriteBadHashesList stores the bad hashes corresponding to the recent fork 1287 func WriteBadHashesList(db ethdb.KeyValueWriter, badHashes []common.Hash) { 1288 data, err := rlp.EncodeToBytes(badHashes) 1289 if err != nil { 1290 log.Fatal("Failed to RLP encode badHashesList", "err", err) 1291 } 1292 if err := db.Put(badHashesListPrefix, data); err != nil { 1293 log.Fatal("Failed to store badHashesList", "err", err) 1294 } 1295 } 1296 1297 // DeleteBadHashesList removes badHashesList from the database 1298 func DeleteBadHashesList(db ethdb.KeyValueWriter) { 1299 if err := db.Delete(badHashesListPrefix); err != nil { 1300 log.Fatal("Failed to delete badHashesList", "err", err) 1301 } 1302 } 1303 1304 // WriteInboundEtxs stores the inbound etxs for a given dom block hashes 1305 func WriteInboundEtxs(db ethdb.KeyValueWriter, hash common.Hash, inboundEtxs types.Transactions) { 1306 data, err := rlp.EncodeToBytes(inboundEtxs) 1307 if err != nil { 1308 log.Fatal("Failed to RLP encode inbound etxs", "err", err) 1309 } 1310 if err := db.Put(inboundEtxsKey(hash), data); err != nil { 1311 log.Fatal("Failed to store badHashesList", "err", err) 1312 } 1313 } 1314 1315 // ReadInboundEtxs reads the inbound etxs from the database 1316 func ReadInboundEtxs(db ethdb.Reader, hash common.Hash) types.Transactions { 1317 // Try to look up the data in leveldb. 1318 data, _ := db.Get(inboundEtxsKey(hash)) 1319 if len(data) == 0 { 1320 return nil 1321 } 1322 inboundEtxs := types.Transactions{} 1323 if err := rlp.Decode(bytes.NewReader(data), &inboundEtxs); err != nil { 1324 log.Error("Invalid inbound etxs on read", "hash", hash, "err", err) 1325 return nil 1326 } 1327 return inboundEtxs 1328 } 1329 1330 // DeleteInboundEtxs deletes the inbound etxs from the database 1331 func DeleteInboundEtxs(db ethdb.KeyValueWriter, hash common.Hash) { 1332 if err := db.Delete(inboundEtxsKey(hash)); err != nil { 1333 log.Fatal("Failed to delete inbound etxs", "err", err) 1334 } 1335 }