Skip to content

Commit 7e098f4

Browse files
NathanBSCallformless
authored andcommitted
miner: add malicious miner feature for test
1 parent e8a4ba0 commit 7e098f4

10 files changed

Lines changed: 278 additions & 7 deletions

File tree

consensus/parlia/parlia.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,6 +1699,23 @@ func (p *Parlia) Delay(chain consensus.ChainReader, header *types.Header, leftOv
16991699
return &delay
17001700
}
17011701

1702+
// AssembleSignature assemble the signature for block header
1703+
func (p *Parlia) AssembleSignature(block *types.Block) (*types.Block, error) {
1704+
header := block.Header()
1705+
// Don't hold the val fields for the entire sealing procedure
1706+
p.lock.RLock()
1707+
val, signFn := p.val, p.signFn
1708+
p.lock.RUnlock()
1709+
sig, err := signFn(accounts.Account{Address: val}, accounts.MimetypeParlia, ParliaRLP(header, p.chainConfig.ChainID))
1710+
if err != nil {
1711+
log.Error("Sign for the block header failed when sealing", "err", err)
1712+
return nil, err
1713+
}
1714+
copy(header.Extra[len(header.Extra)-extraSeal:], sig)
1715+
block = block.WithSeal(header)
1716+
return block, nil
1717+
}
1718+
17021719
// Seal implements consensus.Engine, attempting to create a sealed block using
17031720
// the local signing credentials.
17041721
func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {

core/blockchain.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,18 +2021,18 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
20212021

20222022
// WriteBlockAndSetHead writes the given block and all associated state to the database,
20232023
// and applies the block as the new chain head.
2024-
func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, sealedBlockSender *event.TypeMux) (status WriteStatus, err error) {
2024+
func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, sealedBlockSender *event.TypeMux, delayBroadcast bool) (status WriteStatus, err error) {
20252025
if !bc.chainmu.TryLock() {
20262026
return NonStatTy, errChainStopped
20272027
}
20282028
defer bc.chainmu.Unlock()
20292029

2030-
return bc.writeBlockAndSetHead(block, receipts, logs, state, sealedBlockSender)
2030+
return bc.writeBlockAndSetHead(block, receipts, logs, state, sealedBlockSender, delayBroadcast)
20312031
}
20322032

