mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-11 14:33:52 +00:00
Merge branch 'master' into feature/private-key-management
This commit is contained in:
commit
8570ff1a5f
11 changed files with 103 additions and 19 deletions
|
|
@ -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)
|
||||||
[](https://goreportcard.com/report/github.com/ethereum/go-ethereum)
|
[](https://goreportcard.com/report/github.com/ethereum/go-ethereum)
|
||||||
[](https://travis-ci.com/ethereum/go-ethereum)
|
[](https://app.travis-ci.com/github/ethereum/go-ethereum)
|
||||||
[](https://discord.gg/nthXNEv)
|
[](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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,9 @@
|
||||||
},
|
},
|
||||||
"0x82b941824b43F33e417be1E92273A3020a0D760c": {
|
"0x82b941824b43F33e417be1E92273A3020a0D760c": {
|
||||||
"balance": "10000000000000000000000000000"
|
"balance": "10000000000000000000000000000"
|
||||||
|
},
|
||||||
|
"0x57508f0B0f3426758F1f3D63ad4935a7c9383620": {
|
||||||
|
"balance": "10000000000000000000000000000"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"number": "0x0",
|
"number": "0x0",
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,10 @@
|
||||||
},
|
},
|
||||||
"f39Fd6e51aad88F6F4ce6aB8827279cffFb92266": {
|
"f39Fd6e51aad88F6F4ce6aB8827279cffFb92266": {
|
||||||
"balance": "10000000000000000000000"
|
"balance": "10000000000000000000000"
|
||||||
}
|
},
|
||||||
|
"0x3fab184622dc19b6109349b94811493bf2a45362": {
|
||||||
|
"balance": "10000000000000000000000"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"number": "0x0",
|
"number": "0x0",
|
||||||
"gasUsed": "0x0",
|
"gasUsed": "0x0",
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue