Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Malicious behavior miner #132

Draft
wants to merge 11 commits into
base: develop
Choose a base branch
from
21 changes: 21 additions & 0 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -1549,6 +1549,23 @@ func (p *Parlia) Delay(chain consensus.ChainReader, header *types.Header, leftOv
return &delay
}

// AssembleSignature assemble the signature for block header
func (p *Parlia) AssembleSignature(block *types.Block) (*types.Block, error) {
header := block.Header()
// Don't hold the val fields for the entire sealing procedure
p.lock.RLock()
val, signFn := p.val, p.signFn
p.lock.RUnlock()
sig, err := signFn(accounts.Account{Address: val}, accounts.MimetypeParlia, ParliaRLP(header, p.chainConfig.ChainID))
if err != nil {
log.Error("Sign for the block header failed when sealing", "err", err)
return nil, err
}
copy(header.Extra[len(header.Extra)-extraSeal:], sig)
block = block.WithSeal(header)
return block, nil
}

// Seal implements consensus.Engine, attempting to create a sealed block using
// the local signing credentials.
func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
Expand Down Expand Up @@ -2110,6 +2127,10 @@ func (p *Parlia) backOffTime(snap *Snapshot, header *types.Header, val common.Ad
backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i]
})

for i := uint64(0); i < uint64(n); i++ {
log.Debug("backOffTime", "Number", header.Number, "val", validators[i], "delay", delay+backOffSteps[i]*wiggleTime)
}

delay += backOffSteps[idx] * wiggleTime
return delay
}
Expand Down
9 changes: 9 additions & 0 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package types

