Compare commits

...

22 Commits

Author SHA1 Message Date
zjubfd
b652ef3a67 Merge pull request #27 from binance-chain/1.0.1.beta.2
[R4R]add niels fork
2020-08-13 21:03:21 +08:00
fudongbai
011f043418 add niels fork 2020-08-13 21:00:57 +08:00
zjubfd
d9a0607e5e Merge pull request #24 from binance-chain/develop
[R4R] prepare for release 1.0.1-beta
2020-08-11 18:03:51 +08:00
fudongbai
f2e4ef2e6d prepare for release 1.0.1-beta 2020-08-11 17:07:20 +08:00
zjubfd
8c8c2a7d9e Merge pull request #16 from binance-chain/system-contract-upgrade
R4R: system contract upgrade framework and upgrade tokenhub
2020-08-11 16:58:57 +08:00
zjubfd
4a8f63917f Merge pull request #26 from binance-chain/chapelupgrade
[R4R]update chapel ramanujan fork
2020-08-11 16:57:50 +08:00
fudongbai
45f17d59a0 update chapel ramanujan fork 2020-08-11 16:55:11 +08:00
fudongbai
c399c88e08 fix not return error when blockTimeVerifyForRamanujanFork failed 2020-08-11 15:13:10 +08:00
zjubfd
8c1d1dbb79 Merge pull request #25 from binance-chain/fixdelayLogic
[R4R] minor fix for ramanujan upgrade
2020-08-10 13:58:01 +08:00
fudongbai
4f431e0843 fix index out of range 2020-08-10 11:27:36 +08:00
fudongbai
85ebea9e8c fix hex code of new smart contract 2020-08-09 18:09:43 +08:00
fudongbai
c4f4377cfd fix deplay check 2020-08-09 12:38:02 +08:00
fudongbai
baae91db37 add upgrade height for rialto 2020-08-07 17:29:22 +08:00
HaoyangLiu
650d066757 resolve comment 2020-08-07 17:16:39 +08:00
HaoyangLiu
02154bb0f0 add multiple upgrade config 2020-08-07 17:15:09 +08:00
HaoyangLiu
13cca06be8 add beforeUpgrade and afterUpgrade 2020-08-07 17:15:09 +08:00
HaoyangLiu
4450b337c4 refactor upgrade config 2020-08-07 17:15:09 +08:00
HaoyangLiu
3789ea31dd improve upgrade config 2020-08-07 17:15:09 +08:00
HaoyangLiu
3f36e996df framework for upgrade system contract 2020-08-07 17:15:09 +08:00
zjubfd
a8c9e53eb0 enforce backoff time for out-turn validator (#23) 2020-08-07 17:06:29 +08:00
yutianwu
83d72b8e91 Merge pull request #22 from binance-chain/resolve-best-pratices
[R4R]: resolve best practice advice
2020-08-05 10:54:38 +08:00
HaoyangLiu
8124e60e9d resolve best practice advice 2020-08-04 13:56:13 +08:00
20 changed files with 568 additions and 88 deletions

View File

@@ -1,5 +1,19 @@
# Changelog # Changelog
## v1.0.1-beta
IMPROVEMENT
* [\#22](https://github.com/binance-chain/bsc/pull/22) resolve best practice advice
FEATURES
* [\#23](https://github.com/binance-chain/bsc/pull/23) enforce backoff time for out-turn validator
BUGFIX
* [\#25](https://github.com/binance-chain/bsc/pull/25) minor fix for ramanujan upgrade
UPGRADE
* [\#26](https://github.com/binance-chain/bsc/pull/26) update chapel network config for ramanujan fork
## v1.0.0-beta.0 ## v1.0.0-beta.0
FEATURES FEATURES

View File

@@ -36,6 +36,7 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/systemcontracts"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
@@ -133,6 +134,7 @@ type CParamsParams struct {
ConstantinopleForkBlock *math.HexOrDecimal64 `json:"constantinopleForkBlock"` ConstantinopleForkBlock *math.HexOrDecimal64 `json:"constantinopleForkBlock"`
ConstantinopleFixForkBlock *math.HexOrDecimal64 `json:"constantinopleFixForkBlock"` ConstantinopleFixForkBlock *math.HexOrDecimal64 `json:"constantinopleFixForkBlock"`
IstanbulBlock *math.HexOrDecimal64 `json:"istanbulForkBlock"` IstanbulBlock *math.HexOrDecimal64 `json:"istanbulForkBlock"`
RamanujanForkBlock *math.HexOrDecimal64 `json:"ramanujanForkBlock"`
ChainID *math.HexOrDecimal256 `json:"chainID"` ChainID *math.HexOrDecimal256 `json:"chainID"`
MaximumExtraDataSize math.HexOrDecimal64 `json:"maximumExtraDataSize"` MaximumExtraDataSize math.HexOrDecimal64 `json:"maximumExtraDataSize"`
TieBreakingGas bool `json:"tieBreakingGas"` TieBreakingGas bool `json:"tieBreakingGas"`
@@ -322,6 +324,7 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
constantinopleBlock *big.Int constantinopleBlock *big.Int
petersburgBlock *big.Int petersburgBlock *big.Int
istanbulBlock *big.Int istanbulBlock *big.Int
ramanujanBlock *big.Int
) )
if chainParams.Params.HomesteadForkBlock != nil { if chainParams.Params.HomesteadForkBlock != nil {
homesteadBlock = big.NewInt(int64(*chainParams.Params.HomesteadForkBlock)) homesteadBlock = big.NewInt(int64(*chainParams.Params.HomesteadForkBlock))
@@ -351,6 +354,9 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
if chainParams.Params.IstanbulBlock != nil { if chainParams.Params.IstanbulBlock != nil {
istanbulBlock = big.NewInt(int64(*chainParams.Params.IstanbulBlock)) istanbulBlock = big.NewInt(int64(*chainParams.Params.IstanbulBlock))
} }
if chainParams.Params.RamanujanForkBlock != nil {
ramanujanBlock = big.NewInt(int64(*chainParams.Params.RamanujanForkBlock))
}
genesis := &core.Genesis{ genesis := &core.Genesis{
Config: &params.ChainConfig{ Config: &params.ChainConfig{
@@ -365,6 +371,7 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
ConstantinopleBlock: constantinopleBlock, ConstantinopleBlock: constantinopleBlock,
PetersburgBlock: petersburgBlock, PetersburgBlock: petersburgBlock,
IstanbulBlock: istanbulBlock, IstanbulBlock: istanbulBlock,
RamanujanBlock: ramanujanBlock,
}, },
Nonce: uint64(chainParams.Genesis.Nonce), Nonce: uint64(chainParams.Genesis.Nonce),
Timestamp: uint64(chainParams.Genesis.Timestamp), Timestamp: uint64(chainParams.Genesis.Timestamp),
@@ -501,6 +508,7 @@ func (api *RetestethAPI) mineBlock() error {
if api.chainConfig.DAOForkSupport && api.chainConfig.DAOForkBlock != nil && api.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { if api.chainConfig.DAOForkSupport && api.chainConfig.DAOForkBlock != nil && api.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 {
misc.ApplyDAOHardFork(statedb) misc.ApplyDAOHardFork(statedb)
} }
systemcontracts.UpgradeBuildInSystemContract(api.chainConfig, header.Number, statedb)
gasPool := new(core.GasPool).AddGas(header.GasLimit) gasPool := new(core.GasPool).AddGas(header.GasLimit)
txCount := 0 txCount := 0
var txs []*types.Transaction var txs []*types.Transaction

View File

@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/systemcontracts"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
@@ -48,21 +49,11 @@ const (
extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
validatorBytesLength = common.AddressLength validatorBytesLength = common.AddressLength
wiggleTime = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers
fixedBackOffTime = 200 * time.Millisecond initialBackOffTime = uint64(1) // second
systemRewardPercent = 4 // it means 1/2^4 = 1/16 percentage of gas fee incoming will be distributed to system systemRewardPercent = 4 // it means 1/2^4 = 1/16 percentage of gas fee incoming will be distributed to system
// genesis contracts
ValidatorContract = "0x0000000000000000000000000000000000001000"
SlashContract = "0x0000000000000000000000000000000000001001"
SystemRewardContract = "0x0000000000000000000000000000000000001002"
LightClientContract = "0x0000000000000000000000000000000000001003"
TokenHubContract = "0x0000000000000000000000000000000000001004"
RelayerIncentivizeContract = "0x0000000000000000000000000000000000001005"
RelayerHubContract = "0x0000000000000000000000000000000000001006"
GovHubContract = "0x0000000000000000000000000000000000001007"
CrossChainContract = "0x0000000000000000000000000000000000002000"
) )
var ( var (
@@ -73,15 +64,15 @@ var (
maxSystemBalance = new(big.Int).Mul(big.NewInt(100), big.NewInt(params.Ether)) maxSystemBalance = new(big.Int).Mul(big.NewInt(100), big.NewInt(params.Ether))
systemContracts = map[common.Address]bool{ systemContracts = map[common.Address]bool{
common.HexToAddress(ValidatorContract): true, common.HexToAddress(systemcontracts.ValidatorContract): true,
common.HexToAddress(SlashContract): true, common.HexToAddress(systemcontracts.SlashContract): true,
common.HexToAddress(SystemRewardContract): true, common.HexToAddress(systemcontracts.SystemRewardContract): true,
common.HexToAddress(LightClientContract): true, common.HexToAddress(systemcontracts.LightClientContract): true,
common.HexToAddress(RelayerHubContract): true, common.HexToAddress(systemcontracts.RelayerHubContract): true,
common.HexToAddress(GovHubContract): true, common.HexToAddress(systemcontracts.GovHubContract): true,
common.HexToAddress(TokenHubContract): true, common.HexToAddress(systemcontracts.TokenHubContract): true,
common.HexToAddress(RelayerIncentivizeContract): true, common.HexToAddress(systemcontracts.RelayerIncentivizeContract): true,
common.HexToAddress(CrossChainContract): true, common.HexToAddress(systemcontracts.CrossChainContract): true,
} }
) )
@@ -395,10 +386,20 @@ func (p *Parlia) verifyCascadingFields(chain consensus.ChainReader, header *type
return consensus.ErrUnknownAncestor return consensus.ErrUnknownAncestor
} }
snap, err := p.snapshot(chain, number-1, header.ParentHash, parents)
if err != nil {
return err
}
err = p.blockTimeVerifyForRamanujanFork(snap, header, parent)
if err != nil {
return err
}
// Verify that the gas limit is <= 2^63-1 // Verify that the gas limit is <= 2^63-1
cap := uint64(0x7fffffffffffffff) capacity := uint64(0x7fffffffffffffff)
if header.GasLimit > cap { if header.GasLimit > capacity {
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap) return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, capacity)
} }
// Verify that the gasUsed is <= gasLimit // Verify that the gasUsed is <= gasLimit
if header.GasUsed > header.GasLimit { if header.GasUsed > header.GasLimit {
@@ -570,7 +571,7 @@ func (p *Parlia) verifySeal(chain consensus.ChainReader, header *types.Header, p
// Ensure that the difficulty corresponds to the turn-ness of the signer // Ensure that the difficulty corresponds to the turn-ness of the signer
if !p.fakeDiff { if !p.fakeDiff {
inturn := snap.inturn(header.Number.Uint64(), signer) inturn := snap.inturn(signer)
if inturn && header.Difficulty.Cmp(diffInTurn) != 0 { if inturn && header.Difficulty.Cmp(diffInTurn) != 0 {
return errWrongDifficulty return errWrongDifficulty
} }
@@ -626,8 +627,7 @@ func (p *Parlia) Prepare(chain consensus.ChainReader, header *types.Header) erro
if parent == nil { if parent == nil {
return consensus.ErrUnknownAncestor return consensus.ErrUnknownAncestor
} }
header.Time = p.blockTimeForRamanujanFork(snap, header, parent)
header.Time = parent.Time + p.config.Period
if header.Time < uint64(time.Now().Unix()) { if header.Time < uint64(time.Now().Unix()) {
header.Time = uint64(time.Now().Unix()) header.Time = uint64(time.Now().Unix())
} }
@@ -809,14 +809,7 @@ func (p *Parlia) Seal(chain consensus.ChainReader, block *types.Block, results c
} }
// Sweet, the protocol permits us to sign the block, wait for our time // Sweet, the protocol permits us to sign the block, wait for our time
delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple delay := p.delayForRamanujanFork(snap, header)
if header.Difficulty.Cmp(diffNoTurn) == 0 {
// It's not our turn explicitly to sign, delay it a bit
wiggle := time.Duration(len(snap.Validators)/2+1) * wiggleTime
delay += time.Duration(fixedBackOffTime) + time.Duration(rand.Int63n(int64(wiggle)))
log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle))
}
log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "val", val.Hex()) log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "val", val.Hex())
@@ -861,7 +854,7 @@ func (p *Parlia) CalcDifficulty(chain consensus.ChainReader, time uint64, parent
// that a new block should have based on the previous blocks in the chain and the // that a new block should have based on the previous blocks in the chain and the
// current signer. // current signer.
func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int { func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
if snap.inturn(snap.Number+1, signer) { if snap.inturn(signer) {
return new(big.Int).Set(diffInTurn) return new(big.Int).Set(diffInTurn)
} }
return new(big.Int).Set(diffNoTurn) return new(big.Int).Set(diffNoTurn)
@@ -907,7 +900,7 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash) ([]common.Address,
} }
// call // call
msgData := (hexutil.Bytes)(data) msgData := (hexutil.Bytes)(data)
toAddress := common.HexToAddress(ValidatorContract) toAddress := common.HexToAddress(systemcontracts.ValidatorContract)
gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
result, err := p.ethAPI.Call(ctx, ethapi.CallArgs{ result, err := p.ethAPI.Call(ctx, ethapi.CallArgs{
Gas: &gas, Gas: &gas,
@@ -945,7 +938,7 @@ func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, he
state.SetBalance(consensus.SystemAddress, big.NewInt(0)) state.SetBalance(consensus.SystemAddress, big.NewInt(0))
state.AddBalance(coinbase, balance) state.AddBalance(coinbase, balance)
doDistributeSysReward := state.GetBalance(common.HexToAddress(SystemRewardContract)).Cmp(maxSystemBalance) < 0 doDistributeSysReward := state.GetBalance(common.HexToAddress(systemcontracts.SystemRewardContract)).Cmp(maxSystemBalance) < 0
if doDistributeSysReward { if doDistributeSysReward {
var rewards = new(big.Int) var rewards = new(big.Int)
rewards = rewards.Rsh(balance, systemRewardPercent) rewards = rewards.Rsh(balance, systemRewardPercent)
@@ -977,7 +970,7 @@ func (p *Parlia) slash(spoiledVal common.Address, state *state.StateDB, header *
return err return err
} }
// get system message // get system message
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(SlashContract), data, common.Big0) msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.SlashContract), data, common.Big0)
// apply message // apply message
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
} }
@@ -988,7 +981,15 @@ func (p *Parlia) initContract(state *state.StateDB, header *types.Header, chain
// method // method
method := "init" method := "init"
// contracts // contracts
contracts := []string{ValidatorContract, SlashContract, LightClientContract, RelayerHubContract, TokenHubContract, RelayerIncentivizeContract, CrossChainContract} contracts := []string{
systemcontracts.ValidatorContract,
systemcontracts.SlashContract,
systemcontracts.LightClientContract,
systemcontracts.RelayerHubContract,
systemcontracts.TokenHubContract,
systemcontracts.RelayerIncentivizeContract,
systemcontracts.CrossChainContract,
}
// get packed data // get packed data
data, err := p.validatorSetABI.Pack(method) data, err := p.validatorSetABI.Pack(method)
if err != nil { if err != nil {
@@ -1010,7 +1011,7 @@ func (p *Parlia) initContract(state *state.StateDB, header *types.Header, chain
func (p *Parlia) distributeToSystem(amount *big.Int, state *state.StateDB, header *types.Header, chain core.ChainContext, func (p *Parlia) distributeToSystem(amount *big.Int, state *state.StateDB, header *types.Header, chain core.ChainContext,
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error { txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error {
// get system message // get system message
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(SystemRewardContract), nil, amount) msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.SystemRewardContract), nil, amount)
// apply message // apply message
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
} }
@@ -1031,7 +1032,7 @@ func (p *Parlia) distributeToValidator(amount *big.Int, validator common.Address
return err return err
} }
// get system message // get system message
msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(ValidatorContract), data, amount) msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.ValidatorContract), data, amount)
// apply message // apply message
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
} }
@@ -1072,8 +1073,8 @@ func (p *Parlia) applyTransaction(
return errors.New("supposed to get a actual transaction, but get none") return errors.New("supposed to get a actual transaction, but get none")
} }
actualTx := (*receivedTxs)[0] actualTx := (*receivedTxs)[0]
if bytes.Compare(p.signer.Hash(actualTx).Bytes(), expectedHash.Bytes()) != 0 { if !bytes.Equal(p.signer.Hash(actualTx).Bytes(), expectedHash.Bytes()) {
return errors.New(fmt.Sprintf("expected tx hash %v, get %v", expectedHash.String(), actualTx.Hash().String())) return fmt.Errorf("expected tx hash %v, get %v", expectedHash.String(), actualTx.Hash().String())
} }
expectedTx = actualTx expectedTx = actualTx
// move to next // move to next
@@ -1140,6 +1141,30 @@ func encodeSigHeader(w io.Writer, header *types.Header, chainId *big.Int) {
} }
} }
func backOffTime(snap *Snapshot, val common.Address) uint64 {
if snap.inturn(val) {
return 0
} else {
idx := snap.indexOfVal(val)
if idx < 0 {
// The backOffTime does not matter when a validator is not authorized.
return 0
}
s := rand.NewSource(int64(snap.Number))
r := rand.New(s)
n := len(snap.Validators)
backOffSteps := make([]uint64, 0, n)
for idx := uint64(0); idx < uint64(n); idx++ {
backOffSteps = append(backOffSteps, idx)
}
r.Shuffle(n, func(i, j int) {
backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i]
})
delay := initialBackOffTime + backOffSteps[idx]*wiggleTime
return delay
}
}
// chain context // chain context
type chainContext struct { type chainContext struct {
Chain consensus.ChainReader Chain consensus.ChainReader
@@ -1194,4 +1219,3 @@ func applyMessage(
} }
return msg.Gas() - returnGas, err return msg.Gas() - returnGas, err
} }

