Skip to content

Commit

Permalink
core/types: replace core.SetReceiptsData with receipts.DeriveFields
Browse files Browse the repository at this point in the history
  • Loading branch information
gzliudan committed Sep 9, 2024
1 parent 32c390a commit 3bf89c9
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 53 deletions.
56 changes: 7 additions & 49 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1027,49 +1027,6 @@ func (bc *BlockChain) Rollback(chain []common.Hash) {
}
}

// SetReceiptsData computes all the non-consensus fields of the receipts
func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts types.Receipts) error {
signer := types.MakeSigner(config, block.Number())

transactions, logIndex := block.Transactions(), uint(0)
if len(transactions) != len(receipts) {
return errors.New("transaction and receipt count mismatch")
}

for j := 0; j < len(receipts); j++ {
// The transaction hash can be retrieved from the transaction itself
receipts[j].TxHash = transactions[j].Hash()

// block location fields
receipts[j].BlockHash = block.Hash()
receipts[j].BlockNumber = block.Number()
receipts[j].TransactionIndex = uint(j)

// The contract address can be derived from the transaction itself
if transactions[j].To() == nil {
// Deriving the signer is expensive, only do if it's actually needed
from, _ := types.Sender(signer, transactions[j])
receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce())
}
// The used gas can be calculated based on previous receipts
if j == 0 {
receipts[j].GasUsed = receipts[j].CumulativeGasUsed
} else {
receipts[j].GasUsed = receipts[j].CumulativeGasUsed - receipts[j-1].CumulativeGasUsed
}
// The derived log fields can simply be set from the block and transaction
for k := 0; k < len(receipts[j].Logs); k++ {
receipts[j].Logs[k].BlockNumber = block.NumberU64()
receipts[j].Logs[k].BlockHash = block.Hash()
receipts[j].Logs[k].TxHash = receipts[j].TxHash
receipts[j].Logs[k].TxIndex = uint(j)
receipts[j].Logs[k].Index = logIndex
logIndex++
}
}
return nil
}

// InsertReceiptChain attempts to complete an already existing header chain with
// transaction and receipt data.
func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
Expand Down Expand Up @@ -1098,22 +1055,23 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
if atomic.LoadInt32(&bc.procInterrupt) == 1 {
return 0, nil
}
blockHash, blockNumber := block.Hash(), block.NumberU64()
// Short circuit if the owner header is unknown
if !bc.HasHeader(block.Hash(), block.NumberU64()) {
return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4])
if !bc.HasHeader(blockHash, blockNumber) {
return i, fmt.Errorf("containing header #%d [%x…] unknown", blockNumber, blockHash.Bytes()[:4])
}
// Skip if the entire data is already known
if bc.HasBlock(block.Hash(), block.NumberU64()) {
if bc.HasBlock(blockHash, blockNumber) {
stats.ignored++
continue
}
// Compute all the non-consensus fields of the receipts
if err := SetReceiptsData(bc.chainConfig, block, receipts); err != nil {
if err := receipts.DeriveFields(bc.chainConfig, blockHash, blockNumber, block.Transactions()); err != nil {
return i, fmt.Errorf("failed to set receipts data: %v", err)
}
// Write all the data out into the database
rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
if err := WriteBlockReceipts(batch, block.Hash(), block.NumberU64(), receipts); err != nil {
rawdb.WriteBody(batch, blockHash, blockNumber, block.Body())
if err := WriteBlockReceipts(batch, blockHash, blockNumber, receipts); err != nil {
return i, fmt.Errorf("failed to write block receipts: %v", err)
}
if err := WriteTxLookupEntries(batch, block); err != nil {
Expand Down
19 changes: 17 additions & 2 deletions light/odr_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package light
import (
"bytes"
"context"
"errors"

"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/core"
Expand All @@ -29,6 +30,13 @@ import (

var sha3_nil = crypto.Keccak256Hash(nil)

// errNonCanonicalHash is returned if the requested chain data doesn't belong
// to the canonical chain. ODR can only retrieve the canonical chain data covered
// by the CHT or Bloom trie for verification.
var errNonCanonicalHash = errors.New("hash is not currently canonical")

// GetHeaderByNumber retrieves the canonical block header corresponding to the
// given number. The returned header is proven by local CHT.
func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*types.Header, error) {
db := odr.Database()
hash := core.GetCanonicalHash(db, number)
Expand Down Expand Up @@ -113,7 +121,7 @@ func GetBlock(ctx context.Context, odr OdrBackend, hash common.Hash, number uint
// Retrieve the block header and body contents
header := core.GetHeader(odr.Database(), hash, number)
if header == nil {
return nil, ErrNoHeader
return nil, errNoHeader
}
body, err := GetBody(ctx, odr, hash, number)
if err != nil {
Expand All @@ -129,6 +137,13 @@ func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, num
// Retrieve the potentially incomplete receipts from disk or network
receipts := core.GetBlockReceipts(odr.Database(), hash, number)
if receipts == nil {
header, err := GetHeaderByNumber(ctx, odr, number)
if err != nil {
return nil, errNoHeader
}
if header.Hash() != hash {
return nil, errNonCanonicalHash
}
r := &ReceiptsRequest{Hash: hash, Number: number}
if err := odr.Retrieve(ctx, r); err != nil {
return nil, err
Expand All @@ -144,7 +159,7 @@ func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, num
genesis := core.GetCanonicalHash(odr.Database(), 0)
config, _ := core.GetChainConfig(odr.Database(), genesis)

if err := core.SetReceiptsData(config, block, receipts); err != nil {
if err := receipts.DeriveFields(config, hash, number, block.Transactions()); err != nil {
return nil, err
}
core.WriteBlockReceipts(odr.Database(), hash, number, receipts)
Expand Down
4 changes: 2 additions & 2 deletions light/postprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ package light
import (
"encoding/binary"
"errors"
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big"
"time"

"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/common/bitutil"
"github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/ethdb"
"github.com/XinFinOrg/XDPoSChain/log"
Expand Down Expand Up @@ -83,7 +83,7 @@ var trustedCheckpoints = map[common.Hash]trustedCheckpoint{
var (
ErrNoTrustedCht = errors.New("No trusted canonical hash trie")
ErrNoTrustedBloomTrie = errors.New("No trusted bloom trie")
ErrNoHeader = errors.New("Header not found")
errNoHeader = errors.New("header not found")
chtPrefix = []byte("chtRoot-") // chtPrefix + chtNum (uint64 big endian) -> trie root hash
ChtTablePrefix = "cht-"
)
Expand Down

0 comments on commit 3bf89c9

Please sign in to comment.