Arpit/temp bor sync (#701)

* Increase grpc message size limit in pprof

* ReadBorReceipts improvements

* use internal function

* fix tests

* fetch geth upstread for ReadBorReceiptRLP

* Only query bor receipt when the query index is equal to # tx in block body

This change reduces the frequency of calling ReadBorReceipt and
ReadBorTransaction, which are CPU and db intensive.

* Revert "fetch geth upstread for ReadBorReceiptRLP"

This reverts commit 2e838a6b1313d26674f3a8df4b044e35dcbf35a0.

* Restore ReadBorReceiptRLP

* fix bor receipts

* remove unused

* fix lints

---------

Co-authored-by: Jerry <jerrycgh@gmail.com>
Co-authored-by: Manav Darji <manavdarji.india@gmail.com>
Co-authored-by: Evgeny Danienko <6655321@bk.ru>
This commit is contained in:
Arpit Temani 2023-02-03 15:42:12 +05:30 committed by GitHub
parent a533ffb289
commit 2be6ae43a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 52 additions and 53 deletions

View file

@ -2059,7 +2059,7 @@ func (bc *BlockChain) collectLogs(hash common.Hash, removed bool) []*types.Log {
receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig) receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig)
// Append bor receipt // Append bor receipt
borReceipt := rawdb.ReadBorReceipt(bc.db, hash, *number) borReceipt := rawdb.ReadBorReceipt(bc.db, hash, *number, bc.chainConfig)
if borReceipt != nil { if borReceipt != nil {
receipts = append(receipts, borReceipt) receipts = append(receipts, borReceipt)
} }

View file

@ -19,7 +19,7 @@ func (bc *BlockChain) GetBorReceiptByHash(hash common.Hash) *types.Receipt {
} }
// read bor reciept by hash and number // read bor reciept by hash and number
receipt := rawdb.ReadBorReceipt(bc.db, hash, *number) receipt := rawdb.ReadBorReceipt(bc.db, hash, *number, bc.chainConfig)
if receipt == nil { if receipt == nil {
return nil return nil
} }

View file