View File

@@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"math/rand" "math/rand"
"testing" "testing"
"time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
) )
@@ -57,7 +56,7 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
return validators[idx] return validators[idx]
} }
downDelay := time.Duration(0) downDelay := uint64(0)
for h := 1; h <= downBlocks; h++ { for h := 1; h <= downBlocks; h++ {
if limit := uint64(totalValidators/2 + 1); uint64(h) >= limit { if limit := uint64(totalValidators/2 + 1); uint64(h) >= limit {
delete(recents, uint64(h)-limit) delete(recents, uint64(h)-limit)
@@ -73,7 +72,7 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
if len(candidates) == 0 { if len(candidates) == 0 {
panic("can not test such case") panic("can not test such case")
} }
idx, delay := producerBlockDelay(candidates, totalValidators) idx, delay := producerBlockDelay(candidates, h, totalValidators)
downDelay = downDelay + delay downDelay = downDelay + delay
recents[uint64(h)] = idx recents[uint64(h)] = idx
} else { } else {
@@ -81,13 +80,13 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
} }
} }
fmt.Printf("average delay is %v when there is %d validators and %d is down \n", fmt.Printf("average delay is %v when there is %d validators and %d is down \n",
downDelay/time.Duration(downBlocks), totalValidators, downValidators) downDelay/uint64(downBlocks), totalValidators, downValidators)
for i := 0; i < downValidators; i++ { for i := 0; i < downValidators; i++ {
validators[down[i]] = true validators[down[i]] = true
} }
recoverDelay := time.Duration(0) recoverDelay := uint64(0)
lastseen := downBlocks lastseen := downBlocks
for h := downBlocks + 1; h <= downBlocks+recoverBlocks; h++ { for h := downBlocks + 1; h <= downBlocks+recoverBlocks; h++ {
if limit := uint64(totalValidators/2 + 1); uint64(h) >= limit { if limit := uint64(totalValidators/2 + 1); uint64(h) >= limit {
@@ -105,7 +104,7 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
if len(candidates) == 0 { if len(candidates) == 0 {
panic("can not test such case") panic("can not test such case")
} }
idx, delay := producerBlockDelay(candidates, totalValidators) idx, delay := producerBlockDelay(candidates, h, totalValidators)
recoverDelay = recoverDelay + delay recoverDelay = recoverDelay + delay
recents[uint64(h)] = idx recents[uint64(h)] = idx
} else { } else {
@@ -116,18 +115,28 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
recoverDelay, downValidators, lastseen) recoverDelay, downValidators, lastseen)
} }
func producerBlockDelay(candidates map[int]bool, numOfValidators int) (int, time.Duration) { func producerBlockDelay(candidates map[int]bool, height, numOfValidators int) (int, uint64) {
minDur := time.Duration(0)
minIdx := 0 s := rand.NewSource(int64(height))
wiggle := time.Duration(numOfValidators/2+1) * wiggleTime r := rand.New(s)
for idx := range candidates { n := numOfValidators
sleepTime := rand.Int63n(int64(wiggle)) backOffSteps := make([]int, 0, n)
if int64(minDur) < sleepTime { for idx := 0; idx < n; idx++ {
minDur = time.Duration(rand.Int63n(int64(wiggle))) backOffSteps = append(backOffSteps, idx)
minIdx = idx }
r.Shuffle(n, func(i, j int) {
backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i]
})
minDelay := numOfValidators
minCandidate := 0
for c := range candidates {
if minDelay > backOffSteps[c] {
minDelay = backOffSteps[c]
minCandidate = c
} }
} }
return minIdx, minDur delay := initialBackOffTime + uint64(minDelay)*wiggleTime
return minCandidate, delay
} }
func randomAddress() common.Address { func randomAddress() common.Address {

View File

@@ -0,0 +1,44 @@
package parlia
import (
"math/rand"
"time"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core/types"
)
const (
wiggleTimeBeforeFork = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers
fixedBackOffTimeBeforeFork = 200 * time.Millisecond
)
func (p *Parlia) delayForRamanujanFork(snap *Snapshot, header *types.Header) time.Duration {
delay := time.Until(time.Unix(int64(header.Time), 0)) // nolint: gosimple
if p.chainConfig.IsRamanujan(header.Number) {
return delay
}
if header.Difficulty.Cmp(diffNoTurn) == 0 {
// It's not our turn explicitly to sign, delay it a bit
wiggle := time.Duration(len(snap.Validators)/2+1) * wiggleTimeBeforeFork
delay += time.Duration(fixedBackOffTimeBeforeFork) + time.Duration(rand.Int63n(int64(wiggle)))
}
return delay
}
func (p *Parlia) blockTimeForRamanujanFork(snap *Snapshot, header, parent *types.Header) uint64 {
blockTime := parent.Time + p.config.Period
if p.chainConfig.IsRamanujan(header.Number) {
blockTime = blockTime + backOffTime(snap, p.val)
}
return blockTime
}
func (p *Parlia) blockTimeVerifyForRamanujanFork(snap *Snapshot, header, parent *types.Header) error {
if p.chainConfig.IsRamanujan(header.Number) {
if header.Time < parent.Time+p.config.Period+backOffTime(snap, header.Coinbase) {
return consensus.ErrFutureBlock
}
}
return nil
}

View File

@@ -210,12 +210,22 @@ func (s *Snapshot) validators() []common.Address {
} }
// inturn returns if a validator at a given block height is in-turn or not. // inturn returns if a validator at a given block height is in-turn or not.
func (s *Snapshot) inturn(number uint64, validator common.Address) bool { func (s *Snapshot) inturn(validator common.Address) bool {
validators := s.validators() validators := s.validators()
offset := number % uint64(len(validators)) offset := (s.Number + 1) % uint64(len(validators))
return validators[offset] == validator return validators[offset] == validator
} }
func (s *Snapshot) indexOfVal(validator common.Address) int {
validators := s.validators()
for idx, val := range validators {
if val == validator {
return idx
}
}
return -1
}
func (s *Snapshot) supposeValidator() common.Address { func (s *Snapshot) supposeValidator() common.Address {
validators := s.validators() validators := s.validators()
index := (s.Number + 1) % uint64(len(validators)) index := (s.Number + 1) % uint64(len(validators))

View File

@@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/systemcontracts"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@@ -207,6 +208,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 { if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 {
misc.ApplyDAOHardFork(statedb) misc.ApplyDAOHardFork(statedb)
} }
systemcontracts.UpgradeBuildInSystemContract(config, b.header.Number, statedb)
// Execute any user modifications to the block // Execute any user modifications to the block
if gen != nil { if gen != nil {
gen(i, b) gen(i, b)

View File

@@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/systemcontracts"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@@ -161,6 +162,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
} }
// Just commit the new block if there is no stored genesis block. // Just commit the new block if there is no stored genesis block.
stored := rawdb.ReadCanonicalHash(db, 0) stored := rawdb.ReadCanonicalHash(db, 0)
systemcontracts.GenesisHash = stored
if (stored == common.Hash{}) { if (stored == common.Hash{}) {
if genesis == nil { if genesis == nil {
log.Info("Writing default main-net genesis block") log.Info("Writing default main-net genesis block")
@@ -222,7 +224,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
// Special case: don't change the existing config of a non-mainnet chain if no new // Special case: don't change the existing config of a non-mainnet chain if no new
// config is supplied. These chains would get AllProtocolChanges (and a compat error) // config is supplied. These chains would get AllProtocolChanges (and a compat error)
// if we just continued here. // if we just continued here.
if genesis == nil && stored != params.MainnetGenesisHash { // The full node of two BSC testnets may run without genesis file after been inited.
if genesis == nil && stored != params.MainnetGenesisHash &&
stored != params.ChapelGenesisHash && stored != params.RialtoGenesisHash {
return storedcfg, stored, nil return storedcfg, stored, nil
} }
@@ -252,6 +256,10 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
return params.RinkebyChainConfig return params.RinkebyChainConfig
case ghash == params.GoerliGenesisHash: case ghash == params.GoerliGenesisHash:
return params.GoerliChainConfig return params.GoerliChainConfig
case ghash == params.ChapelGenesisHash:
return params.ChapelChainConfig
case ghash == params.RialtoGenesisHash:
return params.RialtoChainConfig
default: default:
return params.AllEthashProtocolChanges return params.AllEthashProtocolChanges
} }

View File

@@ -21,6 +21,7 @@ import (
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/systemcontracts"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
@@ -65,6 +66,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
misc.ApplyDAOHardFork(statedb) misc.ApplyDAOHardFork(statedb)
} }
// Handle upgrade build-in system contract code
systemcontracts.UpgradeBuildInSystemContract(p.config, block.Number(), statedb)
// Iterate over and process the individual transactions // Iterate over and process the individual transactions
posa, isPoSA := p.engine.(consensus.PoSA) posa, isPoSA := p.engine.(consensus.PoSA)
commonTxs := make([]*types.Transaction, 0, len(block.Transactions())) commonTxs := make([]*types.Transaction, 0, len(block.Transactions()))

View File

@@ -0,0 +1,15 @@
package systemcontracts
const (
// genesis contracts
ValidatorContract = "0x0000000000000000000000000000000000001000"
SlashContract = "0x0000000000000000000000000000000000001001"
SystemRewardContract = "0x0000000000000000000000000000000000001002"
LightClientContract = "0x0000000000000000000000000000000000001003"
TokenHubContract = "0x0000000000000000000000000000000000001004"
RelayerIncentivizeContract = "0x0000000000000000000000000000000000001005"
RelayerHubContract = "0x0000000000000000000000000000000000001006"
GovHubContract = "0x0000000000000000000000000000000000001007"
TokenManagerContract = "0x0000000000000000000000000000000000001008"
CrossChainContract = "0x0000000000000000000000000000000000002000"
)

File diff suppressed because one or more lines are too long

View File

@@ -9,6 +9,7 @@ import (
) )
const ( const (
uint64TypeLength uint64 = 8
precompileContractInputMetaDataLength uint64 = 32 precompileContractInputMetaDataLength uint64 = 32
consensusStateLengthBytesLength uint64 = 32 consensusStateLengthBytesLength uint64 = 32
@@ -20,7 +21,7 @@ const (
// consensus state length | consensus state | tendermint header | // consensus state length | consensus state | tendermint header |
// 32 bytes | | | // 32 bytes | | |
func decodeTendermintHeaderValidationInput(input []byte) (*lightclient.ConsensusState, *lightclient.Header, error) { func decodeTendermintHeaderValidationInput(input []byte) (*lightclient.ConsensusState, *lightclient.Header, error) {
csLen := binary.BigEndian.Uint64(input[consensusStateLengthBytesLength-8 : consensusStateLengthBytesLength]) csLen := binary.BigEndian.Uint64(input[consensusStateLengthBytesLength-uint64TypeLength : consensusStateLengthBytesLength])
if uint64(len(input)) <= consensusStateLengthBytesLength+csLen { if uint64(len(input)) <= consensusStateLengthBytesLength+csLen {
return nil, nil, fmt.Errorf("expected payload size %d, actual size: %d", consensusStateLengthBytesLength+csLen, len(input)) return nil, nil, fmt.Errorf("expected payload size %d, actual size: %d", consensusStateLengthBytesLength+csLen, len(input))
} }
@@ -55,7 +56,7 @@ func (c *tmHeaderValidate) Run(input []byte) (result []byte, err error) {
return nil, fmt.Errorf("invalid input") return nil, fmt.Errorf("invalid input")
} }
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-8 : precompileContractInputMetaDataLength]) payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-uint64TypeLength : precompileContractInputMetaDataLength])
if uint64(len(input)) != payloadLength+precompileContractInputMetaDataLength { if uint64(len(input)) != payloadLength+precompileContractInputMetaDataLength {
return nil, fmt.Errorf("invalid input: input size should be %d, actual the size is %d", payloadLength+precompileContractInputMetaDataLength, len(input)) return nil, fmt.Errorf("invalid input: input size should be %d, actual the size is %d", payloadLength+precompileContractInputMetaDataLength, len(input))
} }
@@ -83,7 +84,7 @@ func (c *tmHeaderValidate) Run(input []byte) (result []byte, err error) {
copy(lengthBytes[:1], []byte{0x01}) copy(lengthBytes[:1], []byte{0x01})
} }
consensusStateBytesLength := uint64(len(consensusStateBytes)) consensusStateBytesLength := uint64(len(consensusStateBytes))
binary.BigEndian.PutUint64(lengthBytes[tmHeaderValidateResultMetaDataLength-8:], consensusStateBytesLength) binary.BigEndian.PutUint64(lengthBytes[tmHeaderValidateResultMetaDataLength-uint64TypeLength:], consensusStateBytesLength)
result = append(lengthBytes, consensusStateBytes...) result = append(lengthBytes, consensusStateBytes...)
@@ -113,7 +114,7 @@ func (c *iavlMerkleProofValidate) Run(input []byte) (result []byte, err error) {
return nil, fmt.Errorf("invalid input: input should include %d bytes payload length and payload", precompileContractInputMetaDataLength) return nil, fmt.Errorf("invalid input: input should include %d bytes payload length and payload", precompileContractInputMetaDataLength)
} }
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-8 : precompileContractInputMetaDataLength]) payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-uint64TypeLength : precompileContractInputMetaDataLength])
if uint64(len(input)) != payloadLength+precompileContractInputMetaDataLength { if uint64(len(input)) != payloadLength+precompileContractInputMetaDataLength {
return nil, fmt.Errorf("invalid input: input size should be %d, actual the size is %d", payloadLength+precompileContractInputMetaDataLength, len(input)) return nil, fmt.Errorf("invalid input: input size should be %d, actual the size is %d", payloadLength+precompileContractInputMetaDataLength, len(input))
} }
@@ -129,6 +130,6 @@ func (c *iavlMerkleProofValidate) Run(input []byte) (result []byte, err error) {
} }
result = make([]byte, merkleProofValidateResultLength) result = make([]byte, merkleProofValidateResultLength)
binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-8:], 0x01) binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-uint64TypeLength:], 0x01)
return result, nil return result, nil
} }