20332033
// writeBlockAndSetHead is the internal implementation of WriteBlockAndSetHead.
20342034
// This function expects the chain mutex to be held.
2035-
func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, sealedBlockSender *event.TypeMux) (status WriteStatus, err error) {
2035+
func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, sealedBlockSender *event.TypeMux, delayBroadcast bool) (status WriteStatus, err error) {
20362036
currentBlock := bc.CurrentBlock()
20372037
reorg, err := bc.forker.ReorgNeededWithFastFinality(currentBlock, block.Header())
20382038
if err != nil {
@@ -2041,7 +2041,7 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types
20412041
if reorg {
20422042
bc.highestVerifiedBlock.Store(types.CopyHeader(block.Header()))
20432043
bc.highestVerifiedBlockFeed.Send(HighestVerifiedBlockEvent{Header: block.Header()})
2044-
if sealedBlockSender != nil {
2044+
if sealedBlockSender != nil && !delayBroadcast {
20452045
// If the local DB is corrupted, writeBlockWithState may fail.
20462046
// It's fine — other nodes will persist the block.
20472047
//
@@ -2661,7 +2661,7 @@ func (bc *BlockChain) ProcessBlock(parentRoot common.Hash, block *types.Block, s
26612661
// Don't set the head, only insert the block
26622662
err = bc.writeBlockWithState(block, res.Receipts, statedb)
26632663
} else {
2664-
status, err = bc.writeBlockAndSetHead(block, res.Receipts, res.Logs, statedb, nil)
2664+
status, err = bc.writeBlockAndSetHead(block, res.Receipts, res.Logs, statedb, nil, false)
26652665
}
26662666
if err != nil {
26672667
return nil, err

core/types/block.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package types
2020
import (
2121
"crypto/sha256"
2222
"encoding/binary"
23+
"encoding/json"
2324
"fmt"
2425
"io"
2526
"math/big"
@@ -785,6 +786,14 @@ func (b *Block) WithWitness(witness *ExecutionWitness) *Block {
785786
}
786787
}
787788

789+
func (b *Block) DeepCopySidecars(sidecars BlobSidecars) {
790+
b.sidecars = make(BlobSidecars, len(sidecars))
791+
if len(sidecars) != 0 {
792+
buffer, _ := json.Marshal(sidecars)
793+
json.Unmarshal(buffer, &b.sidecars)
794+
}
795+
}
796+
788797
// Hash returns the keccak256 hash of b's header.
789798
// The hash is computed on the first call and cached thereafter.
790799
func (b *Block) Hash() common.Hash {

core/vote/vote_manager.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ var notContinuousJustified = metrics.NewRegisteredCounter("votesManager/notConti
3535
// Backend wraps all methods required for voting.
3636
type Backend interface {
3737
IsMining() bool
38+
VoteEnabled() bool
3839
EventMux() *event.TypeMux
3940
}
4041

@@ -140,6 +141,11 @@ func (voteManager *VoteManager) loop() {
140141
log.Debug("skip voting because mining is disabled, continue")
141142
continue
142143
}
144+
if !voteManager.eth.VoteEnabled() {
145+
log.Debug("skip voting because voting is disabled, continue")
146+
continue
147+
}
148+
143149
blockCountSinceMining++
144150
if blockCountSinceMining <= blocksNumberSinceMining {
145151
log.Debug("skip voting", "blockCountSinceMining", blockCountSinceMining, "blocksNumberSinceMining", blocksNumberSinceMining)

core/vote/vote_pool_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func newTestBackend() *testBackend {
7676
return &testBackend{eventMux: new(event.TypeMux)}
7777
}
7878
func (b *testBackend) IsMining() bool { return true }
79+
func (b *testBackend) VoteEnabled() bool { return true }
7980
func (b *testBackend) EventMux() *event.TypeMux { return b.eventMux }
8081

8182
func (mp *mockPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, headers []*types.Header) (uint64, common.Hash, error) {

eth/api_miner.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"math/big"
2121
"time"
2222

23+
"github.com/ethereum/go-ethereum/miner/minerconfig"
2324
"github.com/ethereum/go-ethereum/params"
2425

2526
"github.com/ethereum/go-ethereum/common"
@@ -117,3 +118,37 @@ func (api *MinerAPI) AddBuilder(builder common.Address, url string) error {
117118
func (api *MinerAPI) RemoveBuilder(builder common.Address) error {
118119
return api.e.APIBackend.RemoveBuilder(builder)
119120
}
121+
122+
func (api *MinerAPI) MBConfig() minerconfig.MBConfig {
123+
return api.e.Miner().MBConfig()
124+
}
125+
126+
func (api *MinerAPI) ResetMaliciousBehavior() minerconfig.MBConfig {
127+
api.e.Miner().ResetMaliciousBehavior()
128+
return api.e.Miner().MBConfig()
129+
}
130+
131+
func (api *MinerAPI) SetDoubleSign(on bool) minerconfig.MBConfig {
132+
api.e.Miner().SetDoubleSign(on)
133+
return api.e.Miner().MBConfig()
134+
}
135+
136+
func (api *MinerAPI) SetVoteDisable(on bool) minerconfig.MBConfig {
137+
api.e.Miner().SetVoteDisable(on)
138+
return api.e.Miner().MBConfig()
139+
}
140+
141+
func (api *MinerAPI) SetSkipOffsetInturn(offset uint64) minerconfig.MBConfig {
142+
api.e.Miner().SetSkipOffsetInturn(offset)
143+
return api.e.Miner().MBConfig()
144+
}
145+
146+
func (api *MinerAPI) SetBroadcastDelayBlocks(num uint64) minerconfig.MBConfig {
147+
api.e.Miner().SetBroadcastDelayBlocks(num)
148+
return api.e.Miner().MBConfig()
149+
}
150+
151+
func (api *MinerAPI) SetLastBlockMiningTime(time uint64) minerconfig.MBConfig {
152+
api.e.Miner().SetLastBlockMiningTime(time)
153+
return api.e.Miner().MBConfig()
154+
}

eth/backend.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,7 @@ func (s *Ethereum) StopMining() {
826826
}
827827

828828
func (s *Ethereum) IsMining() bool { return s.miner.Mining() }
829+
func (s *Ethereum) VoteEnabled() bool { return s.miner.VoteEnabled() }
829830
func (s *Ethereum) Miner() *miner.Miner { return s.miner }
830831

831832
func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager }

miner/miner.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ func (miner *Miner) Mining() bool {
170170
return miner.worker.isRunning()
171171
}
172172

173+
func (miner *Miner) VoteEnabled() bool {
174+
return miner.worker.config.VoteEnable && !miner.worker.config.MB.VoteDisable
175+
}
176+
173177
func (miner *Miner) InTurn() bool {
174178
return miner.worker.inTurn()
175179
}
@@ -227,6 +231,34 @@ func (miner *Miner) SetGasCeil(ceil uint64) {
227231
miner.worker.setGasCeil(ceil)
228232
}
229233

234+
func (miner *Miner) MBConfig() minerconfig.MBConfig {
235+
return miner.worker.config.MB
236+
}
237+
238+
func (miner *Miner) ResetMaliciousBehavior() {
239+
miner.worker.config.MB = minerconfig.DefaultMBConfig
240+
}
241+
242+
func (miner *Miner) SetDoubleSign(on bool) {
243+
miner.worker.config.MB.DoubleSign = on
244+
}
245+
246+
func (miner *Miner) SetVoteDisable(on bool) {
247+
miner.worker.config.MB.VoteDisable = on
248+
}
249+
250+
func (miner *Miner) SetSkipOffsetInturn(offset uint64) {
251+
miner.worker.config.MB.SkipOffsetInturn = &offset
252+
}
253+
254+
func (miner *Miner) SetBroadcastDelayBlocks(num uint64) {
255+
miner.worker.config.MB.BroadcastDelayBlocks = num
256+
}
257+
258+
func (miner *Miner) SetLastBlockMiningTime(time uint64) {
259+
miner.worker.config.MB.LastBlockMiningTime = time
260+
}
261+
230262
// BuildPayload builds the payload according to the provided parameters.
231263
func (miner *Miner) BuildPayload(args *BuildPayloadArgs, witness bool) (*Payload, error) {
232264
return miner.worker.buildPayload(args, witness)

miner/minerconfig/config.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ type Config struct {
7171
TxGasLimit uint64 // Maximum gas for per transaction
7272

7373
Mev MevConfig // Mev configuration
74+
MB MBConfig // Malicious behavior configuration
7475
}
7576

7677
// DefaultConfig contains default settings for miner.
@@ -89,6 +90,7 @@ var DefaultConfig = Config{
8990
MaxWaitProposalInSecs: &defaultMaxWaitProposalInSecs,
9091

9192
Mev: DefaultMevConfig,
93+
MB: DefaultMBConfig,
9294
}
9395

9496
type BuilderConfig struct {
@@ -170,3 +172,24 @@ func ApplyDefaultMinerConfig(cfg *Config) {
170172
log.Info("ApplyDefaultMinerConfig", "Mev.MaxBidsPerBuilder", *cfg.Mev.MaxBidsPerBuilder)
171173
}
172174
}
175+
176+
//go:generate go run github.com/fjl/gencodec -type MBConfig -formats toml -out gen_mb_config.go
177+
type MBConfig struct {
178+
// Generate two consecutive blocks for the same parent block
179+
DoubleSign bool
180+
// Disable voting for Fast Finality
181+
VoteDisable bool
182+
// Skip block production for in-turn validators at a specified offset
183+
SkipOffsetInturn *uint64 `toml:",omitempty"`
184+
// Delay broadcasting mined blocks by a specified number of blocks, only for in turn validators
185+
BroadcastDelayBlocks uint64
186+
// Mining time (milliseconds) for the last block in every turn
187+
LastBlockMiningTime uint64
188+
}
189+
190+
var DefaultMBConfig = MBConfig{
191+
DoubleSign: false,
192+
VoteDisable: false,
193+
BroadcastDelayBlocks: 0,
194+
LastBlockMiningTime: 0,
195+
}

0 commit comments

Comments
 (0)