Skip to content

Commit

Permalink
parlia: consensus changes according to BEP of Early Broadcast (bnb-ch…
Browse files Browse the repository at this point in the history
  • Loading branch information
kyrie-yl authored Feb 28, 2023
1 parent 13fdb9b commit f5cb137
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
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
}
}
// 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),
}
}

0 comments on commit f5cb137

Please sign in to comment.