View File

@@ -24,6 +24,7 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) {
"cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc000000174876e80049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb7" + "cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc000000174876e80049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb7" +
"87a5b314a298e000000174876e80004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b6000000174876e8004034b37ce" + "87a5b314a298e000000174876e80004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b6000000174876e8004034b37ce" +
"da8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e8000000174876e800") "da8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e8000000174876e800")
require.NoError(t, err)
cs, err := lightclient.DecodeConsensusState(consensusStateBytes) cs, err := lightclient.DecodeConsensusState(consensusStateBytes)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -226,17 +226,11 @@ func (kvmp *KeyValueMerkleProof) Validate() bool {
if len(kvmp.Value) == 0 { if len(kvmp.Value) == 0 {
err := prt.VerifyAbsence(kvmp.Proof, kvmp.AppHash, kp.String()) err := prt.VerifyAbsence(kvmp.Proof, kvmp.AppHash, kp.String())
if err != nil { return err == nil
return false
}
return true
} }
err := prt.VerifyValue(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.Value) err := prt.VerifyValue(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.Value)
if err != nil { return err == nil
return false
}
return true
} }
// input: // input:

View File

@@ -681,11 +681,12 @@ func (f *BlockFetcher) insert(peer string, block *types.Block) {
go f.broadcastBlock(block, true) go f.broadcastBlock(block, true)
case consensus.ErrFutureBlock: case consensus.ErrFutureBlock:
// Weird future block, don't fail, but neither propagate log.Error("Received future block", "peer", peer, "number", block.Number(), "hash", hash, "err", err)
f.dropPeer(peer)
default: default:
// Something went very wrong, drop the peer // Something went very wrong, drop the peer
log.Debug("Propagated block verification failed", "peer", peer, "number", block.Number(), "hash", hash, "err", err) log.Error("Propagated block verification failed", "peer", peer, "number", block.Number(), "hash", hash, "err", err)
f.dropPeer(peer) f.dropPeer(peer)
return return
} }

3
go.mod
View File

@@ -72,17 +72,14 @@ require (
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 // indirect
golang.org/x/net v0.0.0-20200301022130-244492dfa37a // indirect golang.org/x/net v0.0.0-20200301022130-244492dfa37a // indirect
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
golang.org/x/text v0.3.2 golang.org/x/text v0.3.2
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 // indirect
google.golang.org/grpc v1.27.1 // indirect google.golang.org/grpc v1.27.1 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9 gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9
gopkg.in/urfave/cli.v1 v1.20.0 gopkg.in/urfave/cli.v1 v1.20.0
gotest.tools v2.2.0+incompatible // indirect gotest.tools v2.2.0+incompatible // indirect
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc // indirect
) )

5
go.sum
View File

@@ -28,6 +28,7 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 h1:rtI0fD4oG/8eVokGVPYJEW1F88p1ZNgXiEIs9thEE4A= github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 h1:rtI0fD4oG/8eVokGVPYJEW1F88p1ZNgXiEIs9thEE4A=
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/aws/aws-sdk-go v1.25.48 h1:J82DYDGZHOKHdhx6hD24Tm30c2C3GchYGfN0mf9iKUk=
github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
@@ -50,6 +51,7 @@ github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18/go.mod h1:HD5P
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9 h1:J82+/8rub3qSy0HxEnoYD8cs+HDlHWYrqYXe2Vqxluk=
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -69,6 +71,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk= github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf h1:sh8rkQZavChcmakYiSlqu2425CHyFXLZZnvm7PDpU8M=
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87 h1:OMbqMXf9OAXzH1dDH82mQMrddBE8LIIwDtxeK4wE1/A= github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87 h1:OMbqMXf9OAXzH1dDH82mQMrddBE8LIIwDtxeK4wE1/A=
github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
@@ -136,11 +139,13 @@ github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZ
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA=
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 h1:I/yrLt2WilKxlQKCM52clh5rGzTKpVctGT1lH4Dc8Jw= github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 h1:I/yrLt2WilKxlQKCM52clh5rGzTKpVctGT1lH4Dc8Jw=
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=