@ -7,6 +7,7 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
@ -33,49 +34,28 @@ func borTxLookupKey(hash common.Hash) []byte {
return append(borTxLookupPrefix, hash.Bytes()...) return append(borTxLookupPrefix, hash.Bytes()...)
} }
// HasBorReceipt verifies the existence of all block receipt belonging
// to a block.
func HasBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) bool {
if has, err := db.Ancient(freezerHashTable, number); err == nil && common.BytesToHash(has) == hash {
return true
}
if has, err := db.Has(borReceiptKey(number, hash)); !has || err != nil {
return false
}
return true
}
// ReadBorReceiptRLP retrieves the block receipt belonging to a block in RLP encoding.
func ReadBorReceiptRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { func ReadBorReceiptRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
// First try to look up the data in ancient database. Extra hash var data []byte
// comparison is necessary since ancient database only maintains
// the canonical data. err := db.ReadAncients(func(reader ethdb.AncientReader) error {
data, _ := db.Ancient(freezerBorReceiptTable, number) // Check if the data is in ancients
if len(data) > 0 { if isCanon(reader, number, hash) {
h, _ := db.Ancient(freezerHashTable, number) data, _ = reader.Ancient(freezerBorReceiptTable, number)
if common.BytesToHash(h) == hash {
return data return nil
} }
// If not, try reading from leveldb
data, _ = db.Get(borReceiptKey(number, hash))
return nil
})
if err != nil {
log.Warn("during ReadBorReceiptRLP", "number", number, "hash", hash, "err", err)
} }
// Then try to look up the data in leveldb.
data, _ = db.Get(borReceiptKey(number, hash)) return data
if len(data) > 0 {
return data
}
// In the background freezer is moving data from leveldb to flatten files.
// So during the first check for ancient db, the data is not yet in there,
// but when we reach into leveldb, the data was already moved. That would
// result in a not found error.
data, _ = db.Ancient(freezerBorReceiptTable, number)
if len(data) > 0 {
h, _ := db.Ancient(freezerHashTable, number)
if common.BytesToHash(h) == hash {
return data
}
}
return nil // Can't find the data anywhere.
} }
// ReadRawBorReceipt retrieves the block receipt belonging to a block. // ReadRawBorReceipt retrieves the block receipt belonging to a block.
@ -101,7 +81,11 @@ func ReadRawBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types.
// ReadBorReceipt retrieves all the bor block receipts belonging to a block, including // ReadBorReceipt retrieves all the bor block receipts belonging to a block, including
// its correspoinding metadata fields. If it is unable to populate these metadata // its correspoinding metadata fields. If it is unable to populate these metadata
// fields then nil is returned. // fields then nil is returned.
func ReadBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types.Receipt { func ReadBorReceipt(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) *types.Receipt {
if config != nil && config.Bor != nil && config.Bor.Sprint != nil && !config.Bor.IsSprintStart(number) {
return nil
}
// We're deriving many fields from the block body, retrieve beside the receipt // We're deriving many fields from the block body, retrieve beside the receipt
borReceipt := ReadRawBorReceipt(db, hash, number) borReceipt := ReadRawBorReceipt(db, hash, number)
if borReceipt == nil { if borReceipt == nil {

View file

@ -38,7 +38,7 @@ func (b *TestBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash)
return &types.Receipt{}, nil return &types.Receipt{}, nil
} }
receipt := rawdb.ReadBorReceipt(b.DB, hash, *number) receipt := rawdb.ReadBorReceipt(b.DB, hash, *number, nil)
if receipt == nil { if receipt == nil {
return &types.Receipt{}, nil return &types.Receipt{}, nil
} }

View file

@ -177,7 +177,7 @@ func (api *API) getAllBlockTransactions(ctx context.Context, block *types.Block)
stateSyncPresent := false stateSyncPresent := false
borReceipt := rawdb.ReadBorReceipt(api.backend.ChainDb(), block.Hash(), block.NumberU64()) borReceipt := rawdb.ReadBorReceipt(api.backend.ChainDb(), block.Hash(), block.NumberU64(), api.backend.ChainConfig())
if borReceipt != nil { if borReceipt != nil {
txHash := types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash())) txHash := types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash()))
if txHash != (common.Hash{}) { if txHash != (common.Hash{}) {

View file

@ -636,7 +636,7 @@ func (s *PublicBlockChainAPI) GetTransactionReceiptsByBlock(ctx context.Context,
var txHash common.Hash var txHash common.Hash
borReceipt := rawdb.ReadBorReceipt(s.b.ChainDb(), block.Hash(), block.NumberU64()) borReceipt := rawdb.ReadBorReceipt(s.b.ChainDb(), block.Hash(), block.NumberU64(), s.b.ChainConfig())
if borReceipt != nil { if borReceipt != nil {
receipts = append(receipts, borReceipt) receipts = append(receipts, borReceipt)
txHash = types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash())) txHash = types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash()))
@ -1453,15 +1453,23 @@ func newRPCPendingTransaction(tx *types.Transaction, current *types.Header, conf
func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *params.ChainConfig, db ethdb.Database) *RPCTransaction { func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *params.ChainConfig, db ethdb.Database) *RPCTransaction {
txs := b.Transactions() txs := b.Transactions()
borReceipt := rawdb.ReadBorReceipt(db, b.Hash(), b.NumberU64()) if index >= uint64(len(txs)+1) {
if borReceipt != nil { return nil
tx, _, _, _ := rawdb.ReadBorTransaction(db, borReceipt.TxHash) }
if tx != nil { // If the index out of the range of transactions defined in block body, it means that the transaction is a bor state sync transaction, and we need to fetch it from the database
txs = append(txs, tx) if index == uint64(len(txs)) {
borReceipt := rawdb.ReadBorReceipt(db, b.Hash(), b.NumberU64(), config)
if borReceipt != nil {
tx, _, _, _ := rawdb.ReadBorTransaction(db, borReceipt.TxHash)
if tx != nil {
txs = append(txs, tx)
}
} }
} }
// If the index is still out of the range after checking bor state sync transaction, it means that the transaction index is invalid
if index >= uint64(len(txs)) { if index >= uint64(len(txs)) {
return nil return nil
} }
@ -1602,7 +1610,7 @@ func (api *PublicTransactionPoolAPI) getAllBlockTransactions(ctx context.Context
stateSyncPresent := false stateSyncPresent := false
borReceipt := rawdb.ReadBorReceipt(api.b.ChainDb(), block.Hash(), block.NumberU64()) borReceipt := rawdb.ReadBorReceipt(api.b.ChainDb(), block.Hash(), block.NumberU64(), api.b.ChainConfig())
if borReceipt != nil { if borReceipt != nil {
txHash := types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash())) txHash := types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash()))
if txHash != (common.Hash{}) { if txHash != (common.Hash{}) {
@ -1772,7 +1780,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha
if borTx { if borTx {
// Fetch bor block receipt // Fetch bor block receipt
receipt = rawdb.ReadBorReceipt(s.b.ChainDb(), blockHash, blockNumber) receipt = rawdb.ReadBorReceipt(s.b.ChainDb(), blockHash, blockNumber, s.b.ChainConfig())
} else { } else {
receipts, err := s.b.GetReceipts(ctx, blockHash) receipts, err := s.b.GetReceipts(ctx, blockHash)
if err != nil { if err != nil {

View file

@ -617,6 +617,10 @@ func (c *BorConfig) IsDelhi(number *big.Int) bool {
return isForked(c.DelhiBlock, number) return isForked(c.DelhiBlock, number)
} }
func (c *BorConfig) IsSprintStart(number uint64) bool {
return number%c.CalculateSprint(number) == 0
}
func (c *BorConfig) calculateBorConfigHelper(field map[string]uint64, number uint64) uint64 { func (c *BorConfig) calculateBorConfigHelper(field map[string]uint64, number uint64) uint64 {
keys := make([]string, 0, len(field)) keys := make([]string, 0, len(field))
for k := range field { for k := range field {

View file

@ -23,6 +23,7 @@ import (
"sync/atomic" "sync/atomic"
mapset "github.com/deckarep/golang-set" mapset "github.com/deckarep/golang-set"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
@ -127,9 +128,11 @@ func (s *Server) serveSingleRequest(ctx context.Context, codec ServerCodec) {
log.Debug("batch limit %d exceeded: %d requests given", s.BatchLimit, len(reqs)) log.Debug("batch limit %d exceeded: %d requests given", s.BatchLimit, len(reqs))
} }
} else { } else {
//nolint:contextcheck
h.handleBatch(reqs) h.handleBatch(reqs)
} }
} else { } else {
//nolint:contextcheck
h.handleMsg(reqs[0]) h.handleMsg(reqs[0])
} }
} }