import (
"encoding/binary"
"encoding/json"
"fmt"
"io"
"math/big"
Expand Down Expand Up @@ -551,6 +552,14 @@ func (b *Block) WithSidecars(sidecars BlobSidecars) *Block {
return block
}

func (b *Block) DeepCopySidecars(sidecars BlobSidecars) {
b.sidecars = make(BlobSidecars, len(sidecars))
if len(sidecars) != 0 {
buffer, _ := json.Marshal(sidecars)
json.Unmarshal(buffer, &b.sidecars)
}
}

// Hash returns the keccak256 hash of b's header.
// The hash is computed on the first call and cached thereafter.
func (b *Block) Hash() common.Hash {
Expand Down
6 changes: 6 additions & 0 deletions core/vote/vote_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var notContinuousJustified = metrics.NewRegisteredCounter("votesManager/notConti
// Backend wraps all methods required for voting.
type Backend interface {
IsMining() bool
VoteEnabled() bool
EventMux() *event.TypeMux
}

Expand Down Expand Up @@ -136,6 +137,11 @@ func (voteManager *VoteManager) loop() {
log.Debug("skip voting because mining is disabled, continue")
continue
}
if !voteManager.eth.VoteEnabled() {
log.Debug("skip voting because voting is disabled, continue")
continue
}

blockCountSinceMining++
if blockCountSinceMining <= blocksNumberSinceMining {
log.Debug("skip voting", "blockCountSinceMining", blockCountSinceMining, "blocksNumberSinceMining", blocksNumberSinceMining)
Expand Down
1 change: 1 addition & 0 deletions core/vote/vote_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func newTestBackend() *testBackend {
return &testBackend{eventMux: new(event.TypeMux)}
}
func (b *testBackend) IsMining() bool { return true }
func (b *testBackend) VoteEnabled() bool { return true }
func (b *testBackend) EventMux() *event.TypeMux { return b.eventMux }

func (p *mockPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, headers []*types.Header) (uint64, common.Hash, error) {
Expand Down
35 changes: 35 additions & 0 deletions eth/api_miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"math/big"
"time"

"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/params"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -117,3 +118,37 @@ func (api *MinerAPI) AddBuilder(builder common.Address, url string) error {
func (api *MinerAPI) RemoveBuilder(builder common.Address) error {
return api.e.APIBackend.RemoveBuilder(builder)
}

func (api *MinerAPI) MBConfig() miner.MBConfig {
return api.e.Miner().MBConfig()
}

func (api *MinerAPI) ResetMaliciousBehavior() miner.MBConfig {
api.e.Miner().ResetMaliciousBehavior()
return api.e.Miner().MBConfig()
}

func (api *MinerAPI) SetDoubleSign(on bool) miner.MBConfig {
api.e.Miner().SetDoubleSign(on)
return api.e.Miner().MBConfig()
}

func (api *MinerAPI) SetVoteDisable(on bool) miner.MBConfig {
api.e.Miner().SetVoteDisable(on)
return api.e.Miner().MBConfig()
}

func (api *MinerAPI) SetSkipOffsetInturn(offset uint64) miner.MBConfig {
api.e.Miner().SetSkipOffsetInturn(offset)
return api.e.Miner().MBConfig()
}

func (api *MinerAPI) SetBroadcastDelayBlocks(num uint64) miner.MBConfig {
api.e.Miner().SetBroadcastDelayBlocks(num)
return api.e.Miner().MBConfig()
}

func (api *MinerAPI) SetLastBlockMiningTime(time uint64) miner.MBConfig {
api.e.Miner().SetLastBlockMiningTime(time)
return api.e.Miner().MBConfig()
}
1 change: 1 addition & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ func (s *Ethereum) StopMining() {
}

func (s *Ethereum) IsMining() bool { return s.miner.Mining() }
func (s *Ethereum) VoteEnabled() bool { return s.miner.VoteEnabled() }
func (s *Ethereum) Miner() *miner.Miner { return s.miner }

func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager }
Expand Down
52 changes: 52 additions & 0 deletions miner/gen_mb_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions miner/malicious_behaviour.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package miner

//go:generate go run github.com/fjl/gencodec -type MBConfig -formats toml -out gen_mb_config.go
type MBConfig struct {
// Generate two consecutive blocks for the same parent block
DoubleSign bool
// Disable voting for Fast Finality
VoteDisable bool
// Skip block production for in-turn validators at a specified offset
SkipOffsetInturn *uint64 `toml:",omitempty"`
// Delay broadcasting mined blocks by a specified number of blocks, only for in turn validators
BroadcastDelayBlocks uint64
// Mining time (milliseconds) for the last block in every turn
LastBlockMiningTime uint64
}

var DefaultMBConfig = MBConfig{
DoubleSign: false,
VoteDisable: false,
BroadcastDelayBlocks: 0,
LastBlockMiningTime: 0,
}
34 changes: 34 additions & 0 deletions miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type Config struct {
DisableVoteAttestation bool // Whether to skip assembling vote attestation

Mev MevConfig // Mev configuration
MB MBConfig // Malicious behavior configuration
}

// DefaultConfig contains default settings for miner.
Expand All @@ -74,6 +75,7 @@ var DefaultConfig = Config{
DelayLeftOver: 50 * time.Millisecond,

Mev: DefaultMevConfig,
MB: DefaultMBConfig,
}

// Miner creates blocks and searches for proof-of-work values.
Expand Down Expand Up @@ -202,6 +204,10 @@ func (miner *Miner) Mining() bool {
return miner.worker.isRunning()
}

func (miner *Miner) VoteEnabled() bool {
return miner.worker.config.VoteEnable && !miner.worker.config.MB.VoteDisable
}

func (miner *Miner) InTurn() bool {
return miner.worker.inTurn()
}
Expand Down Expand Up @@ -285,6 +291,34 @@ func (miner *Miner) SetGasCeil(ceil uint64) {
miner.worker.setGasCeil(ceil)
}

func (miner *Miner) MBConfig() MBConfig {
return miner.worker.config.MB
}

func (miner *Miner) ResetMaliciousBehavior() {
miner.worker.config.MB = DefaultMBConfig
}

func (miner *Miner) SetDoubleSign(on bool) {
miner.worker.config.MB.DoubleSign = on
}

func (miner *Miner) SetVoteDisable(on bool) {
miner.worker.config.MB.VoteDisable = on
}

func (miner *Miner) SetSkipOffsetInturn(offset uint64) {
miner.worker.config.MB.SkipOffsetInturn = &offset
}

func (miner *Miner) SetBroadcastDelayBlocks(num uint64) {
miner.worker.config.MB.BroadcastDelayBlocks = num
}

func (miner *Miner) SetLastBlockMiningTime(time uint64) {
miner.worker.config.MB.LastBlockMiningTime = time
}

// SubscribePendingLogs starts delivering logs from pending transactions
// to the given channel.
func (miner *Miner) SubscribePendingLogs(ch chan<- []*types.Log) event.Subscription {
Expand Down
Loading
Loading