mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +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
|
// InsertReceiptChain attempts to complete an already existing header chain with
|
||||||
// transaction and receipt data.
|
// transaction and receipt data.
|
||||||
func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
|
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 {
|
if atomic.LoadInt32(&bc.procInterrupt) == 1 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
blockHash, blockNumber := block.Hash(), block.NumberU64()
|
||||||
// Short circuit if the owner header is unknown
|
// Short circuit if the owner header is unknown
|
||||||
if !bc.HasHeader(block.Hash(), block.NumberU64()) {
|
if !bc.HasHeader(blockHash, blockNumber) {
|
||||||
return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4])
|
return i, fmt.Errorf("containing header #%d [%x…] unknown", blockNumber, blockHash.Bytes()[:4])
|
||||||
}
|
}
|
||||||
// Skip if the entire data is already known
|
// Skip if the entire data is already known
|
||||||
if bc.HasBlock(block.Hash(), block.NumberU64()) {
|
if bc.HasBlock(blockHash, blockNumber) {
|
||||||
stats.ignored++
|
stats.ignored++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Compute all the non-consensus fields of the receipts
|
// 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)
|
return i, fmt.Errorf("failed to set receipts data: %v", err)
|
||||||
}
|
}
|
||||||
// Write all the data out into the database
|
// Write all the data out into the database
|
||||||
rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
|
rawdb.WriteBody(batch, blockHash, blockNumber, block.Body())
|
||||||
if err := WriteBlockReceipts(batch, block.Hash(), block.NumberU64(), receipts); err != nil {
|
if err := WriteBlockReceipts(batch, blockHash, blockNumber, receipts); err != nil {
|
||||||
return i, fmt.Errorf("failed to write block receipts: %v", err)
|
return i, fmt.Errorf("failed to write block receipts: %v", err)
|
||||||
}
|
}
|
||||||
if err := WriteTxLookupEntries(batch, block); err != nil {
|
if err := WriteTxLookupEntries(batch, block); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package light
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core"
|
"github.com/XinFinOrg/XDPoSChain/core"
|
||||||
|
|
@ -29,6 +30,13 @@ import (
|
||||||
|
|
||||||
var sha3_nil = crypto.Keccak256Hash(nil)
|
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) {
|
func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*types.Header, error) {
|
||||||
db := odr.Database()
|
db := odr.Database()
|
||||||
hash := core.GetCanonicalHash(db, number)
|
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
|
// Retrieve the block header and body contents
|
||||||
header := core.GetHeader(odr.Database(), hash, number)
|
header := core.GetHeader(odr.Database(), hash, number)
|
||||||
if header == nil {
|
if header == nil {
|
||||||
return nil, ErrNoHeader
|
return nil, errNoHeader
|
||||||
}
|
}
|
||||||
body, err := GetBody(ctx, odr, hash, number)
|
body, err := GetBody(ctx, odr, hash, number)
|
||||||
if err != nil {
|
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
|
// Retrieve the potentially incomplete receipts from disk or network
|
||||||
receipts := core.GetBlockReceipts(odr.Database(), hash, number)
|
receipts := core.GetBlockReceipts(odr.Database(), hash, number)
|
||||||
if receipts == nil {
|
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}
|
r := &ReceiptsRequest{Hash: hash, Number: number}
|
||||||
if err := odr.Retrieve(ctx, r); err != nil {
|
if err := odr.Retrieve(ctx, r); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -144,7 +159,7 @@ func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, num
|
||||||
genesis := core.GetCanonicalHash(odr.Database(), 0)
|
genesis := core.GetCanonicalHash(odr.Database(), 0)
|
||||||
config, _ := core.GetChainConfig(odr.Database(), genesis)
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
core.WriteBlockReceipts(odr.Database(), hash, number, receipts)
|
core.WriteBlockReceipts(odr.Database(), hash, number, receipts)
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ var trustedCheckpoints = map[common.Hash]trustedCheckpoint{
|
||||||
var (
|
var (
|
||||||
ErrNoTrustedCht = errors.New("no trusted canonical hash trie")
|
ErrNoTrustedCht = errors.New("no trusted canonical hash trie")
|
||||||
ErrNoTrustedBloomTrie = errors.New("no trusted bloom 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
|
chtPrefix = []byte("chtRoot-") // chtPrefix + chtNum (uint64 big endian) -> trie root hash
|
||||||
ChtTablePrefix = "cht-"
|
ChtTablePrefix = "cht-"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue