From 159713d46bb0e291d3d8b6a1728c263cb580b748 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Wed, 25 Jan 2023 17:39:28 +0530 Subject: [PATCH 1/6] ReadBorReceipts improvements --- core/blockchain.go | 2 +- core/bor_blockchain.go | 2 +- core/rawdb/bor_receipt.go | 24 ++++++++++++------------ eth/filters/test_backend.go | 2 +- eth/tracers/api.go | 2 +- internal/ethapi/api.go | 16 ++++++++-------- params/config.go | 4 ++++ 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 74fd4bfeda..cbcf02fef4 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2059,7 +2059,7 @@ func (bc *BlockChain) collectLogs(hash common.Hash, removed bool) []*types.Log { receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig) // Append bor receipt - borReceipt := rawdb.ReadBorReceipt(bc.db, hash, *number) + borReceipt := rawdb.ReadBorReceipt(bc.db, hash, *number, bc.chainConfig) if borReceipt != nil { receipts = append(receipts, borReceipt) } diff --git a/core/bor_blockchain.go b/core/bor_blockchain.go index ae2cdf3c6f..49973421bd 100644 --- a/core/bor_blockchain.go +++ b/core/bor_blockchain.go @@ -19,7 +19,7 @@ func (bc *BlockChain) GetBorReceiptByHash(hash common.Hash) *types.Receipt { } // 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 { return nil } diff --git a/core/rawdb/bor_receipt.go b/core/rawdb/bor_receipt.go index e225083741..535b48ee48 100644 --- a/core/rawdb/bor_receipt.go +++ b/core/rawdb/bor_receipt.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" ) @@ -52,15 +53,9 @@ func ReadBorReceiptRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.Raw // First try to look up the data in ancient database. Extra hash // comparison is necessary since ancient database only maintains // the canonical data. - data, _ := db.Ancient(freezerBorReceiptTable, number) - if len(data) > 0 { - h, _ := db.Ancient(freezerHashTable, number) - if common.BytesToHash(h) == hash { - return data - } - } - // Then try to look up the data in leveldb. - data, _ = db.Get(borReceiptKey(number, hash)) + + // Look up the data in leveldb. + data, _ := db.Get(borReceiptKey(number, hash)) if len(data) > 0 { return data } @@ -101,7 +96,12 @@ func ReadRawBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types. // ReadBorReceipt retrieves all the bor block receipts belonging to a block, including // its correspoinding metadata fields. If it is unable to populate these metadata // 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.IsSprintStart(number, config.Bor.CalculateSprint(number)) { + return nil + } + // We're deriving many fields from the block body, retrieve beside the receipt borReceipt := ReadRawBorReceipt(db, hash, number) if borReceipt == nil { @@ -114,8 +114,8 @@ func ReadBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types.Rec return nil } - body := ReadBody(db, hash, number) - if body == nil { + body := HasBody(db, hash, number) + if !body { log.Error("Missing body but have bor receipt", "hash", hash, "number", number) return nil } diff --git a/eth/filters/test_backend.go b/eth/filters/test_backend.go index 979ed3efb6..8b2ef4a7f2 100644 --- a/eth/filters/test_backend.go +++ b/eth/filters/test_backend.go @@ -38,7 +38,7 @@ func (b *TestBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) return &types.Receipt{}, nil } - receipt := rawdb.ReadBorReceipt(b.DB, hash, *number) + receipt := rawdb.ReadBorReceipt(b.DB, hash, *number, nil) if receipt == nil { return &types.Receipt{}, nil } diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 3fce91ac9c..13f5c627cd 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -177,7 +177,7 @@ func (api *API) getAllBlockTransactions(ctx context.Context, block *types.Block) 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 { txHash := types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash())) if txHash != (common.Hash{}) { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 2fd148c7c6..231769999b 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -636,7 +636,7 @@ func (s *PublicBlockChainAPI) GetTransactionReceiptsByBlock(ctx context.Context, 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 { receipts = append(receipts, borReceipt) txHash = types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash())) @@ -1448,7 +1448,11 @@ func newRPCPendingTransaction(tx *types.Transaction, current *types.Header, conf func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *params.ChainConfig, db ethdb.Database) *RPCTransaction { txs := b.Transactions() - borReceipt := rawdb.ReadBorReceipt(db, b.Hash(), b.NumberU64()) + if index >= uint64(len(txs)+1) { + return nil + } + + borReceipt := rawdb.ReadBorReceipt(db, b.Hash(), b.NumberU64(), config) if borReceipt != nil { tx, _, _, _ := rawdb.ReadBorTransaction(db, borReceipt.TxHash) @@ -1456,10 +1460,6 @@ func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *param txs = append(txs, tx) } } - - if index >= uint64(len(txs)) { - return nil - } return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index, b.BaseFee(), config) } @@ -1597,7 +1597,7 @@ func (api *PublicTransactionPoolAPI) getAllBlockTransactions(ctx context.Context 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 { txHash := types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash())) if txHash != (common.Hash{}) { @@ -1767,7 +1767,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha if borTx { // Fetch bor block receipt - receipt = rawdb.ReadBorReceipt(s.b.ChainDb(), blockHash, blockNumber) + receipt = rawdb.ReadBorReceipt(s.b.ChainDb(), blockHash, blockNumber, s.b.ChainConfig()) } else { receipts, err := s.b.GetReceipts(ctx, blockHash) if err != nil { diff --git a/params/config.go b/params/config.go index 94729224bb..f410f772fd 100644 --- a/params/config.go +++ b/params/config.go @@ -617,6 +617,10 @@ func (c *BorConfig) IsDelhi(number *big.Int) bool { return isForked(c.DelhiBlock, number) } +func (c *BorConfig) IsSprintStart(number, sprint uint64) bool { + return number%sprint == 0 +} + func (c *BorConfig) calculateBorConfigHelper(field map[string]uint64, number uint64) uint64 { keys := make([]string, 0, len(field)) for k := range field { From f2acf201f743de2875f40ae53782a1cfb8d0cd73 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Wed, 25 Jan 2023 17:48:13 +0530 Subject: [PATCH 2/6] use internal function --- core/rawdb/bor_receipt.go | 3 +-- params/config.go | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/rawdb/bor_receipt.go b/core/rawdb/bor_receipt.go index 535b48ee48..f599eeee96 100644 --- a/core/rawdb/bor_receipt.go +++ b/core/rawdb/bor_receipt.go @@ -97,8 +97,7 @@ func ReadRawBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types. // its correspoinding metadata fields. If it is unable to populate these metadata // fields then nil is returned. func ReadBorReceipt(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) *types.Receipt { - - if config != nil && !config.Bor.IsSprintStart(number, config.Bor.CalculateSprint(number)) { + if config != nil && !config.Bor.IsSprintStart(number) { return nil } diff --git a/params/config.go b/params/config.go index f410f772fd..9833c9eac5 100644 --- a/params/config.go +++ b/params/config.go @@ -617,8 +617,8 @@ func (c *BorConfig) IsDelhi(number *big.Int) bool { return isForked(c.DelhiBlock, number) } -func (c *BorConfig) IsSprintStart(number, sprint uint64) bool { - return number%sprint == 0 +func (c *BorConfig) IsSprintStart(number uint64) bool { + return number%c.CalculateSprint(number) == 0 } func (c *BorConfig) calculateBorConfigHelper(field map[string]uint64, number uint64) uint64 { From 3fa48ea401fa3c6284c32da7c6b48ab92ee1fd83 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Wed, 25 Jan 2023 18:59:51 +0530 Subject: [PATCH 3/6] fix tests --- core/rawdb/bor_receipt.go | 3 ++- internal/ethapi/api.go | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/core/rawdb/bor_receipt.go b/core/rawdb/bor_receipt.go index f599eeee96..5f908c936f 100644 --- a/core/rawdb/bor_receipt.go +++ b/core/rawdb/bor_receipt.go @@ -97,7 +97,8 @@ func ReadRawBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types. // its correspoinding metadata fields. If it is unable to populate these metadata // fields then nil is returned. func ReadBorReceipt(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) *types.Receipt { - if config != nil && !config.Bor.IsSprintStart(number) { + + if config != nil && config.Bor != nil && config.Bor.Sprint != nil && !config.Bor.IsSprintStart(number) { return nil } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 231769999b..72eeae2b09 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1460,6 +1460,10 @@ func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *param txs = append(txs, tx) } } + + if index >= uint64(len(txs)) { + return nil + } return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index, b.BaseFee(), config) } From 12553715330d9d1f88bc6287deb5bd144a4139d7 Mon Sep 17 00:00:00 2001 From: Jerry Date: Wed, 25 Jan 2023 11:40:41 -0800 Subject: [PATCH 4/6] 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. --- internal/ethapi/api.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 72eeae2b09..1db2a60a68 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1452,15 +1452,19 @@ func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *param return nil } - 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 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 + 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)) { return nil } From 4602774c9a481ee5bf54d526a67377a6eaf04b76 Mon Sep 17 00:00:00 2001 From: Jerry Date: Wed, 25 Jan 2023 15:01:19 -0800 Subject: [PATCH 5/6] Fix linter --- core/rawdb/bor_receipt.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/rawdb/bor_receipt.go b/core/rawdb/bor_receipt.go index 5f908c936f..a80f99e3c2 100644 --- a/core/rawdb/bor_receipt.go +++ b/core/rawdb/bor_receipt.go @@ -97,7 +97,6 @@ func ReadRawBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types. // its correspoinding metadata fields. If it is unable to populate these metadata // fields then nil is returned. 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 } From bc8772e82831140c9697f0f134dd64c024cdd541 Mon Sep 17 00:00:00 2001 From: Jerry Date: Wed, 25 Jan 2023 15:04:36 -0800 Subject: [PATCH 6/6] Restore ReadBorReceiptRLP --- core/rawdb/bor_receipt.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/rawdb/bor_receipt.go b/core/rawdb/bor_receipt.go index a80f99e3c2..6adc9ee976 100644 --- a/core/rawdb/bor_receipt.go +++ b/core/rawdb/bor_receipt.go @@ -53,9 +53,16 @@ func ReadBorReceiptRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.Raw // First try to look up the data in ancient database. Extra hash // comparison is necessary since ancient database only maintains // the canonical data. + data, _ := db.Ancient(freezerBorReceiptTable, number) + if len(data) > 0 { + h, _ := db.Ancient(freezerHashTable, number) + if common.BytesToHash(h) == hash { + return data + } + } // Look up the data in leveldb. - data, _ := db.Get(borReceiptKey(number, hash)) + data, _ = db.Get(borReceiptKey(number, hash)) if len(data) > 0 { return data }