Skip to content

Commit 2157877

Browse files
committed
consensus/clique: partial port to config2
1 parent 1a63295 commit 2157877

File tree

5 files changed

+79
-41
lines changed

5 files changed

+79
-41
lines changed

consensus/clique/clique.go

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
"github.com/ethereum/go-ethereum/ethdb"
4141
"github.com/ethereum/go-ethereum/log"
4242
"github.com/ethereum/go-ethereum/params"
43+
"github.com/ethereum/go-ethereum/params/forks"
4344
"github.com/ethereum/go-ethereum/rlp"
4445
"github.com/ethereum/go-ethereum/trie"
4546
"golang.org/x/crypto/sha3"
@@ -51,20 +52,25 @@ const (
5152
inmemorySignatures = 4096 // Number of recent block signatures to keep in memory
5253
)
5354

55+
const (
56+
ExtraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
57+
ExtraSeal = crypto.SignatureLength // Fixed number of extra-data suffix bytes reserved for signer seal
58+
59+
DiffInTurn = 2 // Block difficulty for in-turn signatures
60+
DiffNoTurn = 1 // Block difficulty for out-of-turn signatures
61+
)
62+
5463
// Clique proof-of-authority protocol constants.
5564
var (
5665
epochLength = uint64(30000) // Default number of blocks after which to checkpoint and reset the pending votes
5766

58-
extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
59-
extraSeal = crypto.SignatureLength // Fixed number of extra-data suffix bytes reserved for signer seal
60-
6167
nonceAuthVote = hexutil.MustDecode("0xffffffffffffffff") // Magic nonce number to vote on adding a new signer
6268
nonceDropVote = hexutil.MustDecode("0x0000000000000000") // Magic nonce number to vote on removing a signer.
6369

6470
uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW.
6571

66-
diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures
67-
diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures
72+
diffInTurn = big.NewInt(DiffInTurn)
73+
diffNoTurn = big.NewInt(DiffNoTurn)
6874
)
6975