View File

@@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/parlia" "github.com/ethereum/go-ethereum/consensus/parlia"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/systemcontracts"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
@@ -900,6 +901,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
if w.chainConfig.DAOForkSupport && w.chainConfig.DAOForkBlock != nil && w.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { if w.chainConfig.DAOForkSupport && w.chainConfig.DAOForkBlock != nil && w.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 {
misc.ApplyDAOHardFork(env.state) misc.ApplyDAOHardFork(env.state)
} }
systemcontracts.UpgradeBuildInSystemContract(w.chainConfig, header.Number, env.state)
// Accumulate the uncles for the current block // Accumulate the uncles for the current block
uncles := make([]*types.Header, 0, 2) uncles := make([]*types.Header, 0, 2)
commitUncles := func(blocks map[common.Hash]*types.Block) { commitUncles := func(blocks map[common.Hash]*types.Block) {

View File

@@ -31,6 +31,9 @@ var (
RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d") RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d")
RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177")
GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
ChapelGenesisHash = common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34")
RialtoGenesisHash = common.HexToHash("0xaa1c1e0af675e846942719466ab72822eff51ebf8462ead0897ae1240e3c0da1")
) )
// TrustedCheckpoints associates each known checkpoint with the genesis hash of // TrustedCheckpoints associates each known checkpoint with the genesis hash of
@@ -210,21 +213,59 @@ var (
Threshold: 2, Threshold: 2,
} }
ChapelChainConfig = &ChainConfig{
ChainID: big.NewInt(97),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
RamanujanBlock: big.NewInt(1010000),
NielsBlock: big.NewInt(1014369),
Parlia: &ParliaConfig{
Period: 3,
Epoch: 200,
},
}
RialtoChainConfig = &ChainConfig{
ChainID: big.NewInt(1417),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
RamanujanBlock: big.NewInt(400),
NielsBlock: big.NewInt(0),
Parlia: &ParliaConfig{
Period: 3,
Epoch: 200,
},
}
// AllEthashProtocolChanges contains every protocol change (EIPs) introduced // AllEthashProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Ethash consensus. // and accepted by the Ethereum core developers into the Ethash consensus.
// //
// This configuration is intentionally not using keyed fields to force anyone // This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields. // 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), nil, nil, 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), nil, nil, nil, nil, new(EthashConfig), nil, nil}
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Clique consensus. // and accepted by the Ethereum core developers into the Clique consensus.
// //
// This configuration is intentionally not using keyed fields to force anyone // This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields. // 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), 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), nil, 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), nil, 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), nil, nil, nil, nil, new(EthashConfig), nil, nil}
TestRules = TestChainConfig.Rules(new(big.Int)) TestRules = TestChainConfig.Rules(new(big.Int))
) )
@@ -296,6 +337,8 @@ type ChainConfig struct {
IstanbulBlock *big.Int `json:"istanbulBlock,omitempty" toml:",omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul) IstanbulBlock *big.Int `json:"istanbulBlock,omitempty" toml:",omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul)
MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty" toml:",omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty" toml:",omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
EWASMBlock *big.Int `json:"ewasmBlock,omitempty" toml:",omitempty"` // EWASM switch block (nil = no fork, 0 = already activated) EWASMBlock *big.Int `json:"ewasmBlock,omitempty" toml:",omitempty"` // EWASM switch block (nil = no fork, 0 = already activated)
RamanujanBlock *big.Int `json:"ramanujanBlock,omitempty" toml:",omitempty"` // ramanujanBlock switch block (nil = no fork, 0 = already activated)
NielsBlock *big.Int `json:"nielsBlock,omitempty" toml:",omitempty"` // nielsBlock switch block (nil = no fork, 0 = already activated)
// Various consensus engines // Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"` Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"`
@@ -346,7 +389,7 @@ func (c *ChainConfig) String() string {
default: default:
engine = "unknown" 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, 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, Engine: %v}",
c.ChainID, c.ChainID,
c.HomesteadBlock, c.HomesteadBlock,
c.DAOForkBlock, c.DAOForkBlock,
@@ -359,6 +402,8 @@ func (c *ChainConfig) String() string {
c.PetersburgBlock, c.PetersburgBlock,
c.IstanbulBlock, c.IstanbulBlock,
c.MuirGlacierBlock, c.MuirGlacierBlock,
c.RamanujanBlock,
c.NielsBlock,
engine, engine,
) )
} }
@@ -398,6 +443,26 @@ func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
return isForked(c.ConstantinopleBlock, num) return isForked(c.ConstantinopleBlock, num)
} }
// IsRamanujan returns whether num is either equal to the IsRamanujan fork block or greater.
func (c *ChainConfig) IsRamanujan(num *big.Int) bool {
return isForked(c.RamanujanBlock, num)
}
// IsOnRamanujan returns whether num is equal to the Ramanujan fork block
func (c *ChainConfig) IsOnRamanujan(num *big.Int) bool {
return configNumEqual(c.RamanujanBlock, num)
}
// IsNiels returns whether num is either equal to the Niels fork block or greater.
func (c *ChainConfig) IsNiels(num *big.Int) bool {
return isForked(c.NielsBlock, num)
}
// IsOnNiels returns whether num is equal to the IsNiels fork block
func (c *ChainConfig) IsOnNiels(num *big.Int) bool {
return configNumEqual(c.NielsBlock, num)
}
// IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
return isForked(c.MuirGlacierBlock, num) return isForked(c.MuirGlacierBlock, num)
@@ -456,6 +521,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
{"petersburgBlock", c.PetersburgBlock}, {"petersburgBlock", c.PetersburgBlock},
{"istanbulBlock", c.IstanbulBlock}, {"istanbulBlock", c.IstanbulBlock},
{"muirGlacierBlock", c.MuirGlacierBlock}, {"muirGlacierBlock", c.MuirGlacierBlock},
{"ramanujanBlock", c.RamanujanBlock},
} { } {
if lastFork.name != "" { if lastFork.name != "" {
// Next one must be higher number // Next one must be higher number
@@ -515,6 +581,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) { if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) {
return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock) return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock)
} }
if isForkIncompatible(c.RamanujanBlock, newcfg.RamanujanBlock, head) {
return newCompatError("ramanujan fork block", c.RamanujanBlock, newcfg.RamanujanBlock)
}
return nil return nil
} }

View File

@@ -23,8 +23,8 @@ import (
const ( const (
VersionMajor = 1 // Major version component of the current release VersionMajor = 1 // Major version component of the current release
VersionMinor = 0 // Minor version component of the current release VersionMinor = 0 // Minor version component of the current release
VersionPatch = 0 // Patch version component of the current release VersionPatch = 1 // Patch version component of the current release
VersionMeta = "beta.1" // Version metadata to append to the version string VersionMeta = "beta.2" // Version metadata to append to the version string
) )
// Version holds the textual version string. // Version holds the textual version string.