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 7 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions cmd/geth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,6 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
params.FixedTurnLength = ctx.Uint64(utils.OverrideFixedTurnLength.Name)
}

// Start metrics export if enabled
utils.SetupMetrics(&cfg.Metrics)

backend, eth := utils.RegisterEthService(stack, &cfg.Eth)

// Create gauge with geth system and build information
Expand Down
25 changes: 22 additions & 3 deletions cmd/jsutils/getchainstatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const addrSlash = '0x0000000000000000000000000000000000001001';
const addrStakeHub = '0x0000000000000000000000000000000000002002';

const validatorSetAbi = [
"function validatorExtraSet(uint256 offset) external view returns (uint256, bool, bytes)",
"function getLivingValidators() external view returns (address[], bytes[])",
"function numOfCabinets() external view returns (uint256)",
"function maxNumOfCandidates() external view returns (uint256)",
Expand Down Expand Up @@ -277,6 +278,11 @@ async function getSlashCount() {
if (blockNum === 0) {
blockNum = await provider.getBlockNumber()
}
let slashScale = await validatorSet.maintainSlashScale({blockTag:blockNum})
let maxElected = await stakeHub.maxElectedValidators({blockTag:blockNum})
const maintainThreshold = BigInt(50) // governable, hardcode to avoid one RPC call
const felonyThreshold = BigInt(150) // governable, hardcode to avoid one RPC call

let block = await provider.getBlock(blockNum)
console.log("At block", blockNum, "time", block.date)
const data = await validatorSet.getLivingValidators({blockTag:blockNum})
Expand All @@ -285,9 +291,22 @@ async function getSlashCount() {
let addr = data[0][i];
var moniker = await getValidatorMoniker(addr, blockNum)
let info = await slashIndicator.getSlashIndicator(addr, {blockTag:blockNum})
let count = ethers.toNumber(info[1])
totalSlash += count
console.log("Slash:", count, addr, moniker)
let slashHeight = ethers.toNumber(info[0])
let slashCount = ethers.toNumber(info[1])
totalSlash += slashCount
console.log("Slash:", slashCount, addr, moniker, slashHeight)
if (slashCount >= maintainThreshold) {
let validatorExtra = await validatorSet.validatorExtraSet(i, {blockTag:blockNum})
let enterMaintenanceHeight = validatorExtra[0]
let isMaintaining = validatorExtra[1]
// let voteAddress = validatorExtra[2]
if (isMaintaining) {
let jailHeight = (felonyThreshold - slashCount) * slashScale * maxElected + BigInt(enterMaintenanceHeight)
console.log(" in maintenance mode since", enterMaintenanceHeight, "will jail after", ethers.toNumber(jailHeight))
} else {
console.log(" exited maintenance mode")
}
}
}
console.log("Total slash count", totalSlash)
};
Expand Down
8 changes: 4 additions & 4 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -2332,7 +2332,7 @@ type SetupMetricsOption func()
func EnableBuildInfo(gitCommit, gitDate string) SetupMetricsOption {
return func() {
// register build info into metrics
metrics.NewRegisteredLabel("build-info", nil).Mark(map[string]interface{}{
metrics.GetOrRegisterLabel("build-info", nil).Mark(map[string]interface{}{
"version": version.WithMeta,
"git-commit": gitCommit,
"git-commit-date": gitDate,
Expand All @@ -2349,7 +2349,7 @@ func EnableMinerInfo(ctx *cli.Context, minerConfig *minerconfig.Config) SetupMet
// register miner info into metrics
minerInfo := structs.Map(minerConfig)
minerInfo[UnlockedAccountFlag.Name] = ctx.String(UnlockedAccountFlag.Name)
metrics.NewRegisteredLabel("miner-info", nil).Mark(minerInfo)
metrics.GetOrRegisterLabel("miner-info", nil).Mark(minerInfo)
}
}
}
Expand All @@ -2369,7 +2369,7 @@ func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconf
func EnableNodeInfo(poolConfig *legacypool.Config, nodeInfo *p2p.NodeInfo) SetupMetricsOption {
return func() {
// register node info into metrics
metrics.NewRegisteredLabel("node-info", nil).Mark(map[string]interface{}{
metrics.GetOrRegisterLabel("node-info", nil).Mark(map[string]interface{}{
"Enode": nodeInfo.Enode,
"ENR": nodeInfo.ENR,
"ID": nodeInfo.ID,
Expand All @@ -2389,7 +2389,7 @@ func EnableNodeTrack(ctx *cli.Context, cfg *ethconfig.Config, stack *node.Node)
nodeInfo := stack.Server().NodeInfo()
return func() {
// register node info into metrics
metrics.NewRegisteredLabel("node-stats", nil).Mark(map[string]interface{}{
metrics.GetOrRegisterLabel("node-stats", nil).Mark(map[string]interface{}{
"NodeType": parseNodeType(),
"ENR": nodeInfo.ENR,
"Mining": ctx.Bool(MiningEnabledFlag.Name),
Expand Down
23 changes: 22 additions & 1 deletion consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
prague := chain.Config().IsPrague(header.Number, header.Time)
if !prague {
if header.RequestsHash != nil {
return fmt.Errorf("invalid RequestsHash, have %#x, expected nil", header.ParentBeaconRoot)
return fmt.Errorf("invalid RequestsHash, have %#x, expected nil", header.RequestsHash)
}
} else {
if header.RequestsHash == nil {
Expand Down Expand Up @@ -1559,6 +1559,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 @@ -2118,6 +2135,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
10 changes: 9 additions & 1 deletion core/txpool/legacypool/legacypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,9 @@ func New(config Config, chain BlockChain) *LegacyPool {
// pool, specifically, whether it is a Legacy, AccessList or Dynamic transaction.
func (pool *LegacyPool) Filter(tx *types.Transaction) bool {
switch tx.Type() {
case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType:
// TODO(Nathan): add SetCodeTxType into LegacyPool for test
// finally will rollback and be consistent with upstream
case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType, types.SetCodeTxType:
return true
default:
return false
Expand Down Expand Up @@ -692,6 +694,12 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) erro
MinTip: pool.gasTip.Load().ToBig(),
MaxGas: pool.GetMaxGas(),
}
// TODO(Nathan): ensure before prague, no SetCodeTxType will be accepted and propagated
// finally will rollback and be consistent with upstream
currentBlock := pool.chain.CurrentBlock()
if pool.chainconfig.IsPrague(currentBlock.Number, currentBlock.Time) {
opts.Accept |= 1 << types.SetCodeTxType
}
if local {
opts.MinTip = new(big.Int)
}
Expand Down
9 changes: 9 additions & 0 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package types
import (
"crypto/sha256"
"encoding/binary"
"encoding/json"
"fmt"
"io"
"math/big"
Expand Down Expand Up @@ -604,6 +605,14 @@ func (b *Block) WithWitness(witness *ExecutionWitness) *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
17 changes: 7 additions & 10 deletions core/vote/vote_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"fmt"
"math/big"
"sync"
"time"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -31,6 +30,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 @@ -71,6 +71,7 @@ func NewVoteManager(eth Backend, chain *core.BlockChain, pool *VotePool, journal
}
log.Info("Create voteSigner successfully")
voteManager.signer = voteSigner
metrics.GetOrRegisterLabel("miner-info", nil).Mark(map[string]interface{}{"VoteKey": common.Bytes2Hex(voteManager.signer.PubKey[:])})

// Create voteJournal
voteJournal, err := NewVoteJournal(journalPath)
Expand Down Expand Up @@ -107,7 +108,6 @@ func (voteManager *VoteManager) loop() {

startVote := true
blockCountSinceMining := 0
var once sync.Once
for {
select {
case ev := <-dlEventCh:
Expand Down Expand Up @@ -136,6 +136,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 Expand Up @@ -166,14 +171,6 @@ func (voteManager *VoteManager) loop() {
continue
}

// Add VoteKey to `miner-info`
once.Do(func() {
minerInfo := metrics.Get("miner-info")
if minerInfo != nil {
minerInfo.(metrics.Label).Value()["VoteKey"] = common.Bytes2Hex(voteManager.signer.PubKey[:])
}
})

// Vote for curBlockHeader block.
vote := &types.VoteData{
TargetNumber: curHead.Number.Uint64(),
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 (mp *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/minerconfig"
"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() minerconfig.MBConfig {
return api.e.Miner().MBConfig()
}

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

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

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

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

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

func (api *MinerAPI) SetLastBlockMiningTime(time uint64) minerconfig.MBConfig {
api.e.Miner().SetLastBlockMiningTime(time)
return api.e.Miner().MBConfig()
}
58 changes: 27 additions & 31 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ import (
"github.com/ethereum/go-ethereum/internal/shutdowncheck"
"github.com/ethereum/go-ethereum/internal/version"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
Expand Down Expand Up @@ -178,6 +177,32 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
if err != nil {
return nil, err
}
// Override the chain config with provided settings.
var overrides core.ChainOverrides
if config.OverridePassedForkTime != nil {
chainConfig.ShanghaiTime = config.OverridePassedForkTime
chainConfig.KeplerTime = config.OverridePassedForkTime
chainConfig.FeynmanTime = config.OverridePassedForkTime
chainConfig.FeynmanFixTime = config.OverridePassedForkTime
chainConfig.CancunTime = config.OverridePassedForkTime
chainConfig.HaberTime = config.OverridePassedForkTime
chainConfig.HaberFixTime = config.OverridePassedForkTime
chainConfig.BohrTime = config.OverridePassedForkTime
overrides.OverridePassedForkTime = config.OverridePassedForkTime
}
if config.OverridePascal != nil {
chainConfig.PascalTime = config.OverridePascal
overrides.OverridePascal = config.OverridePascal
}
if config.OverridePrague != nil {
chainConfig.PragueTime = config.OverridePrague
overrides.OverridePrague = config.OverridePrague
}
if config.OverrideVerkle != nil {
chainConfig.VerkleTime = config.OverrideVerkle
overrides.OverrideVerkle = config.OverrideVerkle
}

// startup ancient freeze
freezeDb := chainDb
if stack.CheckIfMultiDataBase() {
Expand Down Expand Up @@ -279,31 +304,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
}
vmConfig.Tracer = t
}
// Override the chain config with provided settings.
var overrides core.ChainOverrides
if config.OverridePassedForkTime != nil {
chainConfig.ShanghaiTime = config.OverridePassedForkTime
chainConfig.KeplerTime = config.OverridePassedForkTime
chainConfig.FeynmanTime = config.OverridePassedForkTime
chainConfig.FeynmanFixTime = config.OverridePassedForkTime
chainConfig.CancunTime = config.OverridePassedForkTime
chainConfig.HaberTime = config.OverridePassedForkTime
chainConfig.HaberFixTime = config.OverridePassedForkTime
chainConfig.BohrTime = config.OverridePassedForkTime
overrides.OverridePassedForkTime = config.OverridePassedForkTime
}
if config.OverridePascal != nil {
chainConfig.PascalTime = config.OverridePascal
overrides.OverridePascal = config.OverridePascal
}
if config.OverridePrague != nil {
chainConfig.PragueTime = config.OverridePrague
overrides.OverridePrague = config.OverridePrague
}
if config.OverrideVerkle != nil {
chainConfig.VerkleTime = config.OverrideVerkle
overrides.OverrideVerkle = config.OverrideVerkle
}

bcOps := make([]core.BlockChainOption, 0)
if config.PersistDiff {
Expand Down Expand Up @@ -510,11 +510,6 @@ func (s *Ethereum) StartMining() error {
return fmt.Errorf("signer missing: %v", err)
}
parlia.Authorize(eb, wallet.SignData, wallet.SignTx)

minerInfo := metrics.Get("miner-info")
if minerInfo != nil {
minerInfo.(metrics.Label).Value()["Etherbase"] = eb.String()
}
}
// If mining is started, we can disable the transaction rejection mechanism
// introduced to speed sync times.
Expand All @@ -540,6 +535,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
Loading
Loading