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

parlia: consensus changes for Early broadcast #1268

Merged
merged 1 commit into from
Feb 28, 2023
Merged
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
4 changes: 4 additions & 0 deletions consensus/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ var (
// to the current node.
ErrFutureBlock = errors.New("block in the future")

// ErrFutureParentBlock is returned when a block's parent's timestamp is in the future
// according to the current node.
ErrFutureParentBlock = errors.New("parent block in the future")

// ErrInvalidNumber is returned if a block's number doesn't equal its parent's
// plus one.
ErrInvalidNumber = errors.New("invalid block number")
Expand Down
21 changes: 19 additions & 2 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,26 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
}
number := header.Number.Uint64()

// Don't waste time checking blocks from the future
// According to BEP188, after Bohr fork, an in-turn validator is allowed to broadcast
// a mined block earlier but not earlier than its parent's timestamp when the block is ready .
if header.Time > uint64(time.Now().Unix()) {
return consensus.ErrFutureBlock
if !chain.Config().IsBohr(header.Number) || header.Difficulty.Cmp(diffInTurn) != 0 {
return consensus.ErrFutureBlock
}
var parent *types.Header
if len(parents) > 0 {
parent = parents[len(parents)-1]
} else {
parent = chain.GetHeader(header.ParentHash, number-1)
}

if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
return consensus.ErrUnknownAncestor
}

if parent.Time > uint64(time.Now().Unix()) {
return consensus.ErrFutureParentBlock
}
unclezoro marked this conversation as resolved.
Show resolved Hide resolved
}
// Check that the extra-data contains the vanity, validators and signature.
if len(header.Extra) < extraVanity {
Expand Down
27 changes: 23 additions & 4 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ var (
NanoBlock: big.NewInt(21962149),
MoranBlock: big.NewInt(22107423),
GibbsBlock: big.NewInt(23846001),
BohrBlock: nil, // todo: TBD

Parlia: &ParliaConfig{
Period: 3,
Expand All @@ -325,6 +326,7 @@ var (
GibbsBlock: big.NewInt(22800220),
NanoBlock: big.NewInt(23482428),
MoranBlock: big.NewInt(23603940),
BohrBlock: nil, // todo: TBD
Parlia: &ParliaConfig{
Period: 3,
Epoch: 200,
Expand All @@ -350,6 +352,7 @@ var (
GibbsBlock: big.NewInt(400),
NanoBlock: nil,
MoranBlock: nil,
BohrBlock: nil,

Parlia: &ParliaConfig{
Period: 3,
Expand Down Expand Up @@ -378,6 +381,7 @@ var (
GibbsBlock: big.NewInt(0),
NanoBlock: nil,
MoranBlock: nil,
BohrBlock: nil,
MuirGlacierBlock: nil,
BerlinBlock: nil, // Don't enable Berlin directly, we're YOLOing it
YoloV3Block: big.NewInt(0),
Expand All @@ -392,16 +396,16 @@ var (
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil}
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil}

// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Clique consensus.
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}

TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil}
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil}
TestRules = TestChainConfig.Rules(new(big.Int), false)
)

Expand Down Expand Up @@ -497,6 +501,7 @@ type ChainConfig struct {
GibbsBlock *big.Int `json:"gibbsBlock,omitempty" toml:",omitempty"` // gibbsBlock switch block (nil = no fork, 0 = already activated)
NanoBlock *big.Int `json:"nanoBlock,omitempty" toml:",omitempty"` // nanoBlock switch block (nil = no fork, 0 = already activated)
MoranBlock *big.Int `json:"moranBlock,omitempty" toml:",omitempty"` // moranBlock switch block (nil = no fork, 0 = already activated)
BohrBlock *big.Int `json:"bohrBlock,omitempty" toml:",omitempty"` // bohrBlock switch block (nil = no fork, 0 = already activated)

// Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"`
Expand Down Expand Up @@ -547,7 +552,7 @@ func (c *ChainConfig) String() string {
default:
engine = "unknown"
}
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Engine: %v}",
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Bohr: %v, Engine: %v}",
c.ChainID,
c.HomesteadBlock,
c.DAOForkBlock,
Expand All @@ -574,6 +579,7 @@ func (c *ChainConfig) String() string {
c.GibbsBlock,
c.NanoBlock,
c.MoranBlock,
c.BohrBlock,
engine,
)
}
Expand Down Expand Up @@ -729,6 +735,14 @@ func (c *ChainConfig) IsOnMoran(num *big.Int) bool {
return configNumEqual(c.MoranBlock, num)
}

func (c *ChainConfig) IsBohr(num *big.Int) bool {
return isForked(c.BohrBlock, num)
}

func (c *ChainConfig) IsOnBohr(num *big.Int) bool {
return configNumEqual(c.BohrBlock, num)
}

// CheckCompatible checks whether scheduled fork transitions have been imported
// with a mismatching chain configuration.
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
Expand Down Expand Up @@ -857,6 +871,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
if isForkIncompatible(c.MoranBlock, newcfg.MoranBlock, head) {
return newCompatError("moran fork block", c.MoranBlock, newcfg.MoranBlock)
}
if isForkIncompatible(c.BohrBlock, newcfg.BohrBlock, head) {
return newCompatError("bohr fork block", c.BohrBlock, newcfg.BohrBlock)
}
return nil
}

Expand Down Expand Up @@ -928,6 +945,7 @@ type Rules struct {
IsMerge bool
IsNano bool
IsMoran bool
IsBohr bool
}

// Rules ensures c's ChainID is not nil.
Expand All @@ -951,5 +969,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool) Rules {
IsMerge: isMerge,
IsNano: c.IsNano(num),
IsMoran: c.IsMoran(num),
IsBohr: c.IsBohr(num),
}
}