@@ -26,6 +26,7 @@ import (
2626 "github.com/ethereum/go-ethereum/consensus/misc"
2727 "github.com/ethereum/go-ethereum/core"
2828 "github.com/ethereum/go-ethereum/core/state"
29+ "github.com/ethereum/go-ethereum/core/systemcontracts"
2930 "github.com/ethereum/go-ethereum/core/types"
3031 "github.com/ethereum/go-ethereum/core/vm"
3132 "github.com/ethereum/go-ethereum/crypto"
@@ -48,21 +49,11 @@ const (
4849 extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
4950
5051 validatorBytesLength = common .AddressLength
51- wiggleTime = 500 * time . Millisecond // Random delay (per signer) to allow concurrent signers
52- fixedBackOffTime = 200 * time . Millisecond
52+ wiggleTime = uint64 ( 1 ) // second, Random delay (per signer) to allow concurrent signers
53+ initialBackOffTime = uint64 ( 1 ) // second
5354
5455 systemRewardPercent = 4 // it means 1/2^4 = 1/16 percentage of gas fee incoming will be distributed to system
5556
56- // genesis contracts
57- ValidatorContract = "0x0000000000000000000000000000000000001000"
58- SlashContract = "0x0000000000000000000000000000000000001001"
59- SystemRewardContract = "0x0000000000000000000000000000000000001002"
60- LightClientContract = "0x0000000000000000000000000000000000001003"
61- TokenHubContract = "0x0000000000000000000000000000000000001004"
62- RelayerIncentivizeContract = "0x0000000000000000000000000000000000001005"
63- RelayerHubContract = "0x0000000000000000000000000000000000001006"
64- GovHubContract = "0x0000000000000000000000000000000000001007"
65- CrossChainContract = "0x0000000000000000000000000000000000002000"
6657)
6758
6859var (
@@ -73,15 +64,15 @@ var (
7364 maxSystemBalance = new (big.Int ).Mul (big .NewInt (100 ), big .NewInt (params .Ether ))
7465
7566 systemContracts = map [common.Address ]bool {
76- common .HexToAddress (ValidatorContract ): true ,
77- common .HexToAddress (SlashContract ): true ,
78- common .HexToAddress (SystemRewardContract ): true ,
79- common .HexToAddress (LightClientContract ): true ,
80- common .HexToAddress (RelayerHubContract ): true ,
81- common .HexToAddress (GovHubContract ): true ,
82- common .HexToAddress (TokenHubContract ): true ,
83- common .HexToAddress (RelayerIncentivizeContract ): true ,
84- common .HexToAddress (CrossChainContract ): true ,
67+ common .HexToAddress (systemcontracts . ValidatorContract ): true ,
68+ common .HexToAddress (systemcontracts . SlashContract ): true ,
69+ common .HexToAddress (systemcontracts . SystemRewardContract ): true ,
70+ common .HexToAddress (systemcontracts . LightClientContract ): true ,
71+ common .HexToAddress (systemcontracts . RelayerHubContract ): true ,
72+ common .HexToAddress (systemcontracts . GovHubContract ): true ,
73+ common .HexToAddress (systemcontracts . TokenHubContract ): true ,
74+ common .HexToAddress (systemcontracts . RelayerIncentivizeContract ): true ,
75+ common .HexToAddress (systemcontracts . CrossChainContract ): true ,
8576 }
8677)
8778
@@ -395,10 +386,20 @@ func (p *Parlia) verifyCascadingFields(chain consensus.ChainReader, header *type
395386 return consensus .ErrUnknownAncestor
396387 }
397388
389+ snap , err := p .snapshot (chain , number - 1 , header .ParentHash , parents )
390+ if err != nil {
391+ return err
392+ }
393+
394+ err = p .blockTimeVerifyForRamanujanFork (snap , header , parent )
395+ if err != nil {
396+ return err
397+ }
398+
398399 // Verify that the gas limit is <= 2^63-1
399- cap := uint64 (0x7fffffffffffffff )
400- if header .GasLimit > cap {
401- return fmt .Errorf ("invalid gasLimit: have %v, max %v" , header .GasLimit , cap )
400+ capacity := uint64 (0x7fffffffffffffff )
401+ if header .GasLimit > capacity {
402+ return fmt .Errorf ("invalid gasLimit: have %v, max %v" , header .GasLimit , capacity )
402403 }
403404 // Verify that the gasUsed is <= gasLimit
404405 if header .GasUsed > header .GasLimit {
@@ -570,7 +571,7 @@ func (p *Parlia) verifySeal(chain consensus.ChainReader, header *types.Header, p
570571
571572 // Ensure that the difficulty corresponds to the turn-ness of the signer
572573 if ! p .fakeDiff {
573- inturn := snap .inturn (header . Number . Uint64 (), signer )
574+ inturn := snap .inturn (signer )
574575 if inturn && header .Difficulty .Cmp (diffInTurn ) != 0 {
575576 return errWrongDifficulty
576577 }
@@ -626,8 +627,7 @@ func (p *Parlia) Prepare(chain consensus.ChainReader, header *types.Header) erro
626627 if parent == nil {
627628 return consensus .ErrUnknownAncestor
628629 }
629-
630- header .Time = parent .Time + p .config .Period
630+ header .Time = p .blockTimeForRamanujanFork (snap , header , parent )
631631 if header .Time < uint64 (time .Now ().Unix ()) {
632632 header .Time = uint64 (time .Now ().Unix ())
633633 }
@@ -809,14 +809,7 @@ func (p *Parlia) Seal(chain consensus.ChainReader, block *types.Block, results c
809809 }
810810
811811 // Sweet, the protocol permits us to sign the block, wait for our time
812- delay := time .Unix (int64 (header .Time ), 0 ).Sub (time .Now ()) // nolint: gosimple
813- if header .Difficulty .Cmp (diffNoTurn ) == 0 {
814- // It's not our turn explicitly to sign, delay it a bit
815- wiggle := time .Duration (len (snap .Validators )/ 2 + 1 ) * wiggleTime
816- delay += time .Duration (fixedBackOffTime ) + time .Duration (rand .Int63n (int64 (wiggle )))
817-
818- log .Trace ("Out-of-turn signing requested" , "wiggle" , common .PrettyDuration (wiggle ))
819- }
812+ delay := p .delayForRamanujanFork (snap , header )
820813
821814 log .Info ("Sealing block with" , "number" , number , "delay" , delay , "headerDifficulty" , header .Difficulty , "val" , val .Hex ())
822815
@@ -861,7 +854,7 @@ func (p *Parlia) CalcDifficulty(chain consensus.ChainReader, time uint64, parent
861854// that a new block should have based on the previous blocks in the chain and the
862855// current signer.
863856func CalcDifficulty (snap * Snapshot , signer common.Address ) * big.Int {
864- if snap .inturn (snap . Number + 1 , signer ) {
857+ if snap .inturn (signer ) {
865858 return new (big.Int ).Set (diffInTurn )
866859 }
867860 return new (big.Int ).Set (diffNoTurn )
@@ -907,7 +900,7 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash) ([]common.Address,
907900 }
908901 // call
909902 msgData := (hexutil .Bytes )(data )
910- toAddress := common .HexToAddress (ValidatorContract )
903+ toAddress := common .HexToAddress (systemcontracts . ValidatorContract )
911904 gas := (hexutil .Uint64 )(uint64 (math .MaxUint64 / 2 ))
912905 result , err := p .ethAPI .Call (ctx , ethapi.CallArgs {
913906 Gas : & gas ,
@@ -945,7 +938,7 @@ func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, he
945938 state .SetBalance (consensus .SystemAddress , big .NewInt (0 ))
946939 state .AddBalance (coinbase , balance )
947940
948- doDistributeSysReward := state .GetBalance (common .HexToAddress (SystemRewardContract )).Cmp (maxSystemBalance ) < 0
941+ doDistributeSysReward := state .GetBalance (common .HexToAddress (systemcontracts . SystemRewardContract )).Cmp (maxSystemBalance ) < 0
949942 if doDistributeSysReward {
950943 var rewards = new (big.Int )
951944 rewards = rewards .Rsh (balance , systemRewardPercent )
@@ -977,7 +970,7 @@ func (p *Parlia) slash(spoiledVal common.Address, state *state.StateDB, header *
977970 return err
978971 }
979972 // get system message
980- msg := p .getSystemMessage (header .Coinbase , common .HexToAddress (SlashContract ), data , common .Big0 )
973+ msg := p .getSystemMessage (header .Coinbase , common .HexToAddress (systemcontracts . SlashContract ), data , common .Big0 )
981974 // apply message
982975 return p .applyTransaction (msg , state , header , chain , txs , receipts , receivedTxs , usedGas , mining )
983976}
@@ -988,7 +981,15 @@ func (p *Parlia) initContract(state *state.StateDB, header *types.Header, chain
988981 // method
989982 method := "init"
990983 // contracts
991- contracts := []string {ValidatorContract , SlashContract , LightClientContract , RelayerHubContract , TokenHubContract , RelayerIncentivizeContract , CrossChainContract }
984+ contracts := []string {
985+ systemcontracts .ValidatorContract ,
986+ systemcontracts .SlashContract ,
987+ systemcontracts .LightClientContract ,
988+ systemcontracts .RelayerHubContract ,
989+ systemcontracts .TokenHubContract ,
990+ systemcontracts .RelayerIncentivizeContract ,
991+ systemcontracts .CrossChainContract ,
992+ }
992993 // get packed data
993994 data , err := p .validatorSetABI .Pack (method )
994995 if err != nil {
@@ -1010,7 +1011,7 @@ func (p *Parlia) initContract(state *state.StateDB, header *types.Header, chain
10101011func (p * Parlia ) distributeToSystem (amount * big.Int , state * state.StateDB , header * types.Header , chain core.ChainContext ,
10111012 txs * []* types.Transaction , receipts * []* types.Receipt , receivedTxs * []* types.Transaction , usedGas * uint64 , mining bool ) error {
10121013 // get system message
1013- msg := p .getSystemMessage (header .Coinbase , common .HexToAddress (SystemRewardContract ), nil , amount )
1014+ msg := p .getSystemMessage (header .Coinbase , common .HexToAddress (systemcontracts . SystemRewardContract ), nil , amount )
10141015 // apply message
10151016 return p .applyTransaction (msg , state , header , chain , txs , receipts , receivedTxs , usedGas , mining )
10161017}
@@ -1031,7 +1032,7 @@ func (p *Parlia) distributeToValidator(amount *big.Int, validator common.Address
10311032 return err
10321033 }
10331034 // get system message
1034- msg := p .getSystemMessage (header .Coinbase , common .HexToAddress (ValidatorContract ), data , amount )
1035+ msg := p .getSystemMessage (header .Coinbase , common .HexToAddress (systemcontracts . ValidatorContract ), data , amount )
10351036 // apply message
10361037 return p .applyTransaction (msg , state , header , chain , txs , receipts , receivedTxs , usedGas , mining )
10371038}
@@ -1072,8 +1073,8 @@ func (p *Parlia) applyTransaction(
10721073 return errors .New ("supposed to get a actual transaction, but get none" )
10731074 }
10741075 actualTx := (* receivedTxs )[0 ]
1075- if bytes .Compare (p .signer .Hash (actualTx ).Bytes (), expectedHash .Bytes ()) != 0 {
1076- return errors . New ( fmt .Sprintf ("expected tx hash %v, get %v" , expectedHash .String (), actualTx .Hash ().String () ))
1076+ if ! bytes .Equal (p .signer .Hash (actualTx ).Bytes (), expectedHash .Bytes ()) {
1077+ return fmt .Errorf ("expected tx hash %v, get %v" , expectedHash .String (), actualTx .Hash ().String ())
10771078 }
10781079 expectedTx = actualTx
10791080 // move to next
@@ -1140,6 +1141,30 @@ func encodeSigHeader(w io.Writer, header *types.Header, chainId *big.Int) {
11401141 }
11411142}
11421143
1144+ func backOffTime (snap * Snapshot , val common.Address ) uint64 {
1145+ if snap .inturn (val ) {
1146+ return 0
1147+ } else {
1148+ idx := snap .indexOfVal (val )
1149+ if idx < 0 {
1150+ // The backOffTime does not matter when a validator is not authorized.
1151+ return 0
1152+ }
1153+ s := rand .NewSource (int64 (snap .Number ))
1154+ r := rand .New (s )
1155+ n := len (snap .Validators )
1156+ backOffSteps := make ([]uint64 , 0 , n )
1157+ for idx := uint64 (0 ); idx < uint64 (n ); idx ++ {
1158+ backOffSteps = append (backOffSteps , idx )
1159+ }
1160+ r .Shuffle (n , func (i , j int ) {
1161+ backOffSteps [i ], backOffSteps [j ] = backOffSteps [j ], backOffSteps [i ]
1162+ })
1163+ delay := initialBackOffTime + backOffSteps [idx ]* wiggleTime
1164+ return delay
1165+ }
1166+ }
1167+
11431168// chain context
11441169type chainContext struct {
11451170 Chain consensus.ChainReader
@@ -1194,4 +1219,3 @@ func applyMessage(
11941219 }
11951220 return msg .Gas () - returnGas , err
11961221}
1197-
0 commit comments