@@ -3,6 +3,7 @@ package parlia
33import (
44 "bytes"
55 "context"
6+ "encoding/hex"
67 "errors"
78 "fmt"
89 "io"
@@ -25,6 +26,7 @@ import (
2526 "github.com/ethereum/go-ethereum/consensus"
2627 "github.com/ethereum/go-ethereum/consensus/misc"
2728 "github.com/ethereum/go-ethereum/core"
29+ "github.com/ethereum/go-ethereum/core/forkid"
2830 "github.com/ethereum/go-ethereum/core/state"
2931 "github.com/ethereum/go-ethereum/core/systemcontracts"
3032 "github.com/ethereum/go-ethereum/core/types"
@@ -45,8 +47,9 @@ const (
4547 checkpointInterval = 1024 // Number of blocks after which to save the snapshot to the database
4648 defaultEpochLength = uint64 (100 ) // Default number of blocks of checkpoint to update validatorSet from contract
4749
48- extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
49- extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
50+ extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
51+ extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
52+ nextForkHashSize = 4 // Fixed number of extra-data suffix bytes reserved for nextForkHash.
5053
5154 validatorBytesLength = common .AddressLength
5255 wiggleTime = uint64 (1 ) // second, Random delay (per signer) to allow concurrent signers
@@ -188,7 +191,8 @@ func ParliaRLP(header *types.Header, chainId *big.Int) []byte {
188191type Parlia struct {
189192 chainConfig * params.ChainConfig // Chain config
190193 config * params.ParliaConfig // Consensus engine configuration parameters for parlia consensus
191- db ethdb.Database // Database to store and retrieve snapshot checkpoints
194+ genesisHash common.Hash
195+ db ethdb.Database // Database to store and retrieve snapshot checkpoints
192196
193197 recentSnaps * lru.ARCCache // Snapshots for recent block to speed up
194198 signatures * lru.ARCCache // Signatures of recent blocks to speed up mining
@@ -214,6 +218,7 @@ func New(
214218 chainConfig * params.ChainConfig ,
215219 db ethdb.Database ,
216220 ethAPI * ethapi.PublicBlockChainAPI ,
221+ genesisHash common.Hash ,
217222) * Parlia {
218223 // get parlia config
219224 parliaConfig := chainConfig .Parlia
@@ -243,6 +248,7 @@ func New(
243248 c := & Parlia {
244249 chainConfig : chainConfig ,
245250 config : parliaConfig ,
251+ genesisHash : genesisHash ,
246252 db : db ,
247253 ethAPI : ethAPI ,
248254 recentSnaps : recentSnaps ,
@@ -599,10 +605,12 @@ func (p *Parlia) Prepare(chain consensus.ChainReader, header *types.Header) erro
599605 header .Difficulty = CalcDifficulty (snap , p .val )
600606
601607 // Ensure the extra data has all it's components
602- if len (header .Extra ) < extraVanity {
603- header .Extra = append (header .Extra , bytes .Repeat ([]byte {0x00 }, extraVanity - len (header .Extra ))... )
608+ if len (header .Extra ) < extraVanity - nextForkHashSize {
609+ header .Extra = append (header .Extra , bytes .Repeat ([]byte {0x00 }, extraVanity - nextForkHashSize - len (header .Extra ))... )
604610 }
605- header .Extra = header .Extra [:extraVanity ]
611+ header .Extra = header .Extra [:extraVanity - nextForkHashSize ]
612+ nextForkHash := forkid .NextForkHash (p .chainConfig , p .genesisHash , number )
613+ header .Extra = append (header .Extra , nextForkHash [:]... )
606614
607615 if number % p .config .Epoch == 0 {
608616 newValidators , err := p .getCurrentValidators (header .ParentHash )
@@ -638,6 +646,16 @@ func (p *Parlia) Prepare(chain consensus.ChainReader, header *types.Header) erro
638646// rewards given.
639647func (p * Parlia ) Finalize (chain consensus.ChainReader , header * types.Header , state * state.StateDB , txs * []* types.Transaction ,
640648 uncles []* types.Header , receipts * []* types.Receipt , systemTxs * []* types.Transaction , usedGas * uint64 ) error {
649+ // warn if not in majority fork
650+ number := header .Number .Uint64 ()
651+ snap , err := p .snapshot (chain , number - 1 , header .ParentHash , nil )
652+ if err != nil {
653+ panic (err )
654+ }
655+ nextForkHash := forkid .NextForkHash (p .chainConfig , p .genesisHash , number )
656+ if ! snap .isMajorityFork (hex .EncodeToString (nextForkHash [:])) {
657+ log .Warn ("there is a possible fork, and your client is not the majority. Please check..." , "nextForkHash" , hex .EncodeToString (nextForkHash [:]))
658+ }
641659 // If the block is a epoch end block, verify the validator list
642660 // The verification can only be done when the state is ready, it can't be done in VerifyHeader.
643661 if header .Number .Uint64 ()% p .config .Epoch == 0 {
@@ -666,11 +684,6 @@ func (p *Parlia) Finalize(chain consensus.ChainReader, header *types.Header, sta
666684 }
667685 }
668686 if header .Difficulty .Cmp (diffInTurn ) != 0 {
669- number := header .Number .Uint64 ()
670- snap , err := p .snapshot (chain , number - 1 , header .ParentHash , nil )
671- if err != nil {
672- panic (err )
673- }
674687 spoiledVal := snap .supposeValidator ()
675688 signedRecently := false
676689 for _ , recent := range snap .Recents {
@@ -689,7 +702,7 @@ func (p *Parlia) Finalize(chain consensus.ChainReader, header *types.Header, sta
689702 }
690703 }
691704 val := header .Coinbase
692- err : = p .distributeIncoming (val , state , header , cx , txs , receipts , systemTxs , usedGas , false )
705+ err = p .distributeIncoming (val , state , header , cx , txs , receipts , systemTxs , usedGas , false )
693706 if err != nil {
694707 panic (err )
695708 }
0 commit comments