7076
// Various error messages to mark blocks invalid. These should be private to
@@ -145,10 +151,10 @@ func ecrecover(header *types.Header, sigcache *sigLRU) (common.Address, error) {
145151
return address, nil
146152
}
147153
// Retrieve the signature from the header extra-data
148-
if len(header.Extra) < extraSeal {
154+
if len(header.Extra) < ExtraSeal {
149155
return common.Address{}, errMissingSignature
150156
}
151-
signature := header.Extra[len(header.Extra)-extraSeal:]
157+
signature := header.Extra[len(header.Extra)-ExtraSeal:]
152158

153159
// Recover the public key and the Ethereum address
154160
pubkey, err := crypto.Ecrecover(SealHash(header).Bytes(), signature)
@@ -165,8 +171,8 @@ func ecrecover(header *types.Header, sigcache *sigLRU) (common.Address, error) {
165171
// Clique is the proof-of-authority consensus engine proposed to support the
166172
// Ethereum testnet following the Ropsten attacks.
167173
type Clique struct {
168-
config *params.CliqueConfig // Consensus engine configuration parameters
169-
db ethdb.Database // Database to store and retrieve snapshot checkpoints
174+
config *Config // Consensus engine configuration parameters
175+
db ethdb.Database // Database to store and retrieve snapshot checkpoints
170176

171177
recents *lru.Cache[common.Hash, *Snapshot] // Snapshots for recent block to speed up reorgs
172178
signatures *sigLRU // Signatures of recent blocks to speed up mining
@@ -182,18 +188,17 @@ type Clique struct {
182188

183189
// New creates a Clique proof-of-authority consensus engine with the initial
184190
// signers set to the ones provided by the user.
185-
func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
191+
func New(config Config, db ethdb.Database) *Clique {
186192
// Set any missing consensus parameters to their defaults
187-
conf := *config
188-
if conf.Epoch == 0 {
189-
conf.Epoch = epochLength
193+
if config.Epoch == 0 {
194+
config.Epoch = epochLength
190195
}
191196
// Allocate the snapshot caches and create the engine
192197
recents := lru.NewCache[common.Hash, *Snapshot](inmemorySnapshots)
193198
signatures := lru.NewCache[common.Hash, common.Address](inmemorySignatures)
194199

195200
return &Clique{
196-
config: &conf,
201+
config: &config,
197202
db: db,
198203
recents: recents,
199204
signatures: signatures,
@@ -260,14 +265,14 @@ func (c *Clique) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
260265
return errInvalidCheckpointVote
261266
}
262267
// Check that the extra-data contains both the vanity and signature
263-
if len(header.Extra) < extraVanity {
268+
if len(header.Extra) < ExtraVanity {
264269
return errMissingVanity
265270
}
266-
if len(header.Extra) < extraVanity+extraSeal {
271+
if len(header.Extra) < ExtraVanity+ExtraSeal {
267272
return errMissingSignature
268273
}
269274
// Ensure that the extra-data contains a signer list on checkpoint, but none otherwise
270-
signersBytes := len(header.Extra) - extraVanity - extraSeal
275+
signersBytes := len(header.Extra) - ExtraVanity - ExtraSeal
271276
if !checkpoint && signersBytes != 0 {
272277
return errExtraSigners
273278
}
@@ -292,14 +297,14 @@ func (c *Clique) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
292297
if header.GasLimit > params.MaxGasLimit {
293298
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, params.MaxGasLimit)
294299
}
295-
if chain.Config().IsShanghai(header.Number, header.Time) {
300+
if chain.Config().Active(forks.Shanghai, header.Number.Uint64(), header.Time) {
296301
return errors.New("clique does not support shanghai fork")
297302
}
298303
// Verify the non-existence of withdrawalsHash.
299304
if header.WithdrawalsHash != nil {
300305
return fmt.Errorf("invalid withdrawalsHash: have %x, expected nil", header.WithdrawalsHash)
301306
}
302-
if chain.Config().IsCancun(header.Number, header.Time) {
307+
if chain.Config().Active(forks.Cancun, header.Number.Uint64(), header.Time) {
303308
return errors.New("clique does not support cancun fork")
304309
}
305310
// Verify the non-existence of cancun-specific header fields
@@ -342,7 +347,7 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header
342347
if header.GasUsed > header.GasLimit {
343348
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
344349
}
345-
if !chain.Config().IsLondon(header.Number) {
350+
if !chain.Config().Active(forks.London, header.Number.Uint64(), header.Time) {
346351
// Verify BaseFee not present before EIP-1559 fork.
347352
if header.BaseFee != nil {
348353
return fmt.Errorf("invalid baseFee before fork: have %d, want <nil>", header.BaseFee)
@@ -365,8 +370,8 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header
365370
for i, signer := range snap.signers() {
366371
copy(signers[i*common.AddressLength:], signer[:])
367372
}
368-
extraSuffix := len(header.Extra) - extraSeal
369-
if !bytes.Equal(header.Extra[extraVanity:extraSuffix], signers) {
373+
extraSuffix := len(header.Extra) - ExtraSeal
374+
if !bytes.Equal(header.Extra[ExtraVanity:extraSuffix], signers) {
370375
return errMismatchingCheckpointSigners
371376
}
372377
}
@@ -404,9 +409,9 @@ func (c *Clique) snapshot(chain consensus.ChainHeaderReader, number uint64, hash
404409
if checkpoint != nil {
405410
hash := checkpoint.Hash()
406411

407-
signers := make([]common.Address, (len(checkpoint.Extra)-extraVanity-extraSeal)/common.AddressLength)
412+
signers := make([]common.Address, (len(checkpoint.Extra)-ExtraVanity-ExtraSeal)/common.AddressLength)
408413
for i := 0; i < len(signers); i++ {
409-
copy(signers[i][:], checkpoint.Extra[extraVanity+i*common.AddressLength:])
414+
copy(signers[i][:], checkpoint.Extra[ExtraVanity+i*common.AddressLength:])
410415
}
411416
snap = newSnapshot(c.config, c.signatures, number, hash, signers)
412417
if err := snap.store(c.db); err != nil {
@@ -544,17 +549,17 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header
544549
header.Difficulty = calcDifficulty(snap, signer)
545550

546551
// Ensure the extra data has all its components
547-
if len(header.Extra) < extraVanity {
548-
header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...)
552+
if len(header.Extra) < ExtraVanity {
553+
header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, ExtraVanity-len(header.Extra))...)
549554
}
550-
header.Extra = header.Extra[:extraVanity]
555+
header.Extra = header.Extra[:ExtraVanity]
551556

552557
if number%c.config.Epoch == 0 {
553558
for _, signer := range snap.signers() {
554559
header.Extra = append(header.Extra, signer[:]...)
555560
}
556561
}
557-
header.Extra = append(header.Extra, make([]byte, extraSeal)...)
562+
header.Extra = append(header.Extra, make([]byte, ExtraSeal)...)
558563

559564
// Mix digest is reserved for now, set to empty
560565
header.MixDigest = common.Hash{}
@@ -587,7 +592,8 @@ func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
587592
c.Finalize(chain, header, state, body)
588593

589594
// Assign the final state root to header.
590-
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
595+
deleteEmptyObjects := chain.Config().Active(forks.SpuriousDragon, header.Number.Uint64(), header.Time)
596+
header.Root = state.IntermediateRoot(deleteEmptyObjects)
591597

592598
// Assemble and return the final block for sealing.
593599
return types.NewBlock(header, &types.Body{Transactions: body.Transactions}, receipts, trie.NewStackTrie(nil)), nil

consensus/clique/clique_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
1414
// You should have received a copy of the GNU Lesser General Public License
1515
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
1616

17-
package clique
17+
package clique_test
1818

1919
import (
2020
"math/big"
2121
"testing"
2222

2323
"github.com/ethereum/go-ethereum/common"
24+
"github.com/ethereum/go-ethereum/consensus/clique"
2425
"github.com/ethereum/go-ethereum/core"
2526
"github.com/ethereum/go-ethereum/core/rawdb"
2627
"github.com/ethereum/go-ethereum/core/types"
@@ -40,18 +41,19 @@ func TestReimportMirroredState(t *testing.T) {
4041
db = rawdb.NewMemoryDatabase()
4142
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
4243
addr = crypto.PubkeyToAddress(key.PublicKey)
43-
engine = New(params.AllCliqueProtocolChanges.Clique, db)
44+
config = clique.ConfigParam.Get(presets.AllCliqueProtocolChanges)
45+
engine = clique.New(config, db)
4446
signer = new(types.HomesteadSigner)
4547
)
4648
genspec := &core.Genesis{
4749
Config: params.AllCliqueProtocolChanges,
48-
ExtraData: make([]byte, extraVanity+common.AddressLength+extraSeal),
50+
ExtraData: make([]byte, clique.ExtraVanity+common.AddressLength+clique.ExtraSeal),
4951
Alloc: map[common.Address]types.Account{
5052
addr: {Balance: big.NewInt(10000000000000000)},
5153
},
5254
BaseFee: big.NewInt(params.InitialBaseFee),
5355
}
54-
copy(genspec.ExtraData[extraVanity:], addr[:])
56+
copy(genspec.ExtraData[clique.ExtraVanity:], addr[:])
5557

5658
// Generate a batch of blocks, each properly signed
5759
chain, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), genspec, engine, nil)
@@ -60,7 +62,7 @@ func TestReimportMirroredState(t *testing.T) {
6062
_, blocks, _ := core.GenerateChainWithGenesis(genspec, engine, 3, func(i int, block *core.BlockGen) {
6163
// The chain maker doesn't have access to a chain, so the difficulty will be
6264
// lets unset (nil). Set it here to the correct value.
63-
block.SetDifficulty(diffInTurn)
65+
block.SetDifficulty(big.NewInt(clique.DiffInTurn))
6466

6567
// We want to simulate an empty middle block, having the same state as the
6668
// first one. The last is needs a state change again to force a reorg.
@@ -80,7 +82,7 @@ func TestReimportMirroredState(t *testing.T) {
8082
header.Extra = make([]byte, extraVanity+extraSeal)
8183
header.Difficulty = diffInTurn
8284

83-
sig, _ := crypto.Sign(SealHash(header).Bytes(), key)
85+
sig, _ := crypto.Sign(clique.SealHash(header).Bytes(), key)
8486
copy(header.Extra[len(header.Extra)-extraSeal:], sig)
8587
blocks[i] = block.WithSeal(header)
8688
}

consensus/clique/config.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2025 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package clique
18+
19+
import "github.com/ethereum/go-ethereum/params"
20+
21+
var ConfigParam = params.Define(params.T[Config]{
22+
Name: "clique",
23+
Optional: true, // optional says
24+
Default: Config{},
25+
})
26+
27+
// Config is the consensus engine configs for proof-of-authority based sealing.
28+
type Config struct {
29+
Period uint64 `json:"period"` // Number of seconds between blocks to enforce
30+
Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint
31+
}

consensus/clique/snapshot.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
"github.com/ethereum/go-ethereum/core/types"
3030
"github.com/ethereum/go-ethereum/ethdb"
3131
"github.com/ethereum/go-ethereum/log"
32-
"github.com/ethereum/go-ethereum/params"
3332
)
3433

3534
// Vote represents a single vote that an authorized signer made to modify the
@@ -52,8 +51,8 @@ type sigLRU = lru.Cache[common.Hash, common.Address]
5251

5352
// Snapshot is the state of the authorization voting at a given point in time.
5453
type Snapshot struct {
55-
config *params.CliqueConfig // Consensus engine parameters to fine tune behavior
56-
sigcache *sigLRU // Cache of recent block signatures to speed up ecrecover
54+
config *Config // Consensus engine parameters to fine tune behavior
55+
sigcache *sigLRU // Cache of recent block signatures to speed up ecrecover
5756

5857
Number uint64 `json:"number"` // Block number where the snapshot was created
5958
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
@@ -66,7 +65,7 @@ type Snapshot struct {
6665
// newSnapshot creates a new snapshot with the specified startup parameters. This
6766
// method does not initialize the set of recent signers, so only ever use if for
6867
// the genesis block.
69-
func newSnapshot(config *params.CliqueConfig, sigcache *sigLRU, number uint64, hash common.Hash, signers []common.Address) *Snapshot {
68+
func newSnapshot(config *Config, sigcache *sigLRU, number uint64, hash common.Hash, signers []common.Address) *Snapshot {
7069
snap := &Snapshot{
7170
config: config,
7271
sigcache: sigcache,
@@ -83,7 +82,7 @@ func newSnapshot(config *params.CliqueConfig, sigcache *sigLRU, number uint64, h
8382
}
8483

8584
// loadSnapshot loads an existing snapshot from the database.
86-
func loadSnapshot(config *params.CliqueConfig, sigcache *sigLRU, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
85+
func loadSnapshot(config *Config, sigcache *sigLRU, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
8786
blob, err := db.Get(append(rawdb.CliqueSnapshotPrefix, hash[:]...))
8887
if err != nil {
8988
return nil, err

consensus/clique/snapshot_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// You should have received a copy of the GNU Lesser General Public License
1515
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
1616

17-
package clique
17+
package clique_test
1818

1919
import (
2020
"bytes"

0 commit comments

Comments
 (0)