github.com/amazechain/amc@v0.1.3/modules/rawdb/accessors_chain.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package rawdb 18 19 import ( 20 "bytes" 21 "context" 22 "encoding/binary" 23 "fmt" 24 "github.com/amazechain/amc/api/protocol/types_pb" 25 "github.com/amazechain/amc/common/block" 26 "github.com/amazechain/amc/common/transaction" 27 "github.com/amazechain/amc/common/types" 28 "github.com/amazechain/amc/log" 29 "github.com/amazechain/amc/modules" 30 "google.golang.org/protobuf/proto" 31 32 "github.com/holiman/uint256" 33 "math" 34 "time" 35 36 common2 "github.com/ledgerwatch/erigon-lib/common" 37 "github.com/ledgerwatch/erigon-lib/kv" 38 ) 39 40 // ReadCanonicalHash retrieves the hash assigned to a canonical block number. 41 func ReadCanonicalHash(db kv.Getter, number uint64) (types.Hash, error) { 42 data, err := db.GetOne(modules.HeaderCanonical, modules.EncodeBlockNumber(number)) 43 if err != nil { 44 return types.Hash{}, fmt.Errorf("failed ReadCanonicalHash: %w, number=%d", err, number) 45 } 46 if len(data) == 0 { 47 return types.Hash{}, nil 48 } 49 return types.BytesToHash(data), nil 50 } 51 52 // WriteCanonicalHash stores the hash assigned to a canonical block number. 53 func WriteCanonicalHash(db kv.Putter, hash types.Hash, number uint64) error { 54 if err := db.Put(modules.HeaderCanonical, modules.EncodeBlockNumber(number), hash.Bytes()); err != nil { 55 return fmt.Errorf("failed to store number to hash mapping: %w", err) 56 } 57 return nil 58 } 59 60 // TruncateCanonicalHash removes all the number to hash canonical mapping from block number N 61 func TruncateCanonicalHash(tx kv.RwTx, blockFrom uint64, deleteHeaders bool) error { 62 if err := tx.ForEach(modules.HeaderCanonical, modules.EncodeBlockNumber(blockFrom), func(k, v []byte) error { 63 if deleteHeaders { 64 deleteHeader(tx, types.BytesToHash(v), blockFrom) 65 } 66 return tx.Delete(modules.HeaderCanonical, k) 67 }); err != nil { 68 return fmt.Errorf("TruncateCanonicalHash: %w", err) 69 } 70 return nil 71 } 72 73 // IsCanonicalHash determines whether a header with the given hash is on the canonical chain. 74 func IsCanonicalHash(db kv.Getter, hash types.Hash) (bool, error) { 75 number := ReadHeaderNumber(db, hash) 76 if number == nil { 77 return false, nil 78 } 79 canonicalHash, err := ReadCanonicalHash(db, *number) 80 if err != nil { 81 return false, err 82 } 83 return canonicalHash != (types.Hash{}) && canonicalHash == hash, nil 84 } 85 86 // ReadHeaderNumber returns the header number assigned to a hash. 87 func ReadHeaderNumber(db kv.Getter, hash types.Hash) *uint64 { 88 data, err := db.GetOne(modules.HeaderNumber, hash.Bytes()) 89 if err != nil { 90 log.Error("ReadHeaderNumber failed", "err", err) 91 } 92 if len(data) == 0 { 93 return nil 94 } 95 if len(data) != 8 { 96 log.Error("ReadHeaderNumber got wrong data len", "len", len(data)) 97 return nil 98 } 99 number := binary.BigEndian.Uint64(data) 100 return &number 101 } 102 103 // WriteHeaderNumber stores the hash->number mapping. 104 func WriteHeaderNumber(db kv.Putter, hash types.Hash, number uint64) error { 105 if err := db.Put(modules.HeaderNumber, hash[:], modules.EncodeBlockNumber(number)); err != nil { 106 return err 107 } 108 return nil 109 } 110 111 // DeleteHeaderNumber removes hash->number mapping. 112 func DeleteHeaderNumber(db kv.Deleter, hash types.Hash) { 113 if err := db.Delete(modules.HeaderNumber, hash[:]); err != nil { 114 log.Crit("Failed to delete hash mapping", "err", err) 115 } 116 } 117 118 // ReadHeaderRAW retrieves a block header in its raw database encoding. 119 func ReadHeaderRAW(db kv.Getter, hash types.Hash, number uint64) []byte { 120 data, err := db.GetOne(modules.Headers, modules.HeaderKey(number, hash)) 121 if err != nil { 122 log.Error("ReadHeaderRAW failed", "err", err) 123 } 124 return data 125 } 126 127 // HasHeader verifies the existence of a block header corresponding to the hash. 128 func HasHeader(db kv.Has, hash types.Hash, number uint64) bool { 129 if has, err := db.Has(modules.Headers, modules.HeaderKey(number, hash)); !has || err != nil { 130 return false 131 } 132 return true 133 } 134 135 // ReadHeader retrieves the block header corresponding to the hash. 136 func ReadHeader(db kv.Getter, hash types.Hash, number uint64) *block.Header { 137 data := ReadHeaderRAW(db, hash, number) 138 if len(data) == 0 { 139 return nil 140 } 141 142 header := new(block.Header) 143 pbHeader := new(types_pb.Header) 144 145 if err := proto.Unmarshal(data, pbHeader); err != nil { 146 log.Error("Invalid block header RAW", "hash", hash, "err", err) 147 return nil 148 } 149 150 if err := header.FromProtoMessage(pbHeader); err != nil { 151 log.Error("header FromProtoMessage failed", "err", err) 152 return nil 153 } 154 return header 155 } 156 157 //func ReadCurrentBlockNumber(db kv.Getter) *uint64 { 158 // headHash := ReadHeadHeaderHash(db) 159 // return ReadHeaderNumber(db, headHash) 160 //} 161 // 162 //func ReadCurrentHeader(db kv.Getter) *types.Header { 163 // headHash := ReadHeadHeaderHash(db) 164 // headNumber := ReadHeaderNumber(db, headHash) 165 // if headNumber == nil { 166 // return nil 167 // } 168 // return ReadHeader(db, headHash, *headNumber) 169 //} 170 171 //func ReadCurrentBlock(db kv.Tx) *types.Block { 172 // headHash := ReadHeadBlockHash(db) 173 // headNumber := ReadHeaderNumber(db, headHash) 174 // if headNumber == nil { 175 // return nil 176 // } 177 // return ReadBlock(db, headHash, *headNumber) 178 //} 179 180 //func ReadLastBlockSynced(db kv.Tx) (*types.Block, error) { 181 // headNumber, err := stages.GetStageProgress(db, stages.Execution) 182 // if err != nil { 183 // return nil, err 184 // } 185 // headHash, err := ReadCanonicalHash(db, headNumber) 186 // if err != nil { 187 // return nil, err 188 // } 189 // return ReadBlock(db, headHash, headNumber), nil 190 //} 191 192 func ReadHeadersByNumber(db kv.Tx, number uint64) ([]*block.Header, error) { 193 var res []*block.Header 194 c, err := db.Cursor(modules.Headers) 195 if err != nil { 196 return nil, err 197 } 198 defer c.Close() 199 prefix := modules.EncodeBlockNumber(number) 200 for k, v, err := c.Seek(prefix); k != nil; k, v, err = c.Next() { 201 if err != nil { 202 return nil, err 203 } 204 if !bytes.HasPrefix(k, prefix) { 205 break 206 } 207 208 header := new(block.Header) 209 pbHeader := new(types_pb.Header) 210 if err := proto.Unmarshal(v, pbHeader); err != nil { 211 return nil, fmt.Errorf("invalid block header RAW: hash=%x, err=%w", k[8:], err) 212 } 213 if err := header.FromProtoMessage(pbHeader); nil != err { 214 return nil, fmt.Errorf("invalid block pbHeader: hash=%x, err =%w", k[8:], err) 215 } 216 res = append(res, header) 217 } 218 return res, nil 219 } 220 221 // WriteHeader stores a block header into the database and also stores the hash- 222 // to-number mapping. 223 func WriteHeader(db kv.Putter, header *block.Header) { 224 var ( 225 hash = header.Hash() 226 number = header.Number.Uint64() 227 ) 228 229 if err := WriteHeaderNumber(db, hash, number); nil != err { 230 log.Crit("Failed to store hash to number mapping", "err", err) 231 } 232 233 // Write the encoded header 234 data, err := header.Marshal() 235 if nil != err { 236 log.Crit("failed to Marshal header", "err", err) 237 } 238 if err := db.Put(modules.Headers, modules.HeaderKey(number, hash), data); err != nil { 239 log.Crit("Failed to store header", "err", err) 240 } 241 } 242 243 // deleteHeader - dangerous, use DeleteAncientBlocks/TruncateBlocks methods 244 func deleteHeader(db kv.Deleter, hash types.Hash, number uint64) { 245 if err := db.Delete(modules.Headers, modules.HeaderKey(number, hash)); err != nil { 246 log.Crit("Failed to delete header", "err", err) 247 } 248 if err := db.Delete(modules.HeaderNumber, hash.Bytes()); err != nil { 249 log.Crit("Failed to delete hash to number mapping", "err", err) 250 } 251 } 252 253 // ReadBodyRAW retrieves the block body (transactions and uncles) in encoding. 254 func ReadBodyRAW(db kv.Tx, hash types.Hash, number uint64) []byte { 255 body := ReadCanonicalBodyWithTransactions(db, hash, number) 256 pbBody := body.ToProtoMessage() 257 258 bodyRaw, err := proto.Marshal(pbBody) 259 if err != nil { 260 log.Error("ReadBodyRAW failed", "err", err) 261 } 262 return bodyRaw 263 } 264 265 func ReadStorageBodyRAW(db kv.Getter, hash types.Hash, number uint64) []byte { 266 bodyRaw, err := db.GetOne(modules.BlockBody, modules.BlockBodyKey(number, hash)) 267 if err != nil { 268 log.Error("ReadBodyRAW failed", "err", err) 269 } 270 return bodyRaw 271 } 272 273 func ReadStorageBody(db kv.Getter, hash types.Hash, number uint64) (block.BodyForStorage, error) { 274 bodyRaw, err := db.GetOne(modules.BlockBody, modules.BlockBodyKey(number, hash)) 275 if err != nil { 276 log.Error("ReadBodyRAW failed", "err", err) 277 } 278 if len(bodyRaw) != 8+4 { 279 return block.BodyForStorage{}, fmt.Errorf("invalid body raw") 280 } 281 bodyForStorage := new(block.BodyForStorage) 282 bodyForStorage.BaseTxId = binary.BigEndian.Uint64(bodyRaw[:8]) 283 bodyForStorage.TxAmount = binary.BigEndian.Uint32(bodyRaw[8:]) 284 return *bodyForStorage, nil 285 } 286 287 func CanonicalTxnByID(db kv.Getter, id uint64) (*transaction.Transaction, error) { 288 txIdKey := make([]byte, 8) 289 binary.BigEndian.PutUint64(txIdKey, id) 290 v, err := db.GetOne(modules.BlockTx, txIdKey) 291 if err != nil { 292 return nil, err 293 } 294 295 tx := new(transaction.Transaction) 296 if err := tx.Unmarshal(v); nil != err { 297 return nil, err 298 } 299 300 return tx, nil 301 } 302 303 func CanonicalTransactions(db kv.Getter, baseTxId uint64, amount uint32) ([]*transaction.Transaction, error) { 304 if amount == 0 { 305 return []*transaction.Transaction{}, nil 306 } 307 txIdKey := make([]byte, 8) 308 txs := make([]*transaction.Transaction, amount) 309 binary.BigEndian.PutUint64(txIdKey, baseTxId) 310 i := uint32(0) 311 312 if err := db.ForAmount(modules.BlockTx, txIdKey, amount, func(k, v []byte) error { 313 var decodeErr error 314 tx := new(transaction.Transaction) 315 if decodeErr = tx.Unmarshal(v); nil != decodeErr { 316 return decodeErr 317 } 318 txs[i] = tx 319 i++ 320 return nil 321 }); err != nil { 322 return nil, err 323 } 324 txs = txs[:i] // user may request big "amount", but db can return small "amount". Return as much as we found. 325 return txs, nil 326 } 327 328 func WriteTransactions(db kv.RwTx, txs []*transaction.Transaction, baseTxId uint64) error { 329 txId := baseTxId 330 for _, tx := range txs { 331 txIdKey := make([]byte, 8) 332 binary.BigEndian.PutUint64(txIdKey, txId) 333 txId++ 334 var data []byte 335 336 data, err := tx.Marshal() 337 if err != nil { 338 return err 339 } 340 341 //if _, err := tx.MarshalTo(data); nil != err { 342 // return fmt.Errorf("broken tx marshal: %w", err) 343 //} 344 345 // If next Append returns KeyExists error - it means you need to open transaction in App code before calling this func. Batch is also fine. 346 if err := db.Append(modules.BlockTx, txIdKey, types.CopyBytes(data)); err != nil { 347 return err 348 } 349 } 350 return nil 351 } 352 353 func WriteRawTransactions(tx kv.RwTx, txs [][]byte, baseTxId uint64) error { 354 txId := baseTxId 355 for _, txn := range txs { 356 txIdKey := make([]byte, 8) 357 binary.BigEndian.PutUint64(txIdKey, txId) 358 // If next Append returns KeyExists error - it means you need to open transaction in App code before calling this func. Batch is also fine. 359 if err := tx.Append(modules.BlockTx, txIdKey, txn); err != nil { 360 return fmt.Errorf("txId=%d, baseTxId=%d, %w", txId, baseTxId, err) 361 } 362 txId++ 363 } 364 return nil 365 } 366 367 // WriteBodyForStorage stores an encoded block body into the database. 368 func WriteBodyForStorage(db kv.Putter, hash types.Hash, number uint64, body *block.BodyForStorage) error { 369 v := modules.BodyStorageValue(body.BaseTxId, body.TxAmount) 370 return db.Put(modules.BlockBody, modules.BlockBodyKey(number, hash), v) 371 } 372 373 // ReadBodyByNumber - returns canonical block body 374 func ReadBodyByNumber(db kv.Tx, number uint64) (*block.Body, uint64, uint32, error) { 375 hash, err := ReadCanonicalHash(db, number) 376 if err != nil { 377 return nil, 0, 0, fmt.Errorf("failed ReadCanonicalHash: %w", err) 378 } 379 if hash == (types.Hash{}) { 380 return nil, 0, 0, nil 381 } 382 body, baseTxId, txAmount := ReadBody(db, hash, number) 383 return body, baseTxId, txAmount, nil 384 } 385 386 func ReadBodyWithTransactions(db kv.Getter, hash types.Hash, number uint64) (*block.Body, error) { 387 canonicalHash, err := ReadCanonicalHash(db, number) 388 if err != nil { 389 return nil, fmt.Errorf("read canonical hash failed: %d, %w", number, err) 390 } 391 if canonicalHash == hash { 392 return ReadCanonicalBodyWithTransactions(db, hash, number), nil 393 } 394 return nil, fmt.Errorf("mismatch hash: %v", hash) 395 } 396 397 func ReadCanonicalBodyWithTransactions(db kv.Getter, hash types.Hash, number uint64) *block.Body { 398 body, baseTxId, txAmount := ReadBody(db, hash, number) 399 if body == nil { 400 return nil 401 } 402 var err error 403 body.Txs, err = CanonicalTransactions(db, baseTxId, txAmount) 404 if err != nil { 405 log.Error("failed ReadTransactionByHash", "hash", hash, "block", number, "err", err) 406 return nil 407 } 408 409 verifies, err := ReadVerifies(db, hash, number) 410 if nil != err { 411 log.Error("read verifier failed", err) 412 return nil 413 } 414 body.Verifiers = verifies 415 416 rewards, err := ReadRewards(db, hash, number) 417 if nil != err { 418 log.Error("read reward failed", err) 419 return nil 420 } 421 body.Rewards = rewards 422 return body 423 } 424 425 func RawTransactionsRange(db kv.Getter, from, to uint64) (res [][]byte, err error) { 426 blockKey := make([]byte, modules.NumberLength+types.HashLength) 427 encNum := make([]byte, 8) 428 for i := from; i < to+1; i++ { 429 binary.BigEndian.PutUint64(encNum, i) 430 hash, err := db.GetOne(modules.HeaderCanonical, encNum) 431 if err != nil { 432 return nil, err 433 } 434 if len(hash) == 0 { 435 continue 436 } 437 438 binary.BigEndian.PutUint64(blockKey, i) 439 copy(blockKey[modules.NumberLength:], hash) 440 bodyRaw, err := db.GetOne(modules.BlockBody, blockKey) 441 if err != nil { 442 return nil, err 443 } 444 if len(bodyRaw) == 0 { 445 continue 446 } 447 448 baseTxId := binary.BigEndian.Uint64(bodyRaw[:8]) 449 txAmount := binary.BigEndian.Uint32(bodyRaw[8:]) 450 451 binary.BigEndian.PutUint64(encNum, baseTxId) 452 if err = db.ForAmount(modules.BlockTx, encNum, txAmount, func(k, v []byte) error { 453 res = append(res, v) 454 return nil 455 }); err != nil { 456 return nil, err 457 } 458 } 459 return 460 } 461 462 func ReadBodyForStorageByKey(db kv.Getter, k []byte) (*block.BodyForStorage, error) { 463 bodyRaw, err := db.GetOne(modules.BlockBody, k) 464 if err != nil { 465 return nil, err 466 } 467 if len(bodyRaw) == 0 { 468 return nil, nil 469 } 470 bodyForStorage := new(block.BodyForStorage) 471 bodyForStorage.BaseTxId = binary.BigEndian.Uint64(bodyRaw[:8]) 472 bodyForStorage.TxAmount = binary.BigEndian.Uint32(bodyRaw[8:]) 473 return bodyForStorage, nil 474 } 475 476 func ReadBody(db kv.Getter, hash types.Hash, number uint64) (*block.Body, uint64, uint32) { 477 data := ReadStorageBodyRAW(db, hash, number) 478 if len(data) == 0 { 479 return nil, 0, 0 480 } 481 bodyForStorage := new(block.BodyForStorage) 482 bodyForStorage.BaseTxId = binary.BigEndian.Uint64(data[:8]) 483 bodyForStorage.TxAmount = binary.BigEndian.Uint32(data[8:]) 484 485 body := new(block.Body) 486 if bodyForStorage.TxAmount < 2 { 487 panic(fmt.Sprintf("block body hash too few txs amount: %d, %d", number, bodyForStorage.TxAmount)) 488 } 489 return body, bodyForStorage.BaseTxId + 1, bodyForStorage.TxAmount - 2 // 1 system txn in the begining of block, and 1 at the end 490 } 491 492 func ReadSenders(db kv.Getter, hash types.Hash, number uint64) ([]types.Address, error) { 493 data, err := db.GetOne(modules.Senders, modules.BlockBodyKey(number, hash)) 494 if err != nil { 495 return nil, fmt.Errorf("readSenders failed: %w", err) 496 } 497 senders := make([]types.Address, len(data)/types.AddressLength) 498 for i := 0; i < len(senders); i++ { 499 copy(senders[i][:], data[i*types.AddressLength:]) 500 } 501 return senders, nil 502 } 503 504 func WriteRawBodyIfNotExists(db kv.RwTx, hash types.Hash, number uint64, body *block.RawBody) (ok bool, lastTxnNum uint64, err error) { 505 exists, err := db.Has(modules.BlockBody, modules.BlockBodyKey(number, hash)) 506 if err != nil { 507 return false, 0, err 508 } 509 if exists { 510 return false, 0, nil 511 } 512 return WriteRawBody(db, hash, number, body) 513 } 514 515 func WriteRawBody(db kv.RwTx, hash types.Hash, number uint64, body *block.RawBody) (ok bool, lastTxnNum uint64, err error) { 516 baseTxId, err := db.IncrementSequence(modules.BlockTx, uint64(len(body.Transactions))+2) 517 if err != nil { 518 return false, 0, err 519 } 520 data := block.BodyForStorage{ 521 BaseTxId: baseTxId, 522 TxAmount: uint32(len(body.Transactions)) + 2, 523 } 524 if err = WriteBodyForStorage(db, hash, number, &data); err != nil { 525 return false, 0, fmt.Errorf("WriteBodyForStorage: %w", err) 526 } 527 lastTxnNum = baseTxId + uint64(len(body.Transactions)) + 2 528 if err = WriteRawTransactions(db, body.Transactions, baseTxId+1); err != nil { 529 return false, 0, fmt.Errorf("WriteRawTransactions: %w", err) 530 } 531 return true, lastTxnNum, nil 532 } 533 534 func WriteBody(db kv.RwTx, hash types.Hash, number uint64, body *block.Body) error { 535 // Pre-processing 536 body.SendersFromTxs() 537 baseTxId, err := db.IncrementSequence(modules.BlockTx, uint64(len(body.Txs))+2) 538 if err != nil { 539 return err 540 } 541 data := block.BodyForStorage{ 542 BaseTxId: baseTxId, 543 TxAmount: uint32(len(body.Txs)) + 2, 544 } 545 if err := WriteBodyForStorage(db, hash, number, &data); err != nil { 546 return fmt.Errorf("failed to write body: %w", err) 547 } 548 err = WriteTransactions(db, body.Transactions(), baseTxId+1) 549 if err != nil { 550 return fmt.Errorf("failed to WriteTransactions: %w", err) 551 } 552 553 if len(body.Verifiers) > 0 { 554 if err := WriteVerifies(db, hash, number, body.Verifiers); nil != err { 555 return err 556 } 557 } 558 if len(body.Rewards) > 0 { 559 if err := WriteRewards(db, hash, number, body.Rewards); nil != err { 560 return err 561 } 562 } 563 564 return nil 565 } 566 567 func ReadVerifies(db kv.Getter, hash types.Hash, number uint64) ([]*block.Verify, error) { 568 data, err := db.GetOne(modules.BlockVerify, modules.BlockBodyKey(number, hash)) 569 if err != nil { 570 return nil, fmt.Errorf("ReadVerifies failed: %w", err) 571 } 572 verifies := make([]*block.Verify, len(data)/(types.PublicKeyLength+types.AddressLength)) 573 for i := 0; i < len(verifies); i++ { 574 verifies[i] = &block.Verify{ 575 Address: types.Address{}, 576 PublicKey: types.PublicKey{}, 577 } 578 copy(verifies[i].PublicKey[:], data[i*(types.PublicKeyLength+types.AddressLength):]) 579 copy(verifies[i].Address[:], data[i*(types.PublicKeyLength+types.AddressLength)+types.PublicKeyLength:]) 580 } 581 return verifies, nil 582 } 583 584 func WriteVerifies(db kv.Putter, hash types.Hash, number uint64, verifies []*block.Verify) error { 585 data := make([]byte, (types.AddressLength+types.PublicKeyLength)*len(verifies)) 586 for i, v := range verifies { 587 copy(data[i*(types.AddressLength+types.PublicKeyLength):], v.PublicKey[:]) 588 copy(data[i*(types.AddressLength+types.PublicKeyLength)+types.PublicKeyLength:], v.Address[:]) 589 } 590 if err := db.Put(modules.BlockVerify, modules.BlockBodyKey(number, hash), data); err != nil { 591 return fmt.Errorf("failed to store block senders: %w", err) 592 } 593 return nil 594 } 595 596 func ReadRewards(db kv.Getter, hash types.Hash, number uint64) ([]*block.Reward, error) { 597 data, err := db.GetOne(modules.BlockRewards, modules.BlockBodyKey(number, hash)) 598 if err != nil { 599 return nil, fmt.Errorf("ReadBlockRewards failed: %w", err) 600 } 601 602 reward := make([]*block.Reward, len(data)/(32+types.AddressLength)) 603 for i := 0; i < len(reward); i++ { 604 reward[i] = &block.Reward{ 605 Address: *new(types.Address).SetBytes(data[i*(32+types.AddressLength) : i*(32+types.AddressLength)+types.AddressLength]), 606 Amount: new(uint256.Int).SetBytes(data[i*(32+types.AddressLength)+types.AddressLength : i*(32+types.AddressLength)+types.AddressLength+32]), 607 } 608 } 609 return reward, nil 610 } 611 612 func WriteRewards(db kv.Putter, hash types.Hash, number uint64, rewards []*block.Reward) error { 613 614 data := make([]byte, (types.AddressLength+32)*len(rewards)) 615 for i, reward := range rewards { 616 byte32 := reward.Amount.Bytes32() 617 copy(data[i*(types.AddressLength+32):], reward.Address[:]) 618 copy(data[i*(types.AddressLength+32)+types.AddressLength:], byte32[:]) 619 } 620 if err := db.Put(modules.BlockRewards, modules.BlockBodyKey(number, hash), data); err != nil { 621 return fmt.Errorf("failed to store block rewards: %w", err) 622 } 623 return nil 624 } 625 626 // deleteBody removes all block body data associated with a hash. 627 func deleteBody(db kv.Deleter, hash types.Hash, number uint64) { 628 if err := db.Delete(modules.BlockBody, modules.BlockBodyKey(number, hash)); err != nil { 629 log.Crit("Failed to delete block body", "err", err) 630 } 631 } 632 633 // ReadTd retrieves a block's total difficulty corresponding to the hash. 634 func ReadTd(db kv.Getter, hash types.Hash, number uint64) (*uint256.Int, error) { 635 data, err := db.GetOne(modules.HeaderTD, modules.HeaderKey(number, hash)) 636 if err != nil { 637 return nil, fmt.Errorf("failed ReadTd: %w", err) 638 } 639 if data == nil { 640 return nil, nil 641 } 642 td := uint256.NewInt(0).SetBytes(data) 643 log.Trace("readTD", "hash", hash, "number", number, "td", td.Uint64()) 644 return td, nil 645 } 646 647 func ReadTdByHash(db kv.Getter, hash types.Hash) (*uint256.Int, error) { 648 headNumber := ReadHeaderNumber(db, hash) 649 if headNumber == nil { 650 return nil, nil 651 } 652 return ReadTd(db, hash, *headNumber) 653 } 654 655 // WriteTd stores the total difficulty of a block into the database. 656 func WriteTd(db kv.Putter, hash types.Hash, number uint64, td *uint256.Int) error { 657 data := td.Bytes() 658 if err := db.Put(modules.HeaderTD, modules.HeaderKey(number, hash), data); err != nil { 659 return fmt.Errorf("failed to store block total difficulty: %w", err) 660 } 661 return nil 662 } 663 664 // TruncateTd removes all block total difficulty from block number N 665 func TruncateTd(tx kv.RwTx, blockFrom uint64) error { 666 if err := tx.ForEach(modules.HeaderTD, modules.EncodeBlockNumber(blockFrom), func(k, _ []byte) error { 667 return tx.Delete(modules.HeaderTD, k) 668 }); err != nil { 669 return fmt.Errorf("TruncateTd: %w", err) 670 } 671 return nil 672 } 673 674 // HasReceipts verifies the existence of all the transaction receipts belonging 675 // to a block. 676 func HasReceipts(db kv.Has, number uint64) bool { 677 if has, err := db.Has(modules.Receipts, modules.EncodeBlockNumber(number)); !has || err != nil { 678 return false 679 } 680 return true 681 } 682 683 // ReadRawReceipts retrieves all the transaction receipts belonging to a block. 684 // The receipt metadata fields are not guaranteed to be populated, so they 685 // should not be used. Use ReadReceipts instead if the metadata is needed. 686 func ReadRawReceipts(db kv.Tx, blockNum uint64) block.Receipts { 687 // Retrieve the flattened receipt slice 688 data, err := db.GetOne(modules.Receipts, modules.EncodeBlockNumber(blockNum)) 689 if err != nil { 690 log.Error("ReadRawReceipts failed", "err", err) 691 } 692 if len(data) == 0 { 693 return nil 694 } 695 var receipts block.Receipts 696 697 if err := receipts.Unmarshal(data); nil != err { 698 log.Error("ReadRawReceipts failed", "err", err) 699 return nil 700 } 701 702 //prefix := make([]byte, 8) 703 //binary.BigEndian.PutUint64(prefix, blockNum) 704 //if err := db.ForPrefix(Log, prefix, func(k, v []byte) error { 705 // var logs block.Logs 706 // if err := logs.Unmarshal(v); err != nil { 707 // return fmt.Errorf("receipt unmarshal failed: %w", err) 708 // } 709 // 710 // receipts[binary.BigEndian.Uint32(k[8:])].Logs = logs 711 // return nil 712 //}); err != nil { 713 // log.Error("logs fetching failed", "err", err) 714 // return nil 715 //} 716 717 return receipts 718 } 719 720 // ReadReceipts retrieves all the transaction receipts belonging to a block, including 721 // its corresponding metadata fields. If it is unable to populate these metadata 722 // fields then nil is returned. 723 // 724 // The current implementation populates these metadata fields by reading the receipts' 725 // corresponding block body, so if the block body is not found it will return nil even 726 // if the receipt itself is stored. 727 func ReadReceipts(db kv.Tx, block *block.Block, senders []types.Address) block.Receipts { 728 if block == nil { 729 return nil 730 } 731 // We're deriving many fields from the block body, retrieve beside the receipt 732 receipts := ReadRawReceipts(db, block.Number64().Uint64()) 733 if receipts == nil { 734 return nil 735 } 736 if len(senders) > 0 { 737 block.SendersToTxs(senders) 738 } 739 //if err := receipts.DeriveFields(block.Hash(), block.NumberU64(), block.Transactions(), senders); err != nil { 740 // log.Error("Failed to derive block receipts fields", "hash", block.Hash(), "number", block.NumberU64(), "err", err, "stack", dbg.Stack()) 741 // return nil 742 //} 743 return receipts 744 } 745 746 func ReadReceiptsByHash(db kv.Tx, hash types.Hash) (block.Receipts, error) { 747 number := ReadHeaderNumber(db, hash) 748 if number == nil { 749 return nil, nil 750 } 751 canonicalHash, err := ReadCanonicalHash(db, *number) 752 if err != nil { 753 return nil, fmt.Errorf("requested non-canonical hash %x. canonical=%x", hash, canonicalHash) 754 } 755 b, s, err := ReadBlockWithSenders(db, hash, *number) 756 if err != nil { 757 return nil, err 758 } 759 if b == nil { 760 return nil, nil 761 } 762 receipts := ReadReceipts(db, b, s) 763 if receipts == nil { 764 return nil, nil 765 } 766 return receipts, nil 767 } 768 769 // WriteReceipts stores all the transaction receipts belonging to a block. 770 func WriteReceipts(tx kv.Putter, number uint64, receipts block.Receipts) error { 771 for txId, r := range receipts { 772 if len(r.Logs) == 0 { 773 continue 774 } 775 var logs block.Logs 776 logs = r.Logs 777 v, err := logs.Marshal() 778 if err != nil { 779 return fmt.Errorf("encode block logs for block %d: %w", number, err) 780 } 781 782 if err = tx.Put(modules.Log, modules.LogKey(number, uint32(txId)), v); err != nil { 783 return fmt.Errorf("writing logs for block %d: %w", number, err) 784 } 785 } 786 787 v, err := receipts.Marshal() 788 if err != nil { 789 return fmt.Errorf("encode block receipts for block %d: %w", number, err) 790 } 791 792 if err = tx.Put(modules.Receipts, modules.EncodeBlockNumber(number), v); err != nil { 793 return fmt.Errorf("writing receipts for block %d: %w", number, err) 794 } 795 return nil 796 } 797 798 // AppendReceipts stores all the transaction receipts belonging to a block. 799 func AppendReceipts(tx kv.StatelessWriteTx, blockNumber uint64, receipts block.Receipts) error { 800 for txId, r := range receipts { 801 if len(r.Logs) == 0 { 802 continue 803 } 804 805 var logs block.Logs 806 logs = r.Logs 807 v, err := logs.Marshal() 808 if nil != err { 809 return err 810 } 811 812 if err = tx.Append(modules.Log, modules.LogKey(blockNumber, uint32(txId)), v); err != nil { 813 return fmt.Errorf("writing receipts for block %d: %w", blockNumber, err) 814 } 815 } 816 817 rv, err := receipts.Marshal() 818 if err != nil { 819 return fmt.Errorf("encode block receipts for block %d: %w", blockNumber, err) 820 } 821 822 if err = tx.Append(modules.Receipts, modules.EncodeBlockNumber(blockNumber), rv); err != nil { 823 return fmt.Errorf("writing receipts for block %d: %w", blockNumber, err) 824 } 825 return nil 826 } 827 828 // TruncateReceipts removes all receipt for given block number or newer 829 func TruncateReceipts(db kv.RwTx, number uint64) error { 830 if err := db.ForEach(modules.Receipts, modules.EncodeBlockNumber(number), func(k, _ []byte) error { 831 return db.Delete(modules.Receipts, k) 832 }); err != nil { 833 return err 834 } 835 836 from := make([]byte, 8) 837 binary.BigEndian.PutUint64(from, number) 838 if err := db.ForEach(modules.Log, from, func(k, _ []byte) error { 839 return db.Delete(modules.Log, k) 840 }); err != nil { 841 return err 842 } 843 return nil 844 } 845 846 func ReceiptsAvailableFrom(tx kv.Tx) (uint64, error) { 847 c, err := tx.Cursor(modules.Receipts) 848 if err != nil { 849 return math.MaxUint64, err 850 } 851 defer c.Close() 852 k, _, err := c.First() 853 if err != nil { 854 return math.MaxUint64, err 855 } 856 if len(k) == 0 { 857 return math.MaxUint64, nil 858 } 859 return binary.BigEndian.Uint64(k), nil 860 } 861 862 // ReadBlock retrieves an entire block corresponding to the hash, assembling it 863 // back from the stored header and body. If either the header or body could not 864 // be retrieved nil is returned. 865 // 866 // Note, due to concurrent download of header and block body the header and thus 867 // canonical hash can be stored in the database but the body data not (yet). 868 func ReadBlock(tx kv.Getter, hash types.Hash, number uint64) *block.Block { 869 header := ReadHeader(tx, hash, number) 870 if header == nil { 871 return nil 872 } 873 body := ReadCanonicalBodyWithTransactions(tx, hash, number) 874 if body == nil { 875 return nil 876 } 877 return block.NewBlockFromStorage(hash, header, body) 878 } 879 880 // HasBlock - is more efficient than ReadBlock because doesn't read transactions. 881 // It's is not equivalent of HasHeader because headers and bodies written by different stages 882 func HasBlock(db kv.Getter, hash types.Hash, number uint64) bool { 883 body := ReadStorageBodyRAW(db, hash, number) 884 return len(body) > 0 885 } 886 887 func ReadBlockWithSenders(db kv.Getter, hash types.Hash, number uint64) (*block.Block, []types.Address, error) { 888 block := ReadBlock(db, hash, number) 889 if block == nil { 890 return nil, nil, nil 891 } 892 senders, err := ReadSenders(db, hash, number) 893 if err != nil { 894 return nil, nil, err 895 } 896 if len(senders) != len(block.Transactions()) { 897 return block, senders, nil // no senders is fine - will recover them on the fly 898 } 899 block.SendersToTxs(senders) 900 return block, senders, nil 901 } 902 903 // WriteBlock serializes a block into the database, header and body separately. 904 func WriteBlock(db kv.RwTx, b *block.Block) error { 905 iBody := b.Body() 906 if err := WriteBody(db, b.Hash(), b.Number64().Uint64(), iBody.(*block.Body)); err != nil { 907 return err 908 } 909 iHeader := b.Header() 910 header, ok := iHeader.(*block.Header) 911 if !ok { 912 return fmt.Errorf("illegal: assert header") 913 } 914 WriteHeader(db, header) 915 return nil 916 } 917 918 // DeleteAncientBlocks - delete [1, to) old blocks after moving it to snapshots. 919 // keeps genesis in db: [1, to) 920 // doesn't change sequences of kv.EthTx and kv.NonCanonicalTxs 921 // doesn't delete Receipts, Senders, Canonical markers, TotalDifficulty 922 // returns [deletedFrom, deletedTo) 923 //func DeleteAncientBlocks(tx kv.RwTx, blockTo uint64, blocksDeleteLimit int) (deletedFrom, deletedTo uint64, err error) { 924 // c, err := tx.Cursor(Headers) 925 // if err != nil { 926 // return 927 // } 928 // defer c.Close() 929 // 930 // // find first non-genesis block 931 // firstK, _, err := c.Seek(dbutils.EncodeBlockNumber(1)) 932 // if err != nil { 933 // return 934 // } 935 // if firstK == nil { //nothing to delete 936 // return 937 // } 938 // blockFrom := binary.BigEndian.Uint64(firstK) 939 // stopAtBlock := libcommon.Min(blockTo, blockFrom+uint64(blocksDeleteLimit)) 940 // k, _, _ := c.Current() 941 // deletedFrom = binary.BigEndian.Uint64(k) 942 // 943 // var canonicalHash types.Hash 944 // var b *types.BodyForStorage 945 // 946 // for k, _, err = c.Current(); k != nil; k, _, err = c.Next() { 947 // if err != nil { 948 // return 949 // } 950 // 951 // n := binary.BigEndian.Uint64(k) 952 // if n >= stopAtBlock { // [from, to) 953 // break 954 // } 955 // 956 // canonicalHash, err = ReadCanonicalHash(tx, n) 957 // if err != nil { 958 // return 959 // } 960 // isCanonical := bytes.Equal(k[8:], canonicalHash[:]) 961 // 962 // b, err = ReadBodyForStorageByKey(tx, k) 963 // if err != nil { 964 // return 965 // } 966 // if b == nil { 967 // log.Debug("DeleteAncientBlocks: block body not found", "height", n) 968 // } else { 969 // txIDBytes := make([]byte, 8) 970 // for txID := b.BaseTxId; txID < b.BaseTxId+uint64(b.TxAmount); txID++ { 971 // binary.BigEndian.PutUint64(txIDBytes, txID) 972 // bucket := kv.EthTx 973 // if !isCanonical { 974 // bucket = kv.NonCanonicalTxs 975 // } 976 // if err = tx.Delete(bucket, txIDBytes); err != nil { 977 // return 978 // } 979 // } 980 // } 981 // // Copying k because otherwise the same memory will be reused 982 // // for the next key and Delete below will end up deleting 1 more record than required 983 // kCopy := common.CopyBytes(k) 984 // if err = tx.Delete(kv.Headers, kCopy); err != nil { 985 // return 986 // } 987 // if err = tx.Delete(kv.BlockBody, kCopy); err != nil { 988 // return 989 // } 990 // } 991 // 992 // k, _, _ = c.Current() 993 // deletedTo = binary.BigEndian.Uint64(k) 994 // 995 // return 996 //} 997 998 // LastKey - candidate on move to kv.Tx interface 999 func LastKey(tx kv.Tx, table string) ([]byte, error) { 1000 c, err := tx.Cursor(table) 1001 if err != nil { 1002 return nil, err 1003 } 1004 defer c.Close() 1005 k, _, err := c.Last() 1006 if err != nil { 1007 return nil, err 1008 } 1009 return k, nil 1010 } 1011 1012 // FirstKey - candidate on move to kv.Tx interface 1013 func FirstKey(tx kv.Tx, table string) ([]byte, error) { 1014 c, err := tx.Cursor(table) 1015 if err != nil { 1016 return nil, err 1017 } 1018 defer c.Close() 1019 k, _, err := c.First() 1020 if err != nil { 1021 return nil, err 1022 } 1023 return k, nil 1024 } 1025 1026 // SecondKey - useful if table always has zero-key (for example genesis block) 1027 func SecondKey(tx kv.Tx, table string) ([]byte, error) { 1028 c, err := tx.Cursor(table) 1029 if err != nil { 1030 return nil, err 1031 } 1032 defer c.Close() 1033 _, _, err = c.First() 1034 if err != nil { 1035 return nil, err 1036 } 1037 k, _, err := c.Next() 1038 if err != nil { 1039 return nil, err 1040 } 1041 return k, nil 1042 } 1043 1044 // TruncateBlocks - delete block >= blockFrom 1045 // does decrement sequences of kv.EthTx and kv.NonCanonicalTxs 1046 // doesn't delete Receipts, Senders, Canonical markers, TotalDifficulty 1047 func TruncateBlocks(ctx context.Context, tx kv.RwTx, blockFrom uint64) error { 1048 logEvery := time.NewTicker(20 * time.Second) 1049 defer logEvery.Stop() 1050 1051 c, err := tx.Cursor(modules.Headers) 1052 if err != nil { 1053 return err 1054 } 1055 defer c.Close() 1056 if blockFrom < 1 { //protect genesis 1057 blockFrom = 1 1058 } 1059 sequenceTo := map[string]uint64{} 1060 for k, _, err := c.Last(); k != nil; k, _, err = c.Prev() { 1061 if err != nil { 1062 return err 1063 } 1064 n := binary.BigEndian.Uint64(k) 1065 if n < blockFrom { // [from, to) 1066 break 1067 } 1068 //canonicalHash, err := ReadCanonicalHash(tx, n) 1069 //if err != nil { 1070 // return err 1071 //} 1072 //isCanonical := bytes.Equal(k[8:], canonicalHash[:]) 1073 1074 b, err := ReadBodyForStorageByKey(tx, k) 1075 if err != nil { 1076 return err 1077 } 1078 if b != nil { 1079 bucket := modules.BlockTx 1080 if err := tx.ForEach(bucket, modules.EncodeBlockNumber(b.BaseTxId), func(k, _ []byte) error { 1081 if err := tx.Delete(bucket, k); err != nil { 1082 return err 1083 } 1084 return nil 1085 }); err != nil { 1086 return err 1087 } 1088 sequenceTo[bucket] = b.BaseTxId 1089 } 1090 // Copying k because otherwise the same memory will be reused 1091 // for the next key and Delete below will end up deleting 1 more record than required 1092 kCopy := types.CopyBytes(k) 1093 if err := tx.Delete(modules.Headers, kCopy); err != nil { 1094 return err 1095 } 1096 if err := tx.Delete(modules.BlockBody, kCopy); err != nil { 1097 return err 1098 } 1099 1100 select { 1101 case <-ctx.Done(): 1102 return ctx.Err() 1103 case <-logEvery.C: 1104 log.Info("TruncateBlocks", "block", n) 1105 default: 1106 } 1107 } 1108 return nil 1109 } 1110 1111 func ReadBlockByNumber(db kv.Getter, number uint64) (*block.Block, error) { 1112 hash, err := ReadCanonicalHash(db, number) 1113 if err != nil { 1114 return nil, fmt.Errorf("failed ReadCanonicalHash: %w", err) 1115 } 1116 if hash == (types.Hash{}) { 1117 return nil, nil 1118 } 1119 1120 return ReadBlock(db, hash, number), nil 1121 } 1122 1123 func CanonicalBlockByNumberWithSenders(db kv.Tx, number uint64) (*block.Block, []types.Address, error) { 1124 hash, err := ReadCanonicalHash(db, number) 1125 if err != nil { 1126 return nil, nil, fmt.Errorf("failed ReadCanonicalHash: %w", err) 1127 } 1128 if hash == (types.Hash{}) { 1129 return nil, nil, nil 1130 } 1131 1132 return ReadBlockWithSenders(db, hash, number) 1133 } 1134 1135 func ReadBlockByHash(db kv.Tx, hash types.Hash) (*block.Block, error) { 1136 number := ReadHeaderNumber(db, hash) 1137 if number == nil { 1138 return nil, nil 1139 } 1140 return ReadBlock(db, hash, *number), nil 1141 } 1142 1143 func ReadHeaderByNumber(db kv.Getter, number uint64) *block.Header { 1144 hash, err := ReadCanonicalHash(db, number) 1145 if err != nil { 1146 log.Error("ReadCanonicalHash failed", "err", err) 1147 return nil 1148 } 1149 if hash == (types.Hash{}) { 1150 return nil 1151 } 1152 1153 return ReadHeader(db, hash, number) 1154 } 1155 1156 func ReadHeaderByHash(db kv.Getter, hash types.Hash) (*block.Header, error) { 1157 number := ReadHeaderNumber(db, hash) 1158 if number == nil { 1159 return nil, nil 1160 } 1161 return ReadHeader(db, hash, *number), nil 1162 } 1163 1164 //func ReadAncestor(db kv.Getter, hash types.Hash, number, ancestor uint64, maxNonCanonical *uint64, blockReader services.HeaderAndCanonicalReader) (types.Hash, uint64) { 1165 // if ancestor > number { 1166 // return types.Hash{}, 0 1167 // } 1168 // if ancestor == 1 { 1169 // header, err := blockReader.Header(context.Background(), db, hash, number) 1170 // if err != nil { 1171 // panic(err) 1172 // } 1173 // // in this case it is cheaper to just read the header 1174 // if header != nil { 1175 // return header.ParentHash, number - 1 1176 // } 1177 // return types.Hash{}, 0 1178 // } 1179 // for ancestor != 0 { 1180 // h, err := blockReader.CanonicalHash(context.Background(), db, number) 1181 // if err != nil { 1182 // panic(err) 1183 // } 1184 // if h == hash { 1185 // ancestorHash, err := blockReader.CanonicalHash(context.Background(), db, number-ancestor) 1186 // if err != nil { 1187 // panic(err) 1188 // } 1189 // h, err := blockReader.CanonicalHash(context.Background(), db, number) 1190 // if err != nil { 1191 // panic(err) 1192 // } 1193 // if h == hash { 1194 // number -= ancestor 1195 // return ancestorHash, number 1196 // } 1197 // } 1198 // if *maxNonCanonical == 0 { 1199 // return types.Hash{}, 0 1200 // } 1201 // *maxNonCanonical-- 1202 // ancestor-- 1203 // header, err := blockReader.Header(context.Background(), db, hash, number) 1204 // if err != nil { 1205 // panic(err) 1206 // } 1207 // if header == nil { 1208 // return types.Hash{}, 0 1209 // } 1210 // hash = header.ParentHash 1211 // number-- 1212 // } 1213 // return hash, number 1214 //} 1215 1216 // PruneTable has `limit` parameter to avoid too large data deletes per one sync cycle - better delete by small portions to reduce db.FreeList size 1217 func PruneTable(tx kv.RwTx, table string, pruneTo uint64, ctx context.Context, limit int) error { 1218 c, err := tx.RwCursor(table) 1219 1220 if err != nil { 1221 return fmt.Errorf("failed to create cursor for pruning %w", err) 1222 } 1223 defer c.Close() 1224 1225 i := 0 1226 for k, _, err := c.First(); k != nil; k, _, err = c.Next() { 1227 if err != nil { 1228 return err 1229 } 1230 i++ 1231 if i > limit { 1232 break 1233 } 1234 1235 blockNum := binary.BigEndian.Uint64(k) 1236 if blockNum >= pruneTo { 1237 break 1238 } 1239 select { 1240 case <-ctx.Done(): 1241 return common2.ErrStopped 1242 default: 1243 } 1244 if err = c.DeleteCurrent(); err != nil { 1245 return fmt.Errorf("failed to remove for block %d: %w", blockNum, err) 1246 } 1247 } 1248 return nil 1249 } 1250 1251 func PruneTableDupSort(tx kv.RwTx, table string, logPrefix string, pruneTo uint64, logEvery *time.Ticker, ctx context.Context) error { 1252 c, err := tx.RwCursorDupSort(table) 1253 if err != nil { 1254 return fmt.Errorf("failed to create cursor for pruning %w", err) 1255 } 1256 defer c.Close() 1257 1258 for k, _, err := c.First(); k != nil; k, _, err = c.NextNoDup() { 1259 if err != nil { 1260 return fmt.Errorf("failed to move %s cleanup cursor: %w", table, err) 1261 } 1262 blockNum := binary.BigEndian.Uint64(k) 1263 if blockNum >= pruneTo { 1264 break 1265 } 1266 select { 1267 case <-logEvery.C: 1268 log.Info(fmt.Sprintf("[%s]", logPrefix), "table", table, "block", blockNum) 1269 case <-ctx.Done(): 1270 return common2.ErrStopped 1271 default: 1272 } 1273 if err = c.DeleteCurrentDuplicates(); err != nil { 1274 return fmt.Errorf("failed to remove for block %d: %w", blockNum, err) 1275 } 1276 } 1277 return nil 1278 } 1279 1280 func ReadCurrentBlockNumber(db kv.Getter) *uint64 { 1281 headHash := ReadHeadHeaderHash(db) 1282 return ReadHeaderNumber(db, headHash) 1283 } 1284 1285 func ReadCurrentHeader(db kv.Getter) *block.Header { 1286 headHash := ReadHeadHeaderHash(db) 1287 headNumber := ReadHeaderNumber(db, headHash) 1288 if headNumber == nil { 1289 return nil 1290 } 1291 return ReadHeader(db, headHash, *headNumber) 1292 } 1293 1294 func ReadCurrentBlock(db kv.Tx) *block.Block { 1295 headHash := ReadHeadBlockHash(db) 1296 headNumber := ReadHeaderNumber(db, headHash) 1297 if headNumber == nil { 1298 return nil 1299 } 1300 return ReadBlock(db, headHash, *headNumber) 1301 } 1302 1303 // ReadHeadHeaderHash retrieves the hash of the current canonical head header. 1304 func ReadHeadHeaderHash(db kv.Getter) types.Hash { 1305 data, err := db.GetOne(modules.HeadHeaderKey, []byte(modules.HeadHeaderKey)) 1306 if err != nil { 1307 log.Error("ReadHeadHeaderHash failed", "err", err) 1308 } 1309 if len(data) == 0 { 1310 return types.Hash{} 1311 } 1312 return types.BytesToHash(data) 1313 } 1314 1315 // ReadHeadBlockHash retrieves the hash of the current canonical head block. 1316 func ReadHeadBlockHash(db kv.Getter) types.Hash { 1317 data, err := db.GetOne(modules.HeadBlockKey, []byte(modules.HeadBlockKey)) 1318 if err != nil { 1319 log.Error("ReadHeadBlockHash failed", "err", err) 1320 } 1321 if len(data) == 0 { 1322 return types.Hash{} 1323 } 1324 return types.BytesToHash(data) 1325 } 1326 1327 // WriteHeadBlockHash stores the head block's hash. 1328 func WriteHeadBlockHash(db kv.Putter, hash types.Hash) { 1329 if err := db.Put(modules.HeadBlockKey, []byte(modules.HeadBlockKey), hash.Bytes()); err != nil { 1330 log.Crit("Failed to store last block's hash", "err", err) 1331 } 1332 } 1333 1334 // WriteHeadHeaderHash stores the hash of the current canonical head header. 1335 func WriteHeadHeaderHash(db kv.Putter, hash types.Hash) error { 1336 if err := db.Put(modules.HeadHeaderKey, []byte(modules.HeadHeaderKey), hash.Bytes()); err != nil { 1337 return fmt.Errorf("failed to store last header's hash: %w", err) 1338 } 1339 return nil 1340 } 1341 1342 func GetPoaSnapshot(db kv.Getter, hash types.Hash) ([]byte, error) { 1343 1344 return db.GetOne(modules.PoaSnapshot, hash.Bytes()) 1345 } 1346 1347 func StorePoaSnapshot(db kv.Putter, hash types.Hash, data []byte) error { 1348 1349 return db.Put(modules.PoaSnapshot, hash.Bytes(), data) 1350 }