mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-24 07:34:31 +00:00
core/types: replace core.SetReceiptsData with receipts.DeriveFields
This commit is contained in:
parent
e561f2842e
commit
6c77d63dc2
3 changed files with 25 additions and 52 deletions
|
|
@ -1029,49 +1029,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) {
|
||||
|
|
@ -1100,22 +1057,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 {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package light
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/core"
|
||||
|
|
@ -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)
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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-"
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue