Merge branch 'master' into feature/private-key-management

This commit is contained in:
Mikelle 2024-02-02 10:42:29 +08:00
commit 8570ff1a5f
11 changed files with 103 additions and 19 deletions

View file

@ -6,7 +6,7 @@ Golang execution layer implementation of the Ethereum protocol.
https://pkg.go.dev/badge/github.com/ethereum/go-ethereum https://pkg.go.dev/badge/github.com/ethereum/go-ethereum
)](https://pkg.go.dev/github.com/ethereum/go-ethereum?tab=doc) )](https://pkg.go.dev/github.com/ethereum/go-ethereum?tab=doc)
[![Go Report Card](https://goreportcard.com/badge/github.com/ethereum/go-ethereum)](https://goreportcard.com/report/github.com/ethereum/go-ethereum) [![Go Report Card](https://goreportcard.com/badge/github.com/ethereum/go-ethereum)](https://goreportcard.com/report/github.com/ethereum/go-ethereum)
[![Travis](https://travis-ci.com/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.com/ethereum/go-ethereum) [![Travis](https://app.travis-ci.com/ethereum/go-ethereum.svg?branch=master)](https://app.travis-ci.com/github/ethereum/go-ethereum)
[![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv) [![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv)
Automated builds are available for stable releases and the unstable master branch. Binary Automated builds are available for stable releases and the unstable master branch. Binary

View file

@ -2188,6 +2188,12 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
// rewind the canonical chain to a lower point. // rewind the canonical chain to a lower point.
log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain)) log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain))
} }
// Reset the tx lookup cache in case to clear stale txlookups.
// This is done before writing any new chain data to avoid the
// weird scenario that canonical chain is changed while the
// stale lookups are still cached.
bc.txLookupCache.Purge()
// Insert the new chain(except the head block(reverse order)), // Insert the new chain(except the head block(reverse order)),
// taking care of the proper incremental order. // taking care of the proper incremental order.
for i := len(newChain) - 1; i >= 1; i-- { for i := len(newChain) - 1; i >= 1; i-- {
@ -2202,11 +2208,13 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
// Delete useless indexes right now which includes the non-canonical // Delete useless indexes right now which includes the non-canonical
// transaction indexes, canonical chain indexes which above the head. // transaction indexes, canonical chain indexes which above the head.
indexesBatch := bc.db.NewBatch() var (
for _, tx := range types.HashDifference(deletedTxs, addedTxs) { indexesBatch = bc.db.NewBatch()
diffs = types.HashDifference(deletedTxs, addedTxs)
)
for _, tx := range diffs {
rawdb.DeleteTxLookupEntry(indexesBatch, tx) rawdb.DeleteTxLookupEntry(indexesBatch, tx)
} }
// Delete all hash markers that are not part of the new canonical chain. // Delete all hash markers that are not part of the new canonical chain.
// Because the reorg function does not handle new chain head, all hash // Because the reorg function does not handle new chain head, all hash
// markers greater than or equal to new chain head should be deleted. // markers greater than or equal to new chain head should be deleted.

View file

@ -19,6 +19,7 @@ package types
import ( import (
"bytes" "bytes"
"errors" "errors"
"fmt"
"io" "io"
"math/big" "math/big"
"sync/atomic" "sync/atomic"
@ -320,6 +321,7 @@ func (tx *Transaction) Cost() *big.Int {
// RawSignatureValues returns the V, R, S signature values of the transaction. // RawSignatureValues returns the V, R, S signature values of the transaction.
// The return values should not be modified by the caller. // The return values should not be modified by the caller.
// The return values may be nil or zero, if the transaction is unsigned.
func (tx *Transaction) RawSignatureValues() (v, r, s *big.Int) { func (tx *Transaction) RawSignatureValues() (v, r, s *big.Int) {
return tx.inner.rawSignatureValues() return tx.inner.rawSignatureValues()
} }
@ -508,6 +510,9 @@ func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, e
if err != nil { if err != nil {
return nil, err return nil, err
} }
if r == nil || s == nil || v == nil {
return nil, fmt.Errorf("%w: r: %s, s: %s, v: %s", ErrInvalidSig, r, s, v)
}
cpy := tx.inner.copy() cpy := tx.inner.copy()
cpy.setSignatureValues(signer.ChainID(), v, r, s) cpy.setSignatureValues(signer.ChainID(), v, r, s)
return &Transaction{inner: cpy, time: tx.time}, nil return &Transaction{inner: cpy, time: tx.time}, nil

View file

@ -18,11 +18,13 @@ package types
import ( import (
"errors" "errors"
"fmt"
"math/big" "math/big"
"testing" "testing"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
@ -136,3 +138,53 @@ func TestChainId(t *testing.T) {
t.Error("expected no error") t.Error("expected no error")
} }
} }
type nilSigner struct {
v, r, s *big.Int
Signer
}
func (ns *nilSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v *big.Int, err error) {
return ns.v, ns.r, ns.s, nil
}
// TestNilSigner ensures a faulty Signer implementation does not result in nil signature values or panics.
func TestNilSigner(t *testing.T) {
key, _ := crypto.GenerateKey()
innerSigner := LatestSignerForChainID(big.NewInt(1))
for i, signer := range []Signer{
&nilSigner{v: nil, r: nil, s: nil, Signer: innerSigner},
&nilSigner{v: big.NewInt(1), r: big.NewInt(1), s: nil, Signer: innerSigner},
&nilSigner{v: big.NewInt(1), r: nil, s: big.NewInt(1), Signer: innerSigner},
&nilSigner{v: nil, r: big.NewInt(1), s: big.NewInt(1), Signer: innerSigner},
} {
t.Run(fmt.Sprintf("signer_%d", i), func(t *testing.T) {
t.Run("legacy", func(t *testing.T) {
legacyTx := createTestLegacyTxInner()
_, err := SignNewTx(key, signer, legacyTx)
if !errors.Is(err, ErrInvalidSig) {
t.Fatal("expected signature values error, no nil result or panic")
}
})
// test Blob tx specifically, since the signature value types changed
t.Run("blobtx", func(t *testing.T) {
blobtx := createEmptyBlobTxInner(false)
_, err := SignNewTx(key, signer, blobtx)
if !errors.Is(err, ErrInvalidSig) {
t.Fatal("expected signature values error, no nil result or panic")
}
})
})
}
}
func createTestLegacyTxInner() *LegacyTx {
return &LegacyTx{
Nonce: uint64(0),
To: nil,
Value: big.NewInt(0),
Gas: params.TxGas,
GasPrice: big.NewInt(params.GWei),
Data: nil,
}
}

View file

@ -65,6 +65,12 @@ var (
) )
func createEmptyBlobTx(key *ecdsa.PrivateKey, withSidecar bool) *Transaction { func createEmptyBlobTx(key *ecdsa.PrivateKey, withSidecar bool) *Transaction {
blobtx := createEmptyBlobTxInner(withSidecar)
signer := NewCancunSigner(blobtx.ChainID.ToBig())
return MustSignNewTx(key, signer, blobtx)
}
func createEmptyBlobTxInner(withSidecar bool) *BlobTx {
sidecar := &BlobTxSidecar{ sidecar := &BlobTxSidecar{
Blobs: []kzg4844.Blob{emptyBlob}, Blobs: []kzg4844.Blob{emptyBlob},
Commitments: []kzg4844.Commitment{emptyBlobCommit}, Commitments: []kzg4844.Commitment{emptyBlobCommit},
@ -85,6 +91,5 @@ func createEmptyBlobTx(key *ecdsa.PrivateKey, withSidecar bool) *Transaction {
if withSidecar { if withSidecar {
blobtx.Sidecar = sidecar blobtx.Sidecar = sidecar
} }
signer := NewCancunSigner(blobtx.ChainID.ToBig()) return blobtx
return MustSignNewTx(key, signer, blobtx)
} }

View file

@ -87,7 +87,7 @@ The blocks on the 'bad' chain were investigated, and Tim Beiko reached out to th
### Disclosure decision ### Disclosure decision
The geth-team have an official policy regarding [vulnerability disclosure](https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities). The geth-team have an official policy regarding [vulnerability disclosure](https://geth.ethereum.org/docs/developers/geth-developer/disclosures).
> The primary goal for the Geth team is the health of the Ethereum network as a whole, and the decision whether or not to publish details about a serious vulnerability boils down to minimizing the risk and/or impact of discovery and exploitation. > The primary goal for the Geth team is the health of the Ethereum network as a whole, and the decision whether or not to publish details about a serious vulnerability boils down to minimizing the risk and/or impact of discovery and exploitation.

View file

@ -173,8 +173,8 @@ func newConsensusAPIWithoutHeartbeat(eth *eth.Ethereum) *ConsensusAPI {
// and return its payloadID. // and return its payloadID.
func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) { func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) {
if payloadAttributes != nil { if payloadAttributes != nil {
if payloadAttributes.Withdrawals != nil { if payloadAttributes.Withdrawals != nil || payloadAttributes.BeaconRoot != nil {
return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("withdrawals not supported in V1")) return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("withdrawals and beacon root not supported in V1"))
} }
if api.eth.BlockChain().Config().IsShanghai(api.eth.BlockChain().Config().LondonBlock, payloadAttributes.Timestamp) { if api.eth.BlockChain().Config().IsShanghai(api.eth.BlockChain().Config().LondonBlock, payloadAttributes.Timestamp) {
return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("forkChoiceUpdateV1 called post-shanghai")) return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("forkChoiceUpdateV1 called post-shanghai"))
@ -183,23 +183,31 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, pa
return api.forkchoiceUpdated(update, payloadAttributes, engine.PayloadV1, false) return api.forkchoiceUpdated(update, payloadAttributes, engine.PayloadV1, false)
} }
// ForkchoiceUpdatedV2 is equivalent to V1 with the addition of withdrawals in the payload attributes. // ForkchoiceUpdatedV2 is equivalent to V1 with the addition of withdrawals in the payload
// attributes. It supports both PayloadAttributesV1 and PayloadAttributesV2.
func (api *ConsensusAPI) ForkchoiceUpdatedV2(update engine.ForkchoiceStateV1, params *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) { func (api *ConsensusAPI) ForkchoiceUpdatedV2(update engine.ForkchoiceStateV1, params *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) {
if params != nil { if params != nil {
if params.Withdrawals == nil { switch api.eth.BlockChain().Config().LatestFork(params.Timestamp) {
return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("missing withdrawals")) case forks.Paris:
if params.Withdrawals != nil {
return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("withdrawals before shanghai"))
}
case forks.Shanghai:
if params.Withdrawals == nil {
return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("missing withdrawals"))
}
default:
return engine.STATUS_INVALID, engine.UnsupportedFork.With(errors.New("forkchoiceUpdatedV2 must only be called with paris and shanghai payloads"))
} }
if params.BeaconRoot != nil { if params.BeaconRoot != nil {
return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("unexpected beacon root")) return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("unexpected beacon root"))
} }
if api.eth.BlockChain().Config().LatestFork(params.Timestamp) != forks.Shanghai {
return engine.STATUS_INVALID, engine.UnsupportedFork.With(errors.New("forkchoiceUpdatedV2 must only be called for shanghai payloads"))
}
} }
return api.forkchoiceUpdated(update, params, engine.PayloadV2, false) return api.forkchoiceUpdated(update, params, engine.PayloadV2, false)
} }
// ForkchoiceUpdatedV3 is equivalent to V2 with the addition of parent beacon block root in the payload attributes. // ForkchoiceUpdatedV3 is equivalent to V2 with the addition of parent beacon block root
// in the payload attributes. It supports only PayloadAttributesV3.
func (api *ConsensusAPI) ForkchoiceUpdatedV3(update engine.ForkchoiceStateV1, params *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) { func (api *ConsensusAPI) ForkchoiceUpdatedV3(update engine.ForkchoiceStateV1, params *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) {
if params != nil { if params != nil {
// TODO(matt): according to https://github.com/ethereum/execution-apis/pull/498, // TODO(matt): according to https://github.com/ethereum/execution-apis/pull/498,

View file

@ -240,7 +240,7 @@ func newHandler(config *handlerConfig) (*handler, error) {
// accept each others' blocks until a restart. Unfortunately we haven't figured // accept each others' blocks until a restart. Unfortunately we haven't figured
// out a way yet where nodes can decide unilaterally whether the network is new // out a way yet where nodes can decide unilaterally whether the network is new
// or not. This should be fixed if we figure out a solution. // or not. This should be fixed if we figure out a solution.
if !h.synced.Load() { if !h.synced.Load() && config.Sync != downloader.FullSync {
log.Warn("Syncing, discarded propagated block", "number", blocks[0].Number(), "hash", blocks[0].Hash()) log.Warn("Syncing, discarded propagated block", "number", blocks[0].Number(), "hash", blocks[0].Hash())
return 0, nil return 0, nil
} }

View file

@ -56,6 +56,9 @@
}, },
"0x82b941824b43F33e417be1E92273A3020a0D760c": { "0x82b941824b43F33e417be1E92273A3020a0D760c": {
"balance": "10000000000000000000000000000" "balance": "10000000000000000000000000000"
},
"0x57508f0B0f3426758F1f3D63ad4935a7c9383620": {
"balance": "10000000000000000000000000000"
} }
}, },
"number": "0x0", "number": "0x0",

View file

@ -41,7 +41,10 @@
}, },
"f39Fd6e51aad88F6F4ce6aB8827279cffFb92266": { "f39Fd6e51aad88F6F4ce6aB8827279cffFb92266": {
"balance": "10000000000000000000000" "balance": "10000000000000000000000"
} },
"0x3fab184622dc19b6109349b94811493bf2a45362": {
"balance": "10000000000000000000000"
}
}, },
"number": "0x0", "number": "0x0",
"gasUsed": "0x0", "gasUsed": "0x0",

View file

@ -115,7 +115,7 @@ func doMigrateFlags(ctx *cli.Context) {
for _, parent := range ctx.Lineage()[1:] { for _, parent := range ctx.Lineage()[1:] {
if parent.IsSet(name) { if parent.IsSet(name) {
// When iterating across the lineage, we will be served both // When iterating across the lineage, we will be served both
// the 'canon' and alias formats of all commmands. In most cases, // the 'canon' and alias formats of all commands. In most cases,
// it's fine to set it in the ctx multiple times (one for each // it's fine to set it in the ctx multiple times (one for each
// name), however, the Slice-flags are not fine. // name), however, the Slice-flags are not fine.
// The slice-flags accumulate, so if we set it once as // The slice-flags accumulate, so if we set it once as