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  }