Merge tag 'v1.15.2' into firehose-fh3.0

This commit is contained in:
Matthieu Vachon 2025-02-20 12:56:47 -05:00
commit 299fd9600e
14 changed files with 120 additions and 51 deletions

View file

@ -304,7 +304,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
// Set the receipt logs and create the bloom filter. // Set the receipt logs and create the bloom filter.
receipt.Logs = statedb.GetLogs(tx.Hash(), vmContext.BlockNumber.Uint64(), blockHash) receipt.Logs = statedb.GetLogs(tx.Hash(), vmContext.BlockNumber.Uint64(), blockHash)
receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) receipt.Bloom = types.CreateBloom(receipt)
// These three are non-consensus fields: // These three are non-consensus fields:
//receipt.BlockHash //receipt.BlockHash
//receipt.BlockNumber //receipt.BlockNumber
@ -376,7 +377,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
StateRoot: root, StateRoot: root,
TxRoot: types.DeriveSha(includedTxs, trie.NewStackTrie(nil)), TxRoot: types.DeriveSha(includedTxs, trie.NewStackTrie(nil)),
ReceiptRoot: types.DeriveSha(receipts, trie.NewStackTrie(nil)), ReceiptRoot: types.DeriveSha(receipts, trie.NewStackTrie(nil)),
Bloom: types.CreateBloom(receipts), Bloom: types.MergeBloom(receipts),
LogsHash: rlpHash(statedb.Logs()), LogsHash: rlpHash(statedb.Logs()),
Receipts: receipts, Receipts: receipts,
Rejected: rejectedTxs, Rejected: rejectedTxs,

View file

@ -75,9 +75,11 @@ func New(ethone consensus.Engine) *Beacon {
// isPostMerge reports whether the given block number is assumed to be post-merge. // isPostMerge reports whether the given block number is assumed to be post-merge.
// Here we check the MergeNetsplitBlock to allow configuring networks with a PoW or // Here we check the MergeNetsplitBlock to allow configuring networks with a PoW or
// PoA chain for unit testing purposes. // PoA chain for unit testing purposes.
func isPostMerge(config *params.ChainConfig, block uint64) bool { func isPostMerge(config *params.ChainConfig, blockNum uint64, timestamp uint64) bool {
mergedAtGenesis := config.TerminalTotalDifficulty != nil && config.TerminalTotalDifficulty.Sign() == 0 mergedAtGenesis := config.TerminalTotalDifficulty != nil && config.TerminalTotalDifficulty.Sign() == 0
return mergedAtGenesis || config.MergeNetsplitBlock != nil && block >= config.MergeNetsplitBlock.Uint64() return mergedAtGenesis ||
config.MergeNetsplitBlock != nil && blockNum >= config.MergeNetsplitBlock.Uint64() ||
config.ShanghaiTime != nil && timestamp >= *config.ShanghaiTime
} }
// Author implements consensus.Engine, returning the verified author of the block. // Author implements consensus.Engine, returning the verified author of the block.
@ -327,7 +329,7 @@ func (beacon *Beacon) verifyHeaders(chain consensus.ChainHeaderReader, headers [
// Prepare implements consensus.Engine, initializing the difficulty field of a // Prepare implements consensus.Engine, initializing the difficulty field of a
// header to conform to the beacon protocol. The changes are done inline. // header to conform to the beacon protocol. The changes are done inline.
func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
if !isPostMerge(chain.Config(), header.Number.Uint64()) { if !isPostMerge(chain.Config(), header.Number.Uint64(), header.Time) {
return beacon.ethone.Prepare(chain, header) return beacon.ethone.Prepare(chain, header)
} }
header.Difficulty = beaconDifficulty header.Difficulty = beaconDifficulty
@ -437,7 +439,7 @@ func (beacon *Beacon) SealHash(header *types.Header) common.Hash {
// the difficulty that a new block should have when created at time // the difficulty that a new block should have when created at time
// given the parent block's time and difficulty. // given the parent block's time and difficulty.
func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int {
if !isPostMerge(chain.Config(), parent.Number.Uint64()+1) { if !isPostMerge(chain.Config(), parent.Number.Uint64()+1, time) {
return beacon.ethone.CalcDifficulty(chain, time, parent) return beacon.ethone.CalcDifficulty(chain, time, parent)
} }
return beaconDifficulty return beaconDifficulty

View file

@ -129,7 +129,11 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
} }
// Validate the received block's bloom with the one derived from the generated receipts. // Validate the received block's bloom with the one derived from the generated receipts.
// For valid blocks this should always validate to true. // For valid blocks this should always validate to true.
rbloom := types.CreateBloom(res.Receipts) //
// Receipts must go through MakeReceipt to calculate the receipt's bloom
// already. Merge the receipt's bloom together instead of recalculating
// everything.
rbloom := types.MergeBloom(res.Receipts)
if rbloom != header.Bloom { if rbloom != header.Bloom {
return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom, rbloom) return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom, rbloom)
} }

View file

@ -338,7 +338,7 @@ func TestBlockReceiptStorage(t *testing.T) {
ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}),
GasUsed: 111111, GasUsed: 111111,
} }
receipt1.Bloom = types.CreateBloom(types.Receipts{receipt1}) receipt1.Bloom = types.CreateBloom(receipt1)
receipt2 := &types.Receipt{ receipt2 := &types.Receipt{
PostState: common.Hash{2}.Bytes(), PostState: common.Hash{2}.Bytes(),
@ -351,7 +351,7 @@ func TestBlockReceiptStorage(t *testing.T) {
ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}),
GasUsed: 222222, GasUsed: 222222,
} }
receipt2.Bloom = types.CreateBloom(types.Receipts{receipt2}) receipt2.Bloom = types.CreateBloom(receipt2)
receipts := []*types.Receipt{receipt1, receipt2} receipts := []*types.Receipt{receipt1, receipt2}
// Check that no receipt entries are in a pristine database // Check that no receipt entries are in a pristine database
@ -679,7 +679,7 @@ func TestReadLogs(t *testing.T) {
ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}),
GasUsed: 111111, GasUsed: 111111,
} }
receipt1.Bloom = types.CreateBloom(types.Receipts{receipt1}) receipt1.Bloom = types.CreateBloom(receipt1)
receipt2 := &types.Receipt{ receipt2 := &types.Receipt{
PostState: common.Hash{2}.Bytes(), PostState: common.Hash{2}.Bytes(),
@ -692,7 +692,7 @@ func TestReadLogs(t *testing.T) {
ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}),
GasUsed: 222222, GasUsed: 222222,
} }
receipt2.Bloom = types.CreateBloom(types.Receipts{receipt2}) receipt2.Bloom = types.CreateBloom(receipt2)
receipts := []*types.Receipt{receipt1, receipt2} receipts := []*types.Receipt{receipt1, receipt2}
hash := common.BytesToHash([]byte{0x03, 0x14}) hash := common.BytesToHash([]byte{0x03, 0x14})

View file

@ -189,7 +189,7 @@ func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, b
// Set the receipt logs and create the bloom filter. // Set the receipt logs and create the bloom filter.
receipt.Logs = statedb.GetLogs(tx.Hash(), blockNumber.Uint64(), blockHash) receipt.Logs = statedb.GetLogs(tx.Hash(), blockNumber.Uint64(), blockHash)
receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) receipt.Bloom = types.CreateBloom(receipt)
receipt.BlockHash = blockHash receipt.BlockHash = blockHash
receipt.BlockNumber = blockNumber receipt.BlockNumber = blockNumber
receipt.TransactionIndex = uint(statedb.TxIndex()) receipt.TransactionIndex = uint(statedb.TxIndex())

View file

