mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
commit
147cbec38d
21 changed files with 215 additions and 288 deletions
42
.gitea/workflows/release-cron.yml
Normal file
42
.gitea/workflows/release-cron.yml
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
name: Release Builds (cron)
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
cron: '0 0 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
azure-cleanup:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: 1.24
|
||||||
|
cache: false
|
||||||
|
|
||||||
|
- name: Run cleanup script
|
||||||
|
run: |
|
||||||
|
go run build/ci.go purge -store gethstore/builds -days 14
|
||||||
|
|
||||||
|
ppa:
|
||||||
|
name: PPA Upload (master)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: 1.24
|
||||||
|
cache: false
|
||||||
|
|
||||||
|
- name: Install deb toolchain
|
||||||
|
run: |
|
||||||
|
apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot
|
||||||
|
|
||||||
|
- name: Run ci.go
|
||||||
|
run: |
|
||||||
|
echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts
|
||||||
|
go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>"
|
||||||
48
.gitea/workflows/release.yml
Normal file
48
.gitea/workflows/release.yml
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
name: Release Builds (push)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
name: Linux Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: 1.24
|
||||||
|
cache: false
|
||||||
|
|
||||||
|
- name: display environment
|
||||||
|
run: |
|
||||||
|
env
|
||||||
|
|
||||||
|
- name: Run build
|
||||||
|
run: |
|
||||||
|
go run build/ci.go install
|
||||||
|
|
||||||
|
docker:
|
||||||
|
name: Docker Image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: 1.24
|
||||||
|
cache: false
|
||||||
|
|
||||||
|
- name: Run docker build
|
||||||
|
run: |
|
||||||
|
go run build/ci.go dockerx -platform linux/amd64,linux/arm64,linux/riscv64
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
# This file contains sha256 checksums of optional build dependencies.
|
# This file contains sha256 checksums of optional build dependencies.
|
||||||
|
|
||||||
# version:spec-tests pectra-devnet-6@v1.0.0
|
# version:spec-tests v4.5.0
|
||||||
# https://github.com/ethereum/execution-spec-tests/releases
|
# https://github.com/ethereum/execution-spec-tests/releases
|
||||||
# https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/
|
# https://github.com/ethereum/execution-spec-tests/releases/download/v4.5.0/
|
||||||
b69211752a3029083c020dc635fe12156ca1a6725a08559da540a0337586a77e fixtures_pectra-devnet-6.tar.gz
|
58afb92a0075a2cb7c4dec1281f7cb88b21b02afbedad096b580f3f8cc14c54c fixtures_develop.tar.gz
|
||||||
|
|
||||||
# version:golang 1.24.3
|
# version:golang 1.24.3
|
||||||
# https://go.dev/dl/
|
# https://go.dev/dl/
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,7 @@ func doTest(cmdline []string) {
|
||||||
// downloadSpecTestFixtures downloads and extracts the execution-spec-tests fixtures.
|
// downloadSpecTestFixtures downloads and extracts the execution-spec-tests fixtures.
|
||||||
func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string {
|
func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string {
|
||||||
ext := ".tar.gz"
|
ext := ".tar.gz"
|
||||||
base := "fixtures_pectra-devnet-6" // TODO(s1na) rename once the version becomes part of the filename
|
base := "fixtures_develop"
|
||||||
archivePath := filepath.Join(cachedir, base+ext)
|
archivePath := filepath.Join(cachedir, base+ext)
|
||||||
if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil {
|
if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
@ -445,11 +444,6 @@ func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uin
|
||||||
return beaconDifficulty
|
return beaconDifficulty
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIs implements consensus.Engine, returning the user facing RPC APIs.
|
|
||||||
func (beacon *Beacon) APIs(chain consensus.ChainHeaderReader) []rpc.API {
|
|
||||||
return beacon.ethone.APIs(chain)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close shutdowns the consensus engine
|
// Close shutdowns the consensus engine
|
||||||
func (beacon *Beacon) Close() error {
|
func (beacon *Beacon) Close() error {
|
||||||
return beacon.ethone.Close()
|
return beacon.ethone.Close()
|
||||||
|
|
|
||||||
|
|
@ -1,235 +0,0 @@
|
||||||
// Copyright 2017 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package clique
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
// API is a user facing RPC API to allow controlling the signer and voting
|
|
||||||
// mechanisms of the proof-of-authority scheme.
|
|
||||||
type API struct {
|
|
||||||
chain consensus.ChainHeaderReader
|
|
||||||
clique *Clique
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSnapshot retrieves the state snapshot at a given block.
|
|
||||||
func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) {
|
|
||||||
// Retrieve the requested block number (or current if none requested)
|
|
||||||
var header *types.Header
|
|
||||||
if number == nil || *number == rpc.LatestBlockNumber {
|
|
||||||
header = api.chain.CurrentHeader()
|
|
||||||
} else {
|
|
||||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
|
||||||
}
|
|
||||||
// Ensure we have an actually valid block and return its snapshot
|
|
||||||
if header == nil {
|
|
||||||
return nil, errUnknownBlock
|
|
||||||
}
|
|
||||||
return api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSnapshotAtHash retrieves the state snapshot at a given block.
|
|
||||||
func (api *API) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) {
|
|
||||||
header := api.chain.GetHeaderByHash(hash)
|
|
||||||
if header == nil {
|
|
||||||
return nil, errUnknownBlock
|
|
||||||
}
|
|
||||||
return api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSigners retrieves the list of authorized signers at the specified block.
|
|
||||||
func (api *API) GetSigners(number *rpc.BlockNumber) ([]common.Address, error) {
|
|
||||||
// Retrieve the requested block number (or current if none requested)
|
|
||||||
var header *types.Header
|
|
||||||
if number == nil || *number == rpc.LatestBlockNumber {
|
|
||||||
header = api.chain.CurrentHeader()
|
|
||||||
} else {
|
|
||||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
|
||||||
}
|
|
||||||
// Ensure we have an actually valid block and return the signers from its snapshot
|
|
||||||
if header == nil {
|
|
||||||
return nil, errUnknownBlock
|
|
||||||
}
|
|
||||||
snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return snap.signers(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSignersAtHash retrieves the list of authorized signers at the specified block.
|
|
||||||
func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) {
|
|
||||||
header := api.chain.GetHeaderByHash(hash)
|
|
||||||
if header == nil {
|
|
||||||
return nil, errUnknownBlock
|
|
||||||
}
|
|
||||||
snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return snap.signers(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proposals returns the current proposals the node tries to uphold and vote on.
|
|
||||||
func (api *API) Proposals() map[common.Address]bool {
|
|
||||||
api.clique.lock.RLock()
|
|
||||||
defer api.clique.lock.RUnlock()
|
|
||||||
|
|
||||||
proposals := make(map[common.Address]bool)
|
|
||||||
for address, auth := range api.clique.proposals {
|
|
||||||
proposals[address] = auth
|
|
||||||
}
|
|
||||||
return proposals
|
|
||||||
}
|
|
||||||
|
|
||||||
// Propose injects a new authorization proposal that the signer will attempt to
|
|
||||||
// push through.
|
|
||||||
func (api *API) Propose(address common.Address, auth bool) {
|
|
||||||
api.clique.lock.Lock()
|
|
||||||
defer api.clique.lock.Unlock()
|
|
||||||
|
|
||||||
api.clique.proposals[address] = auth
|
|
||||||
}
|
|
||||||
|
|
||||||
// Discard drops a currently running proposal, stopping the signer from casting
|
|
||||||
// further votes (either for or against).
|
|
||||||
func (api *API) Discard(address common.Address) {
|
|
||||||
api.clique.lock.Lock()
|
|
||||||
defer api.clique.lock.Unlock()
|
|
||||||
|
|
||||||
delete(api.clique.proposals, address)
|
|
||||||
}
|
|
||||||
|
|
||||||
type status struct {
|
|
||||||
InturnPercent float64 `json:"inturnPercent"`
|
|
||||||
SigningStatus map[common.Address]int `json:"sealerActivity"`
|
|
||||||
NumBlocks uint64 `json:"numBlocks"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status returns the status of the last N blocks,
|
|
||||||
// - the number of active signers,
|
|
||||||
// - the number of signers,
|
|
||||||
// - the percentage of in-turn blocks
|
|
||||||
func (api *API) Status() (*status, error) {
|
|
||||||
var (
|
|
||||||
numBlocks = uint64(64)
|
|
||||||
header = api.chain.CurrentHeader()
|
|
||||||
diff = uint64(0)
|
|
||||||
optimals = 0
|
|
||||||
)
|
|
||||||
snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
signers = snap.signers()
|
|
||||||
end = header.Number.Uint64()
|
|
||||||
start = end - numBlocks
|
|
||||||
)
|
|
||||||
if numBlocks > end {
|
|
||||||
start = 1
|
|
||||||
numBlocks = end - start
|
|
||||||
}
|
|
||||||
signStatus := make(map[common.Address]int)
|
|
||||||
for _, s := range signers {
|
|
||||||
signStatus[s] = 0
|
|
||||||
}
|
|
||||||
for n := start; n < end; n++ {
|
|
||||||
h := api.chain.GetHeaderByNumber(n)
|
|
||||||
if h == nil {
|
|
||||||
return nil, fmt.Errorf("missing block %d", n)
|
|
||||||
}
|
|
||||||
if h.Difficulty.Cmp(diffInTurn) == 0 {
|
|
||||||
optimals++
|
|
||||||
}
|
|
||||||
diff += h.Difficulty.Uint64()
|
|
||||||
sealer, err := api.clique.Author(h)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
signStatus[sealer]++
|
|
||||||
}
|
|
||||||
return &status{
|
|
||||||
InturnPercent: float64(100*optimals) / float64(numBlocks),
|
|
||||||
SigningStatus: signStatus,
|
|
||||||
NumBlocks: numBlocks,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type blockNumberOrHashOrRLP struct {
|
|
||||||
*rpc.BlockNumberOrHash
|
|
||||||
RLP hexutil.Bytes `json:"rlp,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sb *blockNumberOrHashOrRLP) UnmarshalJSON(data []byte) error {
|
|
||||||
bnOrHash := new(rpc.BlockNumberOrHash)
|
|
||||||
// Try to unmarshal bNrOrHash
|
|
||||||
if err := bnOrHash.UnmarshalJSON(data); err == nil {
|
|
||||||
sb.BlockNumberOrHash = bnOrHash
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// Try to unmarshal RLP
|
|
||||||
var input string
|
|
||||||
if err := json.Unmarshal(data, &input); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
blob, err := hexutil.Decode(input)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
sb.RLP = blob
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSigner returns the signer for a specific clique block.
|
|
||||||
// Can be called with a block number, a block hash or a rlp encoded blob.
|
|
||||||
// The RLP encoded blob can either be a block or a header.
|
|
||||||
func (api *API) GetSigner(rlpOrBlockNr *blockNumberOrHashOrRLP) (common.Address, error) {
|
|
||||||
if len(rlpOrBlockNr.RLP) == 0 {
|
|
||||||
blockNrOrHash := rlpOrBlockNr.BlockNumberOrHash
|
|
||||||
var header *types.Header
|
|
||||||
if blockNrOrHash == nil {
|
|
||||||
header = api.chain.CurrentHeader()
|
|
||||||
} else if hash, ok := blockNrOrHash.Hash(); ok {
|
|
||||||
header = api.chain.GetHeaderByHash(hash)
|
|
||||||
} else if number, ok := blockNrOrHash.Number(); ok {
|
|
||||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
|
||||||
}
|
|
||||||
if header == nil {
|
|
||||||
return common.Address{}, fmt.Errorf("missing block %v", blockNrOrHash.String())
|
|
||||||
}
|
|
||||||
return api.clique.Author(header)
|
|
||||||
}
|
|
||||||
block := new(types.Block)
|
|
||||||
if err := rlp.DecodeBytes(rlpOrBlockNr.RLP, block); err == nil {
|
|
||||||
return api.clique.Author(block.Header())
|
|
||||||
}
|
|
||||||
header := new(types.Header)
|
|
||||||
if err := rlp.DecodeBytes(rlpOrBlockNr.RLP, header); err != nil {
|
|
||||||
return common.Address{}, err
|
|
||||||
}
|
|
||||||
return api.clique.Author(header)
|
|
||||||
}
|
|
||||||
|
|
@ -41,7 +41,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"golang.org/x/crypto/sha3"
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
@ -641,15 +640,6 @@ func (c *Clique) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIs implements consensus.Engine, returning the user facing RPC API to allow
|
|
||||||
// controlling the signer voting.
|
|
||||||
func (c *Clique) APIs(chain consensus.ChainHeaderReader) []rpc.API {
|
|
||||||
return []rpc.API{{
|
|
||||||
Namespace: "clique",
|
|
||||||
Service: &API{chain: chain, clique: c},
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SealHash returns the hash of a block prior to it being sealed.
|
// SealHash returns the hash of a block prior to it being sealed.
|
||||||
func SealHash(header *types.Header) (hash common.Hash) {
|
func SealHash(header *types.Header) (hash common.Hash) {
|
||||||
hasher := sha3.NewLegacyKeccak256()
|
hasher := sha3.NewLegacyKeccak256()
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ChainHeaderReader defines a small collection of methods needed to access the local
|
// ChainHeaderReader defines a small collection of methods needed to access the local
|
||||||
|
|
@ -109,9 +108,6 @@ type Engine interface {
|
||||||
// that a new block should have.
|
// that a new block should have.
|
||||||
CalcDifficulty(chain ChainHeaderReader, time uint64, parent *types.Header) *big.Int
|
CalcDifficulty(chain ChainHeaderReader, time uint64, parent *types.Header) *big.Int
|
||||||
|
|
||||||
// APIs returns the RPC APIs this consensus engine provides.
|
|
||||||
APIs(chain ChainHeaderReader) []rpc.API
|
|
||||||
|
|
||||||
// Close terminates any background threads maintained by the consensus engine.
|
// Close terminates any background threads maintained by the consensus engine.
|
||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ethash is a consensus engine based on proof-of-work implementing the ethash
|
// Ethash is a consensus engine based on proof-of-work implementing the ethash
|
||||||
|
|
@ -71,12 +70,6 @@ func (ethash *Ethash) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIs implements consensus.Engine, returning no APIs as ethash is an empty
|
|
||||||
// shell in the post-merge world.
|
|
||||||
func (ethash *Ethash) APIs(chain consensus.ChainHeaderReader) []rpc.API {
|
|
||||||
return []rpc.API{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seal generates a new sealing request for the given input block and pushes
|
// Seal generates a new sealing request for the given input block and pushes
|
||||||
// the result into the given channel. For the ethash engine, this method will
|
// the result into the given channel. For the ethash engine, this method will
|
||||||
// just panic as sealing is not supported anymore.
|
// just panic as sealing is not supported anymore.
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@ import (
|
||||||
|
|
||||||
// insertStats tracks and reports on block insertion.
|
// insertStats tracks and reports on block insertion.
|
||||||
type insertStats struct {
|
type insertStats struct {
|
||||||
queued, processed, ignored int
|
processed, ignored int
|
||||||
usedGas uint64
|
usedGas uint64
|
||||||
lastIndex int
|
lastIndex int
|
||||||
startTime mclock.AbsTime
|
startTime mclock.AbsTime
|
||||||
}
|
}
|
||||||
|
|
||||||
// statsReportLimit is the time limit during import and export after which we
|
// statsReportLimit is the time limit during import and export after which we
|
||||||
|
|
@ -78,9 +78,6 @@ func (st *insertStats) report(chain []*types.Block, index int, snapDiffItems, sn
|
||||||
}
|
}
|
||||||
context = append(context, []interface{}{"triedirty", triebufNodes}...)
|
context = append(context, []interface{}{"triedirty", triebufNodes}...)
|
||||||
|
|
||||||
if st.queued > 0 {
|
|
||||||
context = append(context, []interface{}{"queued", st.queued}...)
|
|
||||||
}
|
|
||||||
if st.ignored > 0 {
|
if st.ignored > 0 {
|
||||||
context = append(context, []interface{}{"ignored", st.ignored}...)
|
context = append(context, []interface{}{"ignored", st.ignored}...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -408,6 +408,7 @@ func (ch storageChange) copy() journalEntry {
|
||||||
account: ch.account,
|
account: ch.account,
|
||||||
key: ch.key,
|
key: ch.key,
|
||||||
prevvalue: ch.prevvalue,
|
prevvalue: ch.prevvalue,
|
||||||
|
origvalue: ch.origvalue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,12 @@ const (
|
||||||
// limit can never hurt.
|
// limit can never hurt.
|
||||||
txMaxSize = 1024 * 1024
|
txMaxSize = 1024 * 1024
|
||||||
|
|
||||||
|
// maxBlobsPerTx is the maximum number of blobs that a single transaction can
|
||||||
|
// carry. We choose a smaller limit than the protocol-permitted MaxBlobsPerBlock
|
||||||
|
// in order to ensure network and txpool stability.
|
||||||
|
// Note: if you increase this, validation will fail on txMaxSize.
|
||||||
|
maxBlobsPerTx = 7
|
||||||
|
|
||||||
// maxTxsPerAccount is the maximum number of blob transactions admitted from
|
// maxTxsPerAccount is the maximum number of blob transactions admitted from
|
||||||
// a single account. The limit is enforced to minimize the DoS potential of
|
// a single account. The limit is enforced to minimize the DoS potential of
|
||||||
// a private tx cancelling publicly propagated blobs.
|
// a private tx cancelling publicly propagated blobs.
|
||||||
|
|
@ -1095,10 +1101,11 @@ func (p *BlobPool) SetGasTip(tip *big.Int) {
|
||||||
// and does not require the pool mutex to be held.
|
// and does not require the pool mutex to be held.
|
||||||
func (p *BlobPool) ValidateTxBasics(tx *types.Transaction) error {
|
func (p *BlobPool) ValidateTxBasics(tx *types.Transaction) error {
|
||||||
opts := &txpool.ValidationOptions{
|
opts := &txpool.ValidationOptions{
|
||||||
Config: p.chain.Config(),
|
Config: p.chain.Config(),
|
||||||
Accept: 1 << types.BlobTxType,
|
Accept: 1 << types.BlobTxType,
|
||||||
MaxSize: txMaxSize,
|
MaxSize: txMaxSize,
|
||||||
MinTip: p.gasTip.ToBig(),
|
MinTip: p.gasTip.ToBig(),
|
||||||
|
MaxBlobCount: maxBlobsPerTx,
|
||||||
}
|
}
|
||||||
return txpool.ValidateTransaction(tx, p.head, p.signer, opts)
|
return txpool.ValidateTransaction(tx, p.head, p.signer, opts)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1142,6 +1142,65 @@ func TestChangingSlotterSize(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestBlobCountLimit tests the blobpool enforced limits on the max blob count.
|
||||||
|
func TestBlobCountLimit(t *testing.T) {
|
||||||
|
var (
|
||||||
|
key1, _ = crypto.GenerateKey()
|
||||||
|
key2, _ = crypto.GenerateKey()
|
||||||
|
|
||||||
|
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
|
addr2 = crypto.PubkeyToAddress(key2.PublicKey)
|
||||||
|
)
|
||||||
|
|
||||||
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
|
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
|
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
|
statedb.Commit(0, true, false)
|
||||||
|
|
||||||
|
// Make Prague-enabled custom chain config.
|
||||||
|
cancunTime := uint64(0)
|
||||||
|
pragueTime := uint64(0)
|
||||||
|
config := ¶ms.ChainConfig{
|
||||||
|
ChainID: big.NewInt(1),
|
||||||
|
LondonBlock: big.NewInt(0),
|
||||||
|
BerlinBlock: big.NewInt(0),
|
||||||
|
CancunTime: &cancunTime,
|
||||||
|
PragueTime: &pragueTime,
|
||||||
|
BlobScheduleConfig: ¶ms.BlobScheduleConfig{
|
||||||
|
Cancun: params.DefaultCancunBlobConfig,
|
||||||
|
Prague: params.DefaultPragueBlobConfig,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
chain := &testBlockChain{
|
||||||
|
config: config,
|
||||||
|
basefee: uint256.NewInt(1050),
|
||||||
|
blobfee: uint256.NewInt(105),
|
||||||
|
statedb: statedb,
|
||||||
|
}
|
||||||
|
pool := New(Config{Datadir: t.TempDir()}, chain, nil)
|
||||||
|
if err := pool.Init(1, chain.CurrentBlock(), newReserver()); err != nil {
|
||||||
|
t.Fatalf("failed to create blob pool: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to add transactions.
|
||||||
|
var (
|
||||||
|
tx1 = makeMultiBlobTx(0, 1, 1000, 100, 7, key1)
|
||||||
|
tx2 = makeMultiBlobTx(0, 1, 800, 70, 8, key2)
|
||||||
|
)
|
||||||
|
errs := pool.Add([]*types.Transaction{tx1, tx2}, true)
|
||||||
|
|
||||||
|
// Check that first succeeds second fails.
|
||||||
|
if errs[0] != nil {
|
||||||
|
t.Fatalf("expected tx with 7 blobs to succeed")
|
||||||
|
}
|
||||||
|
if !errors.Is(errs[1], txpool.ErrTxBlobLimitExceeded) {
|
||||||
|
t.Fatalf("expected tx with 8 blobs to fail, got: %v", errs[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyPoolInternals(t, pool)
|
||||||
|
pool.Close()
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that adding transaction will correctly store it in the persistent store
|
// Tests that adding transaction will correctly store it in the persistent store
|
||||||
// and update all the indices.
|
// and update all the indices.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,10 @@ var (
|
||||||
// making the transaction invalid, rather a DOS protection.
|
// making the transaction invalid, rather a DOS protection.
|
||||||
ErrOversizedData = errors.New("oversized data")
|
ErrOversizedData = errors.New("oversized data")
|
||||||
|
|
||||||
|
// ErrTxBlobLimitExceeded is returned if a transaction would exceed the number
|
||||||
|
// of blobs allowed by blobpool.
|
||||||
|
ErrTxBlobLimitExceeded = errors.New("transaction blob limit exceeded")
|
||||||
|
|
||||||
// ErrAlreadyReserved is returned if the sender address has a pending transaction
|
// ErrAlreadyReserved is returned if the sender address has a pending transaction
|
||||||
// in a different subpool. For example, this error is returned in response to any
|
// in a different subpool. For example, this error is returned in response to any
|
||||||
// input transaction of non-blob type when a blob transaction from this sender
|
// input transaction of non-blob type when a blob transaction from this sender
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,10 @@ var (
|
||||||
type ValidationOptions struct {
|
type ValidationOptions struct {
|
||||||
Config *params.ChainConfig // Chain configuration to selectively validate based on current fork rules
|
Config *params.ChainConfig // Chain configuration to selectively validate based on current fork rules
|
||||||
|
|
||||||
Accept uint8 // Bitmap of transaction types that should be accepted for the calling pool
|
Accept uint8 // Bitmap of transaction types that should be accepted for the calling pool
|
||||||
MaxSize uint64 // Maximum size of a transaction that the caller can meaningfully handle
|
MaxSize uint64 // Maximum size of a transaction that the caller can meaningfully handle
|
||||||
MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool
|
MaxBlobCount int // Maximum number of blobs allowed per transaction
|
||||||
|
MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidationFunction is an method type which the pools use to perform the tx-validations which do not
|
// ValidationFunction is an method type which the pools use to perform the tx-validations which do not
|
||||||
|
|
@ -63,6 +64,9 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
||||||
if opts.Accept&(1<<tx.Type()) == 0 {
|
if opts.Accept&(1<<tx.Type()) == 0 {
|
||||||
return fmt.Errorf("%w: tx type %v not supported by this pool", core.ErrTxTypeNotSupported, tx.Type())
|
return fmt.Errorf("%w: tx type %v not supported by this pool", core.ErrTxTypeNotSupported, tx.Type())
|
||||||
}
|
}
|
||||||
|
if blobCount := len(tx.BlobHashes()); blobCount > opts.MaxBlobCount {
|
||||||
|
return fmt.Errorf("%w: blob count %v, limit %v", ErrTxBlobLimitExceeded, blobCount, opts.MaxBlobCount)
|
||||||
|
}
|
||||||
// Before performing any expensive validations, sanity check that the tx is
|
// Before performing any expensive validations, sanity check that the tx is
|
||||||
// smaller than the maximum limit the pool can meaningfully handle
|
// smaller than the maximum limit the pool can meaningfully handle
|
||||||
if tx.Size() > opts.MaxSize {
|
if tx.Size() > opts.MaxSize {
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//go:build !nacl && !js && !wasip1 && cgo && !gofuzz
|
//go:build !nacl && !js && !wasip1 && cgo && !gofuzz && !tinygo
|
||||||
// +build !nacl,!js,!wasip1,cgo,!gofuzz
|
// +build !nacl,!js,!wasip1,cgo,!gofuzz,!tinygo
|
||||||
|
|
||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//go:build nacl || js || wasip1 || !cgo || gofuzz
|
//go:build nacl || js || wasip1 || !cgo || gofuzz || tinygo
|
||||||
// +build nacl js wasip1 !cgo gofuzz
|
// +build nacl js wasip1 !cgo gofuzz tinygo
|
||||||
|
|
||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -337,9 +337,6 @@ func makeExtraData(extra []byte) []byte {
|
||||||
func (s *Ethereum) APIs() []rpc.API {
|
func (s *Ethereum) APIs() []rpc.API {
|
||||||
apis := ethapi.GetAPIs(s.APIBackend)
|
apis := ethapi.GetAPIs(s.APIBackend)
|
||||||
|
|
||||||
// Append any APIs exposed explicitly by the consensus engine
|
|
||||||
apis = append(apis, s.engine.APIs(s.BlockChain())...)
|
|
||||||
|
|
||||||
// Append all the local APIs and return
|
// Append all the local APIs and return
|
||||||
return append(apis, []rpc.API{
|
return append(apis, []rpc.API{
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,33 @@ func Env() Environment {
|
||||||
IsPullRequest: os.Getenv("APPVEYOR_PULL_REQUEST_NUMBER") != "",
|
IsPullRequest: os.Getenv("APPVEYOR_PULL_REQUEST_NUMBER") != "",
|
||||||
IsCronJob: os.Getenv("APPVEYOR_SCHEDULED_BUILD") == "True",
|
IsCronJob: os.Getenv("APPVEYOR_SCHEDULED_BUILD") == "True",
|
||||||
}
|
}
|
||||||
|
case os.Getenv("CI") == "true" && os.Getenv("GITHUB_ACTIONS") == "true":
|
||||||
|
commit := os.Getenv("GITHUB_SHA")
|
||||||
|
reftype := os.Getenv("GITHUB_REF_TYPE")
|
||||||
|
isPR := os.Getenv("GITHUB_HEAD_REF") != ""
|
||||||
|
tag := ""
|
||||||
|
branch := ""
|
||||||
|
switch {
|
||||||
|
case isPR:
|
||||||
|
branch = os.Getenv("GITHUB_BASE_REF")
|
||||||
|
case reftype == "branch":
|
||||||
|
branch = os.Getenv("GITHUB_REF_NAME")
|
||||||
|
case reftype == "tag":
|
||||||
|
tag = os.Getenv("GITHUB_REF_NAME")
|
||||||
|
}
|
||||||
|
return Environment{
|
||||||
|
CI: true,
|
||||||
|
Name: "github-actions",
|
||||||
|
Repo: os.Getenv("GITHUB_REPOSITORY"),
|
||||||
|
Commit: commit,
|
||||||
|
Date: getDate(commit),
|
||||||
|
Branch: branch,
|
||||||
|
Tag: tag,
|
||||||
|
IsPullRequest: isPR,
|
||||||
|
Buildnum: os.Getenv("GITHUB_RUN_ID"),
|
||||||
|
IsCronJob: os.Getenv("GITHUB_EVENT_NAME") == "schedule",
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return LocalEnv()
|
return LocalEnv()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ func ComputeAccumulator(hashes []common.Hash, tds []*big.Int) (common.Hash, erro
|
||||||
|
|
||||||
// headerRecord is an individual record for a historical header.
|
// headerRecord is an individual record for a historical header.
|
||||||
//
|
//
|
||||||
// See https://github.com/ethereum/portal-network-specs/blob/master/history-network.md#the-header-accumulator
|
// See https://github.com/ethereum/portal-network-specs/blob/master/history/history-network.md#the-historical-hashes-accumulator
|
||||||
// for more information.
|
// for more information.
|
||||||
type headerRecord struct {
|
type headerRecord struct {
|
||||||
Hash common.Hash
|
Hash common.Hash
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,9 @@ func TestExecutionSpecBlocktests(t *testing.T) {
|
||||||
}
|
}
|
||||||
bt := new(testMatcher)
|
bt := new(testMatcher)
|
||||||
|
|
||||||
|
bt.skipLoad(".*prague/eip7251_consolidations/contract_deployment/system_contract_deployment.json")
|
||||||
|
bt.skipLoad(".*prague/eip7002_el_triggerable_withdrawals/contract_deployment/system_contract_deployment.json")
|
||||||
|
|
||||||
bt.walk(t, executionSpecBlockchainTestDir, func(t *testing.T, name string, test *BlockTest) {
|
bt.walk(t, executionSpecBlockchainTestDir, func(t *testing.T, name string, test *BlockTest) {
|
||||||
execBlockTest(t, bt, test)
|
execBlockTest(t, bt, test)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue