Compare commits
28 Commits
v1.0.0-bet
...
v1.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfb73f8068 | ||
|
|
397f6f6108 | ||
|
|
b242e890d2 | ||
|
|
ba0152fea9 | ||
|
|
844ed90c28 | ||
|
|
f94b7de003 | ||
|
|
b652ef3a67 | ||
|
|
011f043418 | ||
|
|
d9a0607e5e | ||
|
|
f2e4ef2e6d | ||
|
|
8c8c2a7d9e | ||
|
|
4a8f63917f | ||
|
|
45f17d59a0 | ||
|
|
c399c88e08 | ||
|
|
8c1d1dbb79 | ||
|
|
4f431e0843 | ||
|
|
85ebea9e8c | ||
|
|
c4f4377cfd | ||
|
|
baae91db37 | ||
|
|
650d066757 | ||
|
|
02154bb0f0 | ||
|
|
13cca06be8 | ||
|
|
4450b337c4 | ||
|
|
3789ea31dd | ||
|
|
3f36e996df | ||
|
|
a8c9e53eb0 | ||
|
|
83d72b8e91 | ||
|
|
8124e60e9d |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,5 +1,19 @@
|
||||
# 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
|
||||
|
||||
FEATURES
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
## Disclaimer
|
||||
|
||||
**The software and related documentation are under active development,
|
||||
all subject to potential future change without notification and not ready for production use.
|
||||
The code and security audit have not been fully completed and not ready for any bug bounty.
|
||||
We advise you to be careful and experiment on the network at your own risk. Stay safe out there.**
|
||||
|
||||
## Binance Smart Chain
|
||||
|
||||
The goal of Binance Smart Chain is to bring programmability and interoperability to Binance Chain. In order to embrace the existing popular community and advanced technology, it will bring huge benefits by staying compatible with all the existing smart contracts on Ethereum and Ethereum tooling. And to achieve that, the easiest solution is to develop based on go-ethereum fork, as we respect the great work of Ethereum very much.
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"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/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
@@ -133,6 +134,7 @@ type CParamsParams struct {
|
||||
ConstantinopleForkBlock *math.HexOrDecimal64 `json:"constantinopleForkBlock"`
|
||||
ConstantinopleFixForkBlock *math.HexOrDecimal64 `json:"constantinopleFixForkBlock"`
|
||||
IstanbulBlock *math.HexOrDecimal64 `json:"istanbulForkBlock"`
|
||||
RamanujanForkBlock *math.HexOrDecimal64 `json:"ramanujanForkBlock"`
|
||||
ChainID *math.HexOrDecimal256 `json:"chainID"`
|
||||
MaximumExtraDataSize math.HexOrDecimal64 `json:"maximumExtraDataSize"`
|
||||
TieBreakingGas bool `json:"tieBreakingGas"`
|
||||
@@ -322,6 +324,7 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
|
||||
constantinopleBlock *big.Int
|
||||
petersburgBlock *big.Int
|
||||
istanbulBlock *big.Int
|
||||
ramanujanBlock *big.Int
|
||||
)
|
||||
if chainParams.Params.HomesteadForkBlock != nil {
|
||||
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 {
|
||||
istanbulBlock = big.NewInt(int64(*chainParams.Params.IstanbulBlock))
|
||||
}
|
||||
if chainParams.Params.RamanujanForkBlock != nil {
|
||||
ramanujanBlock = big.NewInt(int64(*chainParams.Params.RamanujanForkBlock))
|
||||
}
|
||||
|
||||
genesis := &core.Genesis{
|
||||
Config: ¶ms.ChainConfig{
|
||||
@@ -365,6 +371,7 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
|
||||
ConstantinopleBlock: constantinopleBlock,
|
||||
PetersburgBlock: petersburgBlock,
|
||||
IstanbulBlock: istanbulBlock,
|
||||
RamanujanBlock: ramanujanBlock,
|
||||
},
|
||||
Nonce: uint64(chainParams.Genesis.Nonce),
|
||||
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 {
|
||||
misc.ApplyDAOHardFork(statedb)
|
||||
}
|
||||
systemcontracts.UpgradeBuildInSystemContract(api.chainConfig, header.Number, statedb)
|
||||
gasPool := new(core.GasPool).AddGas(header.GasLimit)
|
||||
txCount := 0
|
||||
var txs []*types.Transaction
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"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/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
@@ -48,21 +49,11 @@ const (
|
||||
extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
|
||||
|
||||
validatorBytesLength = common.AddressLength
|
||||
wiggleTime = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers
|
||||
fixedBackOffTime = 200 * time.Millisecond
|
||||
wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers
|
||||
initialBackOffTime = uint64(1) // second
|
||||
|
||||
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 (
|
||||
@@ -73,15 +64,15 @@ var (
|
||||
maxSystemBalance = new(big.Int).Mul(big.NewInt(100), big.NewInt(params.Ether))
|
||||
|
||||
systemContracts = map[common.Address]bool{
|
||||
common.HexToAddress(ValidatorContract): true,
|
||||
common.HexToAddress(SlashContract): true,
|
||||
common.HexToAddress(SystemRewardContract): true,
|
||||
common.HexToAddress(LightClientContract): true,
|
||||
common.HexToAddress(RelayerHubContract): true,
|
||||
common.HexToAddress(GovHubContract): true,
|
||||
common.HexToAddress(TokenHubContract): true,
|
||||
common.HexToAddress(RelayerIncentivizeContract): true,
|
||||
common.HexToAddress(CrossChainContract): true,
|
||||
common.HexToAddress(systemcontracts.ValidatorContract): true,
|
||||
common.HexToAddress(systemcontracts.SlashContract): true,
|
||||
common.HexToAddress(systemcontracts.SystemRewardContract): true,
|
||||
common.HexToAddress(systemcontracts.LightClientContract): true,
|
||||
common.HexToAddress(systemcontracts.RelayerHubContract): true,
|
||||
common.HexToAddress(systemcontracts.GovHubContract): true,
|
||||
common.HexToAddress(systemcontracts.TokenHubContract): true,
|
||||
common.HexToAddress(systemcontracts.RelayerIncentivizeContract): true,
|
||||
common.HexToAddress(systemcontracts.CrossChainContract): true,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -395,10 +386,20 @@ func (p *Parlia) verifyCascadingFields(chain consensus.ChainReader, header *type
|
||||
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
|
||||
cap := uint64(0x7fffffffffffffff)
|
||||
if header.GasLimit > cap {
|
||||
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
|
||||
capacity := uint64(0x7fffffffffffffff)
|
||||
if header.GasLimit > capacity {
|
||||
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, capacity)
|
||||
}
|
||||
// Verify that the gasUsed is <= 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
|
||||
if !p.fakeDiff {
|
||||
inturn := snap.inturn(header.Number.Uint64(), signer)
|
||||
inturn := snap.inturn(signer)
|
||||
if inturn && header.Difficulty.Cmp(diffInTurn) != 0 {
|
||||
return errWrongDifficulty
|
||||
}
|
||||
@@ -626,8 +627,7 @@ func (p *Parlia) Prepare(chain consensus.ChainReader, header *types.Header) erro
|
||||
if parent == nil {
|
||||
return consensus.ErrUnknownAncestor
|
||||
}
|
||||
|
||||
header.Time = parent.Time + p.config.Period
|
||||
header.Time = p.blockTimeForRamanujanFork(snap, header, parent)
|
||||
if 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
|
||||
delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple
|
||||
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))
|
||||
}
|
||||
delay := p.delayForRamanujanFork(snap, header)
|
||||
|
||||
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
|
||||
// current signer.
|
||||
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(diffNoTurn)
|
||||
@@ -907,7 +900,7 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash) ([]common.Address,
|
||||
}
|
||||
// call
|
||||
msgData := (hexutil.Bytes)(data)
|
||||
toAddress := common.HexToAddress(ValidatorContract)
|
||||
toAddress := common.HexToAddress(systemcontracts.ValidatorContract)
|
||||
gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
|
||||
result, err := p.ethAPI.Call(ctx, ethapi.CallArgs{
|
||||
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.AddBalance(coinbase, balance)
|
||||
|
||||
doDistributeSysReward := state.GetBalance(common.HexToAddress(SystemRewardContract)).Cmp(maxSystemBalance) < 0
|
||||
doDistributeSysReward := state.GetBalance(common.HexToAddress(systemcontracts.SystemRewardContract)).Cmp(maxSystemBalance) < 0
|
||||
if doDistributeSysReward {
|
||||
var rewards = new(big.Int)
|
||||
rewards = rewards.Rsh(balance, systemRewardPercent)
|
||||
@@ -977,7 +970,7 @@ func (p *Parlia) slash(spoiledVal common.Address, state *state.StateDB, header *
|
||||
return err
|
||||
}
|
||||
// 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
|
||||
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 := "init"
|
||||
// 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
|
||||
data, err := p.validatorSetABI.Pack(method)
|
||||
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,
|
||||
txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error {
|
||||
// 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
|
||||
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
|
||||
}
|
||||
// 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
|
||||
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")
|
||||
}
|
||||
actualTx := (*receivedTxs)[0]
|
||||
if bytes.Compare(p.signer.Hash(actualTx).Bytes(), expectedHash.Bytes()) != 0 {
|
||||
return errors.New(fmt.Sprintf("expected tx hash %v, get %v", expectedHash.String(), actualTx.Hash().String()))
|
||||
if !bytes.Equal(p.signer.Hash(actualTx).Bytes(), expectedHash.Bytes()) {
|
||||
return fmt.Errorf("expected tx hash %v, get %v", expectedHash.String(), actualTx.Hash().String())
|
||||
}
|
||||
expectedTx = actualTx
|
||||
// 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
|
||||
type chainContext struct {
|
||||
Chain consensus.ChainReader
|
||||
@@ -1194,4 +1219,3 @@ func applyMessage(
|
||||
}
|
||||
return msg.Gas() - returnGas, err
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
@@ -57,7 +56,7 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
|
||||
return validators[idx]
|
||||
}
|
||||
|
||||
downDelay := time.Duration(0)
|
||||
downDelay := uint64(0)
|
||||
for h := 1; h <= downBlocks; h++ {
|
||||
if limit := uint64(totalValidators/2 + 1); uint64(h) >= limit {
|
||||
delete(recents, uint64(h)-limit)
|
||||
@@ -73,7 +72,7 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
|
||||
if len(candidates) == 0 {
|
||||
panic("can not test such case")
|
||||
}
|
||||
idx, delay := producerBlockDelay(candidates, totalValidators)
|
||||
idx, delay := producerBlockDelay(candidates, h, totalValidators)
|
||||
downDelay = downDelay + delay
|
||||
recents[uint64(h)] = idx
|
||||
} 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",
|
||||
downDelay/time.Duration(downBlocks), totalValidators, downValidators)
|
||||
downDelay/uint64(downBlocks), totalValidators, downValidators)
|
||||
|
||||
for i := 0; i < downValidators; i++ {
|
||||
validators[down[i]] = true
|
||||
}
|
||||
|
||||
recoverDelay := time.Duration(0)
|
||||
recoverDelay := uint64(0)
|
||||
lastseen := downBlocks
|
||||
for h := downBlocks + 1; h <= downBlocks+recoverBlocks; h++ {
|
||||
if limit := uint64(totalValidators/2 + 1); uint64(h) >= limit {
|
||||
@@ -105,7 +104,7 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
|
||||
if len(candidates) == 0 {
|
||||
panic("can not test such case")
|
||||
}
|
||||
idx, delay := producerBlockDelay(candidates, totalValidators)
|
||||
idx, delay := producerBlockDelay(candidates, h, totalValidators)
|
||||
recoverDelay = recoverDelay + delay
|
||||
recents[uint64(h)] = idx
|
||||
} else {
|
||||
@@ -116,18 +115,28 @@ func simulateValidatorOutOfService(totalValidators int, downValidators int) {
|
||||
recoverDelay, downValidators, lastseen)
|
||||
}
|
||||
|
||||
func producerBlockDelay(candidates map[int]bool, numOfValidators int) (int, time.Duration) {
|
||||
minDur := time.Duration(0)
|
||||
minIdx := 0
|
||||
wiggle := time.Duration(numOfValidators/2+1) * wiggleTime
|
||||
for idx := range candidates {
|
||||
sleepTime := rand.Int63n(int64(wiggle))
|
||||
if int64(minDur) < sleepTime {
|
||||
minDur = time.Duration(rand.Int63n(int64(wiggle)))
|
||||
minIdx = idx
|
||||
func producerBlockDelay(candidates map[int]bool, height, numOfValidators int) (int, uint64) {
|
||||
|
||||
s := rand.NewSource(int64(height))
|
||||
r := rand.New(s)
|
||||
n := numOfValidators
|
||||
backOffSteps := make([]int, 0, n)
|
||||
for idx := 0; idx < n; idx++ {
|
||||
backOffSteps = append(backOffSteps, 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 {
|
||||
|
||||
44
consensus/parlia/ramanujanfork.go
Normal file
44
consensus/parlia/ramanujanfork.go
Normal 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
|
||||
}
|
||||
@@ -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.
|
||||
func (s *Snapshot) inturn(number uint64, validator common.Address) bool {
|
||||
func (s *Snapshot) inturn(validator common.Address) bool {
|
||||
validators := s.validators()
|
||||
offset := number % uint64(len(validators))
|
||||
offset := (s.Number + 1) % uint64(len(validators))
|
||||
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 {
|
||||
validators := s.validators()
|
||||
index := (s.Number + 1) % uint64(len(validators))
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||
"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/vm"
|
||||
"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 {
|
||||
misc.ApplyDAOHardFork(statedb)
|
||||
}
|
||||
systemcontracts.UpgradeBuildInSystemContract(config, b.header.Number, statedb)
|
||||
// Execute any user modifications to the block
|
||||
if gen != nil {
|
||||
gen(i, b)
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"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/crypto"
|
||||
"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.
|
||||
stored := rawdb.ReadCanonicalHash(db, 0)
|
||||
systemcontracts.GenesisHash = stored
|
||||
if (stored == common.Hash{}) {
|
||||
if genesis == nil {
|
||||
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
|
||||
// config is supplied. These chains would get AllProtocolChanges (and a compat error)
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -252,6 +256,10 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
|
||||
return params.RinkebyChainConfig
|
||||
case ghash == params.GoerliGenesisHash:
|
||||
return params.GoerliChainConfig
|
||||
case ghash == params.ChapelGenesisHash:
|
||||
return params.ChapelChainConfig
|
||||
case ghash == params.RialtoGenesisHash:
|
||||
return params.RialtoChainConfig
|
||||
default:
|
||||
return params.AllEthashProtocolChanges
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||
"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/vm"
|
||||
"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 {
|
||||
misc.ApplyDAOHardFork(statedb)
|
||||
}
|
||||
// Handle upgrade build-in system contract code
|
||||
systemcontracts.UpgradeBuildInSystemContract(p.config, block.Number(), statedb)
|
||||
// Iterate over and process the individual transactions
|
||||
posa, isPoSA := p.engine.(consensus.PoSA)
|
||||
commonTxs := make([]*types.Transaction, 0, len(block.Transactions()))
|
||||
|
||||
15
core/systemcontracts/const.go
Normal file
15
core/systemcontracts/const.go
Normal 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"
|
||||
)
|
||||
273
core/systemcontracts/upgrade.go
Normal file
273
core/systemcontracts/upgrade.go
Normal file
File diff suppressed because one or more lines are too long
@@ -9,6 +9,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
uint64TypeLength uint64 = 8
|
||||
precompileContractInputMetaDataLength uint64 = 32
|
||||
consensusStateLengthBytesLength uint64 = 32
|
||||
|
||||
@@ -20,7 +21,7 @@ const (
|
||||
// consensus state length | consensus state | tendermint header |
|
||||
// 32 bytes | | |
|
||||
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 {
|
||||
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")
|
||||
}
|
||||
|
||||
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-8 : precompileContractInputMetaDataLength])
|
||||
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-uint64TypeLength : 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))
|
||||
}
|
||||
@@ -83,7 +84,7 @@ func (c *tmHeaderValidate) Run(input []byte) (result []byte, err error) {
|
||||
copy(lengthBytes[:1], []byte{0x01})
|
||||
}
|
||||
consensusStateBytesLength := uint64(len(consensusStateBytes))
|
||||
binary.BigEndian.PutUint64(lengthBytes[tmHeaderValidateResultMetaDataLength-8:], consensusStateBytesLength)
|
||||
binary.BigEndian.PutUint64(lengthBytes[tmHeaderValidateResultMetaDataLength-uint64TypeLength:], consensusStateBytesLength)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-8 : precompileContractInputMetaDataLength])
|
||||
payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-uint64TypeLength : 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))
|
||||
}
|
||||
@@ -129,6 +130,6 @@ func (c *iavlMerkleProofValidate) Run(input []byte) (result []byte, err error) {
|
||||
}
|
||||
|
||||
result = make([]byte, merkleProofValidateResultLength)
|
||||
binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-8:], 0x01)
|
||||
binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-uint64TypeLength:], 0x01)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) {
|
||||
"cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc000000174876e80049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb7" +
|
||||
"87a5b314a298e000000174876e80004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b6000000174876e8004034b37ce" +
|
||||
"da8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e8000000174876e800")
|
||||
require.NoError(t, err)
|
||||
|
||||
cs, err := lightclient.DecodeConsensusState(consensusStateBytes)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -226,17 +226,11 @@ func (kvmp *KeyValueMerkleProof) Validate() bool {
|
||||
|
||||
if len(kvmp.Value) == 0 {
|
||||
err := prt.VerifyAbsence(kvmp.Proof, kvmp.AppHash, kp.String())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return err == nil
|
||||
}
|
||||
|
||||
err := prt.VerifyValue(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.Value)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// input:
|
||||
|
||||
@@ -681,11 +681,12 @@ func (f *BlockFetcher) insert(peer string, block *types.Block) {
|
||||
go f.broadcastBlock(block, true)
|
||||
|
||||
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:
|
||||
// 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)
|
||||
return
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -132,13 +132,12 @@
|
||||
// If the call was a contract call, retrieve the gas usage and output
|
||||
if (call.gas !== undefined) {
|
||||
call.gasUsed = '0x' + bigInt(call.gasIn - call.gasCost + call.gas - log.getGas()).toString(16);
|
||||
|
||||
var ret = log.stack.peek(0);
|
||||
if (!ret.equals(0)) {
|
||||
call.output = toHex(log.memory.slice(call.outOff, call.outOff + call.outLen));
|
||||
} else if (call.error === undefined) {
|
||||
call.error = "internal failure"; // TODO(karalabe): surface these faults somehow
|
||||
}
|
||||
}
|
||||
var ret = log.stack.peek(0);
|
||||
if (!ret.equals(0)) {
|
||||
call.output = toHex(log.memory.slice(call.outOff, call.outOff + call.outLen));
|
||||
} else if (call.error === undefined) {
|
||||
call.error = "internal failure"; // TODO(karalabe): surface these faults somehow
|
||||
}
|
||||
delete call.gasIn; delete call.gasCost;
|
||||
delete call.outOff; delete call.outLen;
|
||||
@@ -208,7 +207,7 @@
|
||||
} else if (ctx.error !== undefined) {
|
||||
result.error = ctx.error;
|
||||
}
|
||||
if (result.error !== undefined) {
|
||||
if (result.error !== undefined && (result.error !== "execution reverted" || result.output ==="0x")) {
|
||||
delete result.output;
|
||||
}
|
||||
return this.finalize(result);
|
||||
|
||||
72
eth/tracers/testdata/call_tracer_inner_instafail.json
vendored
Normal file
72
eth/tracers/testdata/call_tracer_inner_instafail.json
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"genesis": {
|
||||
"difficulty": "117067574",
|
||||
"extraData": "0xd783010502846765746887676f312e372e33856c696e7578",
|
||||
"gasLimit": "4712380",
|
||||
"hash": "0xe05db05eeb3f288041ecb10a787df121c0ed69499355716e17c307de313a4486",
|
||||
"miner": "0x0c062b329265c965deef1eede55183b3acb8f611",
|
||||
"mixHash": "0xb669ae39118a53d2c65fd3b1e1d3850dd3f8c6842030698ed846a2762d68b61d",
|
||||
"nonce": "0x2b469722b8e28c45",
|
||||
"number": "24973",
|
||||
"stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369",
|
||||
"timestamp": "1479891145",
|
||||
"totalDifficulty": "1892250259406",
|
||||
"alloc": {
|
||||
"0x6c06b16512b332e6cd8293a2974872674716ce18": {
|
||||
"balance": "0x0",
|
||||
"nonce": "1",
|
||||
"code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d146036575b6000565b34600057604e60048080359060200190919050506050565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f19350505050505b5056",
|
||||
"storage": {}
|
||||
},
|
||||
"0x66fdfd05e46126a07465ad24e40cc0597bc1ef31": {
|
||||
"balance": "0x229ebbb36c3e0f20",
|
||||
"nonce": "3",
|
||||
"code": "0x",
|
||||
"storage": {}
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"chainId": 3,
|
||||
"homesteadBlock": 0,
|
||||
"daoForkSupport": true,
|
||||
"eip150Block": 0,
|
||||
"eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
|
||||
"eip155Block": 10,
|
||||
"eip158Block": 10,
|
||||
"byzantiumBlock": 1700000,
|
||||
"constantinopleBlock": 4230000,
|
||||
"petersburgBlock": 4939394,
|
||||
"istanbulBlock": 6485846,
|
||||
"muirGlacierBlock": 7117117,
|
||||
"ethash": {}
|
||||
}
|
||||
},
|
||||
"context": {
|
||||
"number": "24974",
|
||||
"difficulty": "117067574",
|
||||
"timestamp": "1479891162",
|
||||
"gasLimit": "4712388",
|
||||
"miner": "0xc822ef32e6d26e170b70cf761e204c1806265914"
|
||||
},
|
||||
"input": "0xf889038504a81557008301f97e946c06b16512b332e6cd8293a2974872674716ce1880a42e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b1600002aa0e2a6558040c5d72bc59f2fb62a38993a314c849cd22fb393018d2c5af3112095a01bdb6d7ba32263ccc2ecc880d38c49d9f0c5a72d8b7908e3122b31356d349745",
|
||||
"result": {
|
||||
"type": "CALL",
|
||||
"from": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
|
||||
"to": "0x6c06b16512b332e6cd8293a2974872674716ce18",
|
||||
"value": "0x0",
|
||||
"gas": "0x1a466",
|
||||
"gasUsed": "0x1dc6",
|
||||
"input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000",
|
||||
"output": "0x",
|
||||
"calls": [
|
||||
{
|
||||
"type": "CALL",
|
||||
"from": "0x6c06b16512b332e6cd8293a2974872674716ce18",
|
||||
"to": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
|
||||
"value": "0x14d1120d7b160000",
|
||||
"error":"internal failure",
|
||||
"input": "0x"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
64
eth/tracers/testdata/call_tracer_revert_reason.json
vendored
Normal file
64
eth/tracers/testdata/call_tracer_revert_reason.json
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -269,9 +269,31 @@ func TestCallTracer(t *testing.T) {
|
||||
t.Fatalf("failed to unmarshal trace result: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(ret, test.Result) {
|
||||
if !jsonEqual(ret, test.Result) {
|
||||
// uncomment this for easier debugging
|
||||
//have, _ := json.MarshalIndent(ret, "", " ")
|
||||
//want, _ := json.MarshalIndent(test.Result, "", " ")
|
||||
//t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", string(have), string(want))
|
||||
t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// jsonEqual is similar to reflect.DeepEqual, but does a 'bounce' via json prior to
|
||||
// comparison
|
||||
func jsonEqual(x, y interface{}) bool {
|
||||
xTrace := new(callTrace)
|
||||
yTrace := new(callTrace)
|
||||
if xj, err := json.Marshal(x); err == nil {
|
||||
json.Unmarshal(xj, xTrace)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
if yj, err := json.Marshal(y); err == nil {
|
||||
json.Unmarshal(yj, yTrace)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
return reflect.DeepEqual(xTrace, yTrace)
|
||||
}
|
||||
|
||||
3
go.mod
3
go.mod
@@ -72,17 +72,14 @@ require (
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
|
||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208
|
||||
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/sync v0.0.0-20190911185100-cd5d95a43a6e
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
|
||||
golang.org/x/text v0.3.2
|
||||
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
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9
|
||||
gopkg.in/urfave/cli.v1 v1.20.0
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc // indirect
|
||||
)
|
||||
|
||||
5
go.sum
5
go.sum
@@ -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/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||
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/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
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/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
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/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
||||
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/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=
|
||||
@@ -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/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
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/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/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/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
|
||||
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/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/consensus/parlia"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"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/event"
|
||||
"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 {
|
||||
misc.ApplyDAOHardFork(env.state)
|
||||
}
|
||||
systemcontracts.UpgradeBuildInSystemContract(w.chainConfig, header.Number, env.state)
|
||||
// Accumulate the uncles for the current block
|
||||
uncles := make([]*types.Header, 0, 2)
|
||||
commitUncles := func(blocks map[common.Hash]*types.Block) {
|
||||
|
||||
@@ -31,6 +31,9 @@ var (
|
||||
RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d")
|
||||
RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177")
|
||||
GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
|
||||
|
||||
ChapelGenesisHash = common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34")
|
||||
RialtoGenesisHash = common.HexToHash("0xaa1c1e0af675e846942719466ab72822eff51ebf8462ead0897ae1240e3c0da1")
|
||||
)
|
||||
|
||||
// TrustedCheckpoints associates each known checkpoint with the genesis hash of
|
||||
@@ -210,21 +213,59 @@ var (
|
||||
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
|
||||
// and accepted by the Ethereum core developers into the Ethash consensus.
|
||||
//
|
||||
// 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), 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
|
||||
// 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), 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))
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
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)
|
||||
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
|
||||
Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"`
|
||||
@@ -346,7 +389,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, 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.HomesteadBlock,
|
||||
c.DAOForkBlock,
|
||||
@@ -359,6 +402,8 @@ func (c *ChainConfig) String() string {
|
||||
c.PetersburgBlock,
|
||||
c.IstanbulBlock,
|
||||
c.MuirGlacierBlock,
|
||||
c.RamanujanBlock,
|
||||
c.NielsBlock,
|
||||
engine,
|
||||
)
|
||||
}
|
||||
@@ -398,6 +443,26 @@ func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
|
||||
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.
|
||||
func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
|
||||
return isForked(c.MuirGlacierBlock, num)
|
||||
@@ -456,6 +521,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
|
||||
{"petersburgBlock", c.PetersburgBlock},
|
||||
{"istanbulBlock", c.IstanbulBlock},
|
||||
{"muirGlacierBlock", c.MuirGlacierBlock},
|
||||
{"ramanujanBlock", c.RamanujanBlock},
|
||||
} {
|
||||
if lastFork.name != "" {
|
||||
// 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) {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
VersionMajor = 1 // Major version component of the current release
|
||||
VersionMinor = 0 // Minor version component of the current release
|
||||
VersionPatch = 0 // Patch version component of the current release
|
||||
VersionMeta = "beta.1" // Version metadata to append to the version string
|
||||
VersionMajor = 1 // Major version component of the current release
|
||||
VersionMinor = 0 // Minor version component of the current release
|
||||
VersionPatch = 2 // Patch version component of the current release
|
||||
VersionMeta = "" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
// Version holds the textual version string.
|
||||
|
||||
Reference in New Issue
Block a user