@ -237,6 +237,9 @@ type extblock struct {
// //
// The body elements and the receipts are used to recompute and overwrite the // The body elements and the receipts are used to recompute and overwrite the
// relevant portions of the header. // relevant portions of the header.
//
// The receipt's bloom must already calculated for the block's bloom to be
// correctly calculated.
func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher) *Block { func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher) *Block {
if body == nil { if body == nil {
body = &Body{} body = &Body{}
@ -260,7 +263,10 @@ func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher
b.header.ReceiptHash = EmptyReceiptsHash b.header.ReceiptHash = EmptyReceiptsHash
} else { } else {
b.header.ReceiptHash = DeriveSha(Receipts(receipts), hasher) b.header.ReceiptHash = DeriveSha(Receipts(receipts), hasher)
b.header.Bloom = CreateBloom(receipts) // Receipts must go through MakeReceipt to calculate the receipt's bloom
// already. Merge the receipt's bloom together instead of recalculating
// everything.
b.header.Bloom = MergeBloom(receipts)
} }
if len(uncles) == 0 { if len(uncles) == 0 {

View file

@ -100,32 +100,35 @@ func (b *Bloom) UnmarshalText(input []byte) error {
return hexutil.UnmarshalFixedText("Bloom", input, b[:]) return hexutil.UnmarshalFixedText("Bloom", input, b[:])
} }
// CreateBloom creates a bloom filter out of the give Receipts (+Logs) // CreateBloom creates a bloom filter out of the give Receipt (+Logs)
func CreateBloom(receipts Receipts) Bloom { func CreateBloom(receipt *Receipt) Bloom {
buf := make([]byte, 6) var (
var bin Bloom bin Bloom
for _, receipt := range receipts { buf = make([]byte, 6)
)
for _, log := range receipt.Logs { for _, log := range receipt.Logs {
bin.add(log.Address.Bytes(), buf) bin.add(log.Address.Bytes(), buf)
for _, b := range log.Topics { for _, b := range log.Topics {
bin.add(b[:], buf) bin.add(b[:], buf)
} }
} }
}
return bin return bin
} }
// LogsBloom returns the bloom bytes for the given logs // MergeBloom merges the precomputed bloom filters in the Receipts without
func LogsBloom(logs []*Log) []byte { // recalculating them. It assumes that each receipts Bloom field is already
buf := make([]byte, 6) // correctly populated.
func MergeBloom(receipts Receipts) Bloom {
var bin Bloom var bin Bloom
for _, log := range logs { for _, receipt := range receipts {
bin.add(log.Address.Bytes(), buf) if len(receipt.Logs) != 0 {
for _, b := range log.Topics { bl := receipt.Bloom.Bytes()
bin.add(b[:], buf) for i := range bin {
bin[i] |= bl[i]
} }
} }
return bin[:] }
return bin
} }
// Bloom9 returns the bloom filter for the given data // Bloom9 returns the bloom filter for the given data

View file

@ -126,26 +126,70 @@ func BenchmarkCreateBloom(b *testing.B) {
for i := 0; i < 200; i += 2 { for i := 0; i < 200; i += 2 {
copy(rLarge[i:], rSmall) copy(rLarge[i:], rSmall)
} }
b.Run("small", func(b *testing.B) { b.Run("small-createbloom", func(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
var bl Bloom
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
bl = CreateBloom(rSmall) for _, receipt := range rSmall {
receipt.Bloom = CreateBloom(receipt)
}
} }
b.StopTimer() b.StopTimer()
bl := MergeBloom(rSmall)
var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949") var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949")
got := crypto.Keccak256Hash(bl.Bytes()) got := crypto.Keccak256Hash(bl.Bytes())
if got != exp { if got != exp {
b.Errorf("Got %x, exp %x", got, exp) b.Errorf("Got %x, exp %x", got, exp)
} }
}) })
b.Run("large", func(b *testing.B) { b.Run("large-createbloom", func(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
var bl Bloom
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
bl = CreateBloom(rLarge) for _, receipt := range rLarge {
receipt.Bloom = CreateBloom(receipt)
}
} }
b.StopTimer() b.StopTimer()
bl := MergeBloom(rLarge)
var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949")
got := crypto.Keccak256Hash(bl.Bytes())
if got != exp {
b.Errorf("Got %x, exp %x", got, exp)
}
})
b.Run("small-mergebloom", func(b *testing.B) {
for _, receipt := range rSmall {
receipt.Bloom = CreateBloom(receipt)
}
b.ReportAllocs()
b.ResetTimer()
var bl Bloom
for i := 0; i < b.N; i++ {
bl = MergeBloom(rSmall)
}
b.StopTimer()
var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949")
got := crypto.Keccak256Hash(bl.Bytes())
if got != exp {
b.Errorf("Got %x, exp %x", got, exp)
}
})
b.Run("large-mergebloom", func(b *testing.B) {
for _, receipt := range rLarge {
receipt.Bloom = CreateBloom(receipt)
}
b.ReportAllocs()
b.ResetTimer()
var bl Bloom
for i := 0; i < b.N; i++ {
bl = MergeBloom(rLarge)
}
b.StopTimer()
var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949") var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949")
got := crypto.Keccak256Hash(bl.Bytes()) got := crypto.Keccak256Hash(bl.Bytes())
if got != exp { if got != exp {

View file

@ -291,7 +291,7 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error {
} }
r.CumulativeGasUsed = stored.CumulativeGasUsed r.CumulativeGasUsed = stored.CumulativeGasUsed
r.Logs = stored.Logs r.Logs = stored.Logs
r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) r.Bloom = CreateBloom((*Receipt)(r))
return nil return nil
} }

View file

@ -394,7 +394,7 @@ func TestTypedReceiptEncodingDecoding(t *testing.T) {
func TestReceiptMarshalBinary(t *testing.T) { func TestReceiptMarshalBinary(t *testing.T) {
// Legacy Receipt // Legacy Receipt
legacyReceipt.Bloom = CreateBloom(Receipts{legacyReceipt}) legacyReceipt.Bloom = CreateBloom(legacyReceipt)
have, err := legacyReceipt.MarshalBinary() have, err := legacyReceipt.MarshalBinary()
if err != nil { if err != nil {
t.Fatalf("marshal binary error: %v", err) t.Fatalf("marshal binary error: %v", err)
@ -421,7 +421,7 @@ func TestReceiptMarshalBinary(t *testing.T) {
// 2930 Receipt // 2930 Receipt
buf.Reset() buf.Reset()
accessListReceipt.Bloom = CreateBloom(Receipts{accessListReceipt}) accessListReceipt.Bloom = CreateBloom(accessListReceipt)
have, err = accessListReceipt.MarshalBinary() have, err = accessListReceipt.MarshalBinary()
if err != nil { if err != nil {
t.Fatalf("marshal binary error: %v", err) t.Fatalf("marshal binary error: %v", err)
@ -439,7 +439,7 @@ func TestReceiptMarshalBinary(t *testing.T) {
// 1559 Receipt // 1559 Receipt
buf.Reset() buf.Reset()
eip1559Receipt.Bloom = CreateBloom(Receipts{eip1559Receipt}) eip1559Receipt.Bloom = CreateBloom(eip1559Receipt)
have, err = eip1559Receipt.MarshalBinary() have, err = eip1559Receipt.MarshalBinary()
if err != nil { if err != nil {
t.Fatalf("marshal binary error: %v", err) t.Fatalf("marshal binary error: %v", err)
@ -463,7 +463,7 @@ func TestReceiptUnmarshalBinary(t *testing.T) {
if err := gotLegacyReceipt.UnmarshalBinary(legacyBinary); err != nil { if err := gotLegacyReceipt.UnmarshalBinary(legacyBinary); err != nil {
t.Fatalf("unmarshal binary error: %v", err) t.Fatalf("unmarshal binary error: %v", err)
} }
legacyReceipt.Bloom = CreateBloom(Receipts{legacyReceipt}) legacyReceipt.Bloom = CreateBloom(legacyReceipt)
if !reflect.DeepEqual(gotLegacyReceipt, legacyReceipt) { if !reflect.DeepEqual(gotLegacyReceipt, legacyReceipt) {
t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", gotLegacyReceipt, legacyReceipt) t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", gotLegacyReceipt, legacyReceipt)
} }
@ -474,7 +474,7 @@ func TestReceiptUnmarshalBinary(t *testing.T) {
if err := gotAccessListReceipt.UnmarshalBinary(accessListBinary); err != nil { if err := gotAccessListReceipt.UnmarshalBinary(accessListBinary); err != nil {
t.Fatalf("unmarshal binary error: %v", err) t.Fatalf("unmarshal binary error: %v", err)
} }
accessListReceipt.Bloom = CreateBloom(Receipts{accessListReceipt}) accessListReceipt.Bloom = CreateBloom(accessListReceipt)
if !reflect.DeepEqual(gotAccessListReceipt, accessListReceipt) { if !reflect.DeepEqual(gotAccessListReceipt, accessListReceipt) {
t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", gotAccessListReceipt, accessListReceipt) t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", gotAccessListReceipt, accessListReceipt)
} }
@ -485,7 +485,7 @@ func TestReceiptUnmarshalBinary(t *testing.T) {
if err := got1559Receipt.UnmarshalBinary(eip1559RctBinary); err != nil { if err := got1559Receipt.UnmarshalBinary(eip1559RctBinary); err != nil {
t.Fatalf("unmarshal binary error: %v", err) t.Fatalf("unmarshal binary error: %v", err)
} }
eip1559Receipt.Bloom = CreateBloom(Receipts{eip1559Receipt}) eip1559Receipt.Bloom = CreateBloom(eip1559Receipt)
if !reflect.DeepEqual(got1559Receipt, eip1559Receipt) { if !reflect.DeepEqual(got1559Receipt, eip1559Receipt) {
t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", got1559Receipt, eip1559Receipt) t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", got1559Receipt, eip1559Receipt)
} }

View file

@ -42,7 +42,7 @@ func makeReceipt(addr common.Address) *types.Receipt {
receipt.Logs = []*types.Log{ receipt.Logs = []*types.Log{
{Address: addr}, {Address: addr},
} }
receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) receipt.Bloom = types.CreateBloom(receipt)
return receipt return receipt
} }

View file

@ -89,7 +89,7 @@ type TxPool interface {
} }
// MakeProtocols constructs the P2P protocol definitions for `eth`. // MakeProtocols constructs the P2P protocol definitions for `eth`.
func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2p.Protocol { func MakeProtocols(backend Backend, network uint64, disc enode.Iterator) []p2p.Protocol {
protocols := make([]p2p.Protocol, 0, len(ProtocolVersions)) protocols := make([]p2p.Protocol, 0, len(ProtocolVersions))
for _, version := range ProtocolVersions { for _, version := range ProtocolVersions {
protocols = append(protocols, p2p.Protocol{ protocols = append(protocols, p2p.Protocol{
@ -110,6 +110,7 @@ func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2
PeerInfo: func(id enode.ID) interface{} { PeerInfo: func(id enode.ID) interface{} {
return backend.PeerInfo(id) return backend.PeerInfo(id)
}, },
DialCandidates: disc,
Attributes: []enr.Entry{currentENREntry(backend.Chain())}, Attributes: []enr.Entry{currentENREntry(backend.Chain())},
}) })
} }

View file

@ -18,6 +18,7 @@ package p2p
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"encoding"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/common/mclock"
@ -135,6 +136,13 @@ type configNAT struct {
nat.Interface nat.Interface
} }
func (w *configNAT) MarshalText() ([]byte, error) {
if tm, ok := w.Interface.(encoding.TextMarshaler); ok {
return tm.MarshalText()
}
return nil, fmt.Errorf("NAT specification %#v cannot be marshaled", w.Interface)
}
func (w *configNAT) UnmarshalText(input []byte) error { func (w *configNAT) UnmarshalText(input []byte) error {
n, err := nat.Parse(string(input)) n, err := nat.Parse(string(input))
if err != nil { if err != nil {

View file

@ -19,6 +19,6 @@ package version
const ( const (
Major = 1 // Major version component of the current release Major = 1 // Major version component of the current release
Minor = 15 // Minor version component of the current release Minor = 15 // Minor version component of the current release
Patch = 1 // Patch version component of the current release Patch = 2 // Patch version component of the current release
Meta = "stable" // Version metadata to append to the version string Meta = "stable" // Version metadata to append to the version string
) )