This PR adds a new fork which disables EIP-1283. Internally it's called Petersburg,
but the genesis/config field is ConstantinopleFix.
The block numbers are:
    7280000 for Constantinople on Mainnet
    7280000 for ConstantinopleFix on Mainnet
    4939394 for ConstantinopleFix on Ropsten
    9999999 for ConstantinopleFix on Rinkeby (real number decided later)
This PR also defaults to using the same ConstantinopleFix number as whatever
Constantinople is set to. That is, it will default to mainnet behaviour if ConstantinopleFix
is not set.This means that for private networks which have already transitioned
to Constantinople, this PR will break the network unless ConstantinopleFix is
explicitly set!
		
	
			
		
			
				
	
	
		
			490 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			490 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2017 The go-ethereum Authors
 | |
| // This file is part of go-ethereum.
 | |
| //
 | |
| // go-ethereum is free software: you can redistribute it and/or modify
 | |
| // it under the terms of the GNU General Public License as published by
 | |
| // the Free Software Foundation, either version 3 of the License, or
 | |
| // (at your option) any later version.
 | |
| //
 | |
| // go-ethereum is distributed in the hope that it will be useful,
 | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | |
| // GNU General Public License for more details.
 | |
| //
 | |
| // You should have received a copy of the GNU General Public License
 | |
| // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
 | |
| 
 | |
| package main
 | |
| 
 | |
| import (
 | |
| 	"encoding/binary"
 | |
| 	"errors"
 | |
| 	"math"
 | |
| 	"math/big"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/ethereum/go-ethereum/common"
 | |
| 	"github.com/ethereum/go-ethereum/common/hexutil"
 | |
| 	math2 "github.com/ethereum/go-ethereum/common/math"
 | |
| 	"github.com/ethereum/go-ethereum/consensus/ethash"
 | |
| 	"github.com/ethereum/go-ethereum/core"
 | |
| 	"github.com/ethereum/go-ethereum/params"
 | |
| )
 | |
| 
 | |
| // alethGenesisSpec represents the genesis specification format used by the
 | |
| // C++ Ethereum implementation.
 | |
| type alethGenesisSpec struct {
 | |
| 	SealEngine string `json:"sealEngine"`
 | |
| 	Params     struct {
 | |
| 		AccountStartNonce       math2.HexOrDecimal64   `json:"accountStartNonce"`
 | |
| 		MaximumExtraDataSize    hexutil.Uint64         `json:"maximumExtraDataSize"`
 | |
| 		HomesteadForkBlock      hexutil.Uint64         `json:"homesteadForkBlock"`
 | |
| 		DaoHardforkBlock        math2.HexOrDecimal64   `json:"daoHardforkBlock"`
 | |
| 		EIP150ForkBlock         hexutil.Uint64         `json:"EIP150ForkBlock"`
 | |
| 		EIP158ForkBlock         hexutil.Uint64         `json:"EIP158ForkBlock"`
 | |
| 		ByzantiumForkBlock      hexutil.Uint64         `json:"byzantiumForkBlock"`
 | |
| 		ConstantinopleForkBlock hexutil.Uint64         `json:"constantinopleForkBlock"`
 | |
| 		MinGasLimit             hexutil.Uint64         `json:"minGasLimit"`
 | |
| 		MaxGasLimit             hexutil.Uint64         `json:"maxGasLimit"`
 | |
| 		TieBreakingGas          bool                   `json:"tieBreakingGas"`
 | |
| 		GasLimitBoundDivisor    math2.HexOrDecimal64   `json:"gasLimitBoundDivisor"`
 | |
| 		MinimumDifficulty       *hexutil.Big           `json:"minimumDifficulty"`
 | |
| 		DifficultyBoundDivisor  *math2.HexOrDecimal256 `json:"difficultyBoundDivisor"`
 | |
| 		DurationLimit           *math2.HexOrDecimal256 `json:"durationLimit"`
 | |
| 		BlockReward             *hexutil.Big           `json:"blockReward"`
 | |
| 		NetworkID               hexutil.Uint64         `json:"networkID"`
 | |
| 		ChainID                 hexutil.Uint64         `json:"chainID"`
 | |
| 		AllowFutureBlocks       bool                   `json:"allowFutureBlocks"`
 | |
| 	} `json:"params"`
 | |
| 
 | |
| 	Genesis struct {
 | |
| 		Nonce      hexutil.Bytes  `json:"nonce"`
 | |
| 		Difficulty *hexutil.Big   `json:"difficulty"`
 | |
| 		MixHash    common.Hash    `json:"mixHash"`
 | |
| 		Author     common.Address `json:"author"`
 | |
| 		Timestamp  hexutil.Uint64 `json:"timestamp"`
 | |
| 		ParentHash common.Hash    `json:"parentHash"`
 | |
| 		ExtraData  hexutil.Bytes  `json:"extraData"`
 | |
| 		GasLimit   hexutil.Uint64 `json:"gasLimit"`
 | |
| 	} `json:"genesis"`
 | |
| 
 | |
| 	Accounts map[common.UnprefixedAddress]*alethGenesisSpecAccount `json:"accounts"`
 | |
| }
 | |
| 
 | |
| // alethGenesisSpecAccount is the prefunded genesis account and/or precompiled
 | |
| // contract definition.
 | |
| type alethGenesisSpecAccount struct {
 | |
| 	Balance     *math2.HexOrDecimal256   `json:"balance"`
 | |
| 	Nonce       uint64                   `json:"nonce,omitempty"`
 | |
| 	Precompiled *alethGenesisSpecBuiltin `json:"precompiled,omitempty"`
 | |
| }
 | |
| 
 | |
| // alethGenesisSpecBuiltin is the precompiled contract definition.
 | |
| type alethGenesisSpecBuiltin struct {
 | |
| 	Name          string                         `json:"name,omitempty"`
 | |
| 	StartingBlock hexutil.Uint64                 `json:"startingBlock,omitempty"`
 | |
| 	Linear        *alethGenesisSpecLinearPricing `json:"linear,omitempty"`
 | |
| }
 | |
| 
 | |
| type alethGenesisSpecLinearPricing struct {
 | |
| 	Base uint64 `json:"base"`
 | |
| 	Word uint64 `json:"word"`
 | |
| }
 | |
| 
 | |
| // newAlethGenesisSpec converts a go-ethereum genesis block into a Aleth-specific
 | |
| // chain specification format.
 | |
| func newAlethGenesisSpec(network string, genesis *core.Genesis) (*alethGenesisSpec, error) {
 | |
| 	// Only ethash is currently supported between go-ethereum and aleth
 | |
| 	if genesis.Config.Ethash == nil {
 | |
| 		return nil, errors.New("unsupported consensus engine")
 | |
| 	}
 | |
| 	// Reconstruct the chain spec in Aleth format
 | |
| 	spec := &alethGenesisSpec{
 | |
| 		SealEngine: "Ethash",
 | |
| 	}
 | |
| 	// Some defaults
 | |
| 	spec.Params.AccountStartNonce = 0
 | |
| 	spec.Params.TieBreakingGas = false
 | |
| 	spec.Params.AllowFutureBlocks = false
 | |
| 	spec.Params.DaoHardforkBlock = 0
 | |
| 
 | |
| 	spec.Params.HomesteadForkBlock = (hexutil.Uint64)(genesis.Config.HomesteadBlock.Uint64())
 | |
| 	spec.Params.EIP150ForkBlock = (hexutil.Uint64)(genesis.Config.EIP150Block.Uint64())
 | |
| 	spec.Params.EIP158ForkBlock = (hexutil.Uint64)(genesis.Config.EIP158Block.Uint64())
 | |
| 
 | |
| 	// Byzantium
 | |
| 	if num := genesis.Config.ByzantiumBlock; num != nil {
 | |
| 		spec.setByzantium(num)
 | |
| 	}
 | |
| 	// Constantinople
 | |
| 	if num := genesis.Config.ConstantinopleBlock; num != nil {
 | |
| 		spec.setConstantinople(num)
 | |
| 	}
 | |
| 
 | |
| 	spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
 | |
| 	spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
 | |
| 	spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
 | |
| 	spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
 | |
| 	spec.Params.MaxGasLimit = (hexutil.Uint64)(math.MaxInt64)
 | |
| 	spec.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
 | |
| 	spec.Params.DifficultyBoundDivisor = (*math2.HexOrDecimal256)(params.DifficultyBoundDivisor)
 | |
| 	spec.Params.GasLimitBoundDivisor = (math2.HexOrDecimal64)(params.GasLimitBoundDivisor)
 | |
| 	spec.Params.DurationLimit = (*math2.HexOrDecimal256)(params.DurationLimit)
 | |
| 	spec.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
 | |
| 
 | |
| 	spec.Genesis.Nonce = (hexutil.Bytes)(make([]byte, 8))
 | |
| 	binary.LittleEndian.PutUint64(spec.Genesis.Nonce[:], genesis.Nonce)
 | |
| 
 | |
| 	spec.Genesis.MixHash = genesis.Mixhash
 | |
| 	spec.Genesis.Difficulty = (*hexutil.Big)(genesis.Difficulty)
 | |
| 	spec.Genesis.Author = genesis.Coinbase
 | |
| 	spec.Genesis.Timestamp = (hexutil.Uint64)(genesis.Timestamp)
 | |
| 	spec.Genesis.ParentHash = genesis.ParentHash
 | |
| 	spec.Genesis.ExtraData = (hexutil.Bytes)(genesis.ExtraData)
 | |
| 	spec.Genesis.GasLimit = (hexutil.Uint64)(genesis.GasLimit)
 | |
| 
 | |
| 	for address, account := range genesis.Alloc {
 | |
| 		spec.setAccount(address, account)
 | |
| 	}
 | |
| 
 | |
| 	spec.setPrecompile(1, &alethGenesisSpecBuiltin{Name: "ecrecover",
 | |
| 		Linear: &alethGenesisSpecLinearPricing{Base: 3000}})
 | |
| 	spec.setPrecompile(2, &alethGenesisSpecBuiltin{Name: "sha256",
 | |
| 		Linear: &alethGenesisSpecLinearPricing{Base: 60, Word: 12}})
 | |
| 	spec.setPrecompile(3, &alethGenesisSpecBuiltin{Name: "ripemd160",
 | |
| 		Linear: &alethGenesisSpecLinearPricing{Base: 600, Word: 120}})
 | |
| 	spec.setPrecompile(4, &alethGenesisSpecBuiltin{Name: "identity",
 | |
| 		Linear: &alethGenesisSpecLinearPricing{Base: 15, Word: 3}})
 | |
| 	if genesis.Config.ByzantiumBlock != nil {
 | |
| 		spec.setPrecompile(5, &alethGenesisSpecBuiltin{Name: "modexp",
 | |
| 			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64())})
 | |
| 		spec.setPrecompile(6, &alethGenesisSpecBuiltin{Name: "alt_bn128_G1_add",
 | |
| 			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()),
 | |
| 			Linear:        &alethGenesisSpecLinearPricing{Base: 500}})
 | |
| 		spec.setPrecompile(7, &alethGenesisSpecBuiltin{Name: "alt_bn128_G1_mul",
 | |
| 			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()),
 | |
| 			Linear:        &alethGenesisSpecLinearPricing{Base: 40000}})
 | |
| 		spec.setPrecompile(8, &alethGenesisSpecBuiltin{Name: "alt_bn128_pairing_product",
 | |
| 			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64())})
 | |
| 	}
 | |
| 	return spec, nil
 | |
| }
 | |
| 
 | |
| func (spec *alethGenesisSpec) setPrecompile(address byte, data *alethGenesisSpecBuiltin) {
 | |
| 	if spec.Accounts == nil {
 | |
| 		spec.Accounts = make(map[common.UnprefixedAddress]*alethGenesisSpecAccount)
 | |
| 	}
 | |
| 	addr := common.UnprefixedAddress(common.BytesToAddress([]byte{address}))
 | |
| 	if _, exist := spec.Accounts[addr]; !exist {
 | |
| 		spec.Accounts[addr] = &alethGenesisSpecAccount{}
 | |
| 	}
 | |
| 	spec.Accounts[addr].Precompiled = data
 | |
| }
 | |
| 
 | |
| func (spec *alethGenesisSpec) setAccount(address common.Address, account core.GenesisAccount) {
 | |
| 	if spec.Accounts == nil {
 | |
| 		spec.Accounts = make(map[common.UnprefixedAddress]*alethGenesisSpecAccount)
 | |
| 	}
 | |
| 
 | |
| 	a, exist := spec.Accounts[common.UnprefixedAddress(address)]
 | |
| 	if !exist {
 | |
| 		a = &alethGenesisSpecAccount{}
 | |
| 		spec.Accounts[common.UnprefixedAddress(address)] = a
 | |
| 	}
 | |
| 	a.Balance = (*math2.HexOrDecimal256)(account.Balance)
 | |
| 	a.Nonce = account.Nonce
 | |
| 
 | |
| }
 | |
| 
 | |
| func (spec *alethGenesisSpec) setByzantium(num *big.Int) {
 | |
| 	spec.Params.ByzantiumForkBlock = hexutil.Uint64(num.Uint64())
 | |
| }
 | |
| 
 | |
| func (spec *alethGenesisSpec) setConstantinople(num *big.Int) {
 | |
| 	spec.Params.ConstantinopleForkBlock = hexutil.Uint64(num.Uint64())
 | |
| }
 | |
| 
 | |
| // parityChainSpec is the chain specification format used by Parity.
 | |
| type parityChainSpec struct {
 | |
| 	Name    string `json:"name"`
 | |
| 	Datadir string `json:"dataDir"`
 | |
| 	Engine  struct {
 | |
| 		Ethash struct {
 | |
| 			Params struct {
 | |
| 				MinimumDifficulty      *hexutil.Big      `json:"minimumDifficulty"`
 | |
| 				DifficultyBoundDivisor *hexutil.Big      `json:"difficultyBoundDivisor"`
 | |
| 				DurationLimit          *hexutil.Big      `json:"durationLimit"`
 | |
| 				BlockReward            map[string]string `json:"blockReward"`
 | |
| 				DifficultyBombDelays   map[string]string `json:"difficultyBombDelays"`
 | |
| 				HomesteadTransition    hexutil.Uint64    `json:"homesteadTransition"`
 | |
| 				EIP100bTransition      hexutil.Uint64    `json:"eip100bTransition"`
 | |
| 			} `json:"params"`
 | |
| 		} `json:"Ethash"`
 | |
| 	} `json:"engine"`
 | |
| 
 | |
| 	Params struct {
 | |
| 		AccountStartNonce        hexutil.Uint64       `json:"accountStartNonce"`
 | |
| 		MaximumExtraDataSize     hexutil.Uint64       `json:"maximumExtraDataSize"`
 | |
| 		MinGasLimit              hexutil.Uint64       `json:"minGasLimit"`
 | |
| 		GasLimitBoundDivisor     math2.HexOrDecimal64 `json:"gasLimitBoundDivisor"`
 | |
| 		NetworkID                hexutil.Uint64       `json:"networkID"`
 | |
| 		ChainID                  hexutil.Uint64       `json:"chainID"`
 | |
| 		MaxCodeSize              hexutil.Uint64       `json:"maxCodeSize"`
 | |
| 		MaxCodeSizeTransition    hexutil.Uint64       `json:"maxCodeSizeTransition"`
 | |
| 		EIP98Transition          hexutil.Uint64       `json:"eip98Transition"`
 | |
| 		EIP150Transition         hexutil.Uint64       `json:"eip150Transition"`
 | |
| 		EIP160Transition         hexutil.Uint64       `json:"eip160Transition"`
 | |
| 		EIP161abcTransition      hexutil.Uint64       `json:"eip161abcTransition"`
 | |
| 		EIP161dTransition        hexutil.Uint64       `json:"eip161dTransition"`
 | |
| 		EIP155Transition         hexutil.Uint64       `json:"eip155Transition"`
 | |
| 		EIP140Transition         hexutil.Uint64       `json:"eip140Transition"`
 | |
| 		EIP211Transition         hexutil.Uint64       `json:"eip211Transition"`
 | |
| 		EIP214Transition         hexutil.Uint64       `json:"eip214Transition"`
 | |
| 		EIP658Transition         hexutil.Uint64       `json:"eip658Transition"`
 | |
| 		EIP145Transition         hexutil.Uint64       `json:"eip145Transition"`
 | |
| 		EIP1014Transition        hexutil.Uint64       `json:"eip1014Transition"`
 | |
| 		EIP1052Transition        hexutil.Uint64       `json:"eip1052Transition"`
 | |
| 		EIP1283Transition        hexutil.Uint64       `json:"eip1283Transition"`
 | |
| 		EIP1283DisableTransition hexutil.Uint64       `json:"eip1283DisableTransition"`
 | |
| 	} `json:"params"`
 | |
| 
 | |
| 	Genesis struct {
 | |
| 		Seal struct {
 | |
| 			Ethereum struct {
 | |
| 				Nonce   hexutil.Bytes `json:"nonce"`
 | |
| 				MixHash hexutil.Bytes `json:"mixHash"`
 | |
| 			} `json:"ethereum"`
 | |
| 		} `json:"seal"`
 | |
| 
 | |
| 		Difficulty *hexutil.Big   `json:"difficulty"`
 | |
| 		Author     common.Address `json:"author"`
 | |
| 		Timestamp  hexutil.Uint64 `json:"timestamp"`
 | |
| 		ParentHash common.Hash    `json:"parentHash"`
 | |
| 		ExtraData  hexutil.Bytes  `json:"extraData"`
 | |
| 		GasLimit   hexutil.Uint64 `json:"gasLimit"`
 | |
| 	} `json:"genesis"`
 | |
| 
 | |
| 	Nodes    []string                                             `json:"nodes"`
 | |
| 	Accounts map[common.UnprefixedAddress]*parityChainSpecAccount `json:"accounts"`
 | |
| }
 | |
| 
 | |
| // parityChainSpecAccount is the prefunded genesis account and/or precompiled
 | |
| // contract definition.
 | |
| type parityChainSpecAccount struct {
 | |
| 	Balance math2.HexOrDecimal256   `json:"balance"`
 | |
| 	Nonce   math2.HexOrDecimal64    `json:"nonce,omitempty"`
 | |
| 	Builtin *parityChainSpecBuiltin `json:"builtin,omitempty"`
 | |
| }
 | |
| 
 | |
| // parityChainSpecBuiltin is the precompiled contract definition.
 | |
| type parityChainSpecBuiltin struct {
 | |
| 	Name       string                  `json:"name,omitempty"`
 | |
| 	ActivateAt math2.HexOrDecimal64    `json:"activate_at,omitempty"`
 | |
| 	Pricing    *parityChainSpecPricing `json:"pricing,omitempty"`
 | |
| }
 | |
| 
 | |
| // parityChainSpecPricing represents the different pricing models that builtin
 | |
| // contracts might advertise using.
 | |
| type parityChainSpecPricing struct {
 | |
| 	Linear       *parityChainSpecLinearPricing       `json:"linear,omitempty"`
 | |
| 	ModExp       *parityChainSpecModExpPricing       `json:"modexp,omitempty"`
 | |
| 	AltBnPairing *parityChainSpecAltBnPairingPricing `json:"alt_bn128_pairing,omitempty"`
 | |
| }
 | |
| 
 | |
| type parityChainSpecLinearPricing struct {
 | |
| 	Base uint64 `json:"base"`
 | |
| 	Word uint64 `json:"word"`
 | |
| }
 | |
| 
 | |
| type parityChainSpecModExpPricing struct {
 | |
| 	Divisor uint64 `json:"divisor"`
 | |
| }
 | |
| 
 | |
| type parityChainSpecAltBnPairingPricing struct {
 | |
| 	Base uint64 `json:"base"`
 | |
| 	Pair uint64 `json:"pair"`
 | |
| }
 | |
| 
 | |
| // newParityChainSpec converts a go-ethereum genesis block into a Parity specific
 | |
| // chain specification format.
 | |
| func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []string) (*parityChainSpec, error) {
 | |
| 	// Only ethash is currently supported between go-ethereum and Parity
 | |
| 	if genesis.Config.Ethash == nil {
 | |
| 		return nil, errors.New("unsupported consensus engine")
 | |
| 	}
 | |
| 	// Reconstruct the chain spec in Parity's format
 | |
| 	spec := &parityChainSpec{
 | |
| 		Name:    network,
 | |
| 		Nodes:   bootnodes,
 | |
| 		Datadir: strings.ToLower(network),
 | |
| 	}
 | |
| 	spec.Engine.Ethash.Params.BlockReward = make(map[string]string)
 | |
| 	spec.Engine.Ethash.Params.DifficultyBombDelays = make(map[string]string)
 | |
| 	// Frontier
 | |
| 	spec.Engine.Ethash.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
 | |
| 	spec.Engine.Ethash.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor)
 | |
| 	spec.Engine.Ethash.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit)
 | |
| 	spec.Engine.Ethash.Params.BlockReward["0x0"] = hexutil.EncodeBig(ethash.FrontierBlockReward)
 | |
| 
 | |
| 	// Homestead
 | |
| 	spec.Engine.Ethash.Params.HomesteadTransition = hexutil.Uint64(genesis.Config.HomesteadBlock.Uint64())
 | |
| 
 | |
| 	// Tangerine Whistle : 150
 | |
| 	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-608.md
 | |
| 	spec.Params.EIP150Transition = hexutil.Uint64(genesis.Config.EIP150Block.Uint64())
 | |
| 
 | |
| 	// Spurious Dragon: 155, 160, 161, 170
 | |
| 	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md
 | |
| 	spec.Params.EIP155Transition = hexutil.Uint64(genesis.Config.EIP155Block.Uint64())
 | |
| 	spec.Params.EIP160Transition = hexutil.Uint64(genesis.Config.EIP155Block.Uint64())
 | |
| 	spec.Params.EIP161abcTransition = hexutil.Uint64(genesis.Config.EIP158Block.Uint64())
 | |
| 	spec.Params.EIP161dTransition = hexutil.Uint64(genesis.Config.EIP158Block.Uint64())
 | |
| 
 | |
| 	// Byzantium
 | |
| 	if num := genesis.Config.ByzantiumBlock; num != nil {
 | |
| 		spec.setByzantium(num)
 | |
| 	}
 | |
| 	// Constantinople
 | |
| 	if num := genesis.Config.ConstantinopleBlock; num != nil {
 | |
| 		spec.setConstantinople(num)
 | |
| 	}
 | |
| 	// ConstantinopleFix (remove eip-1283)
 | |
| 	if num := genesis.Config.PetersburgBlock; num != nil {
 | |
| 		spec.setConstantinopleFix(num)
 | |
| 	}
 | |
| 
 | |
| 	spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
 | |
| 	spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
 | |
| 	spec.Params.GasLimitBoundDivisor = (math2.HexOrDecimal64)(params.GasLimitBoundDivisor)
 | |
| 	spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
 | |
| 	spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
 | |
| 	spec.Params.MaxCodeSize = params.MaxCodeSize
 | |
| 	// geth has it set from zero
 | |
| 	spec.Params.MaxCodeSizeTransition = 0
 | |
| 
 | |
| 	// Disable this one
 | |
| 	spec.Params.EIP98Transition = math.MaxInt64
 | |
| 
 | |
| 	spec.Genesis.Seal.Ethereum.Nonce = (hexutil.Bytes)(make([]byte, 8))
 | |
| 	binary.LittleEndian.PutUint64(spec.Genesis.Seal.Ethereum.Nonce[:], genesis.Nonce)
 | |
| 
 | |
| 	spec.Genesis.Seal.Ethereum.MixHash = (hexutil.Bytes)(genesis.Mixhash[:])
 | |
| 	spec.Genesis.Difficulty = (*hexutil.Big)(genesis.Difficulty)
 | |
| 	spec.Genesis.Author = genesis.Coinbase
 | |
| 	spec.Genesis.Timestamp = (hexutil.Uint64)(genesis.Timestamp)
 | |
| 	spec.Genesis.ParentHash = genesis.ParentHash
 | |
| 	spec.Genesis.ExtraData = (hexutil.Bytes)(genesis.ExtraData)
 | |
| 	spec.Genesis.GasLimit = (hexutil.Uint64)(genesis.GasLimit)
 | |
| 
 | |
| 	spec.Accounts = make(map[common.UnprefixedAddress]*parityChainSpecAccount)
 | |
| 	for address, account := range genesis.Alloc {
 | |
| 		bal := math2.HexOrDecimal256(*account.Balance)
 | |
| 
 | |
| 		spec.Accounts[common.UnprefixedAddress(address)] = &parityChainSpecAccount{
 | |
| 			Balance: bal,
 | |
| 			Nonce:   math2.HexOrDecimal64(account.Nonce),
 | |
| 		}
 | |
| 	}
 | |
| 	spec.setPrecompile(1, &parityChainSpecBuiltin{Name: "ecrecover",
 | |
| 		Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 3000}}})
 | |
| 
 | |
| 	spec.setPrecompile(2, &parityChainSpecBuiltin{
 | |
| 		Name: "sha256", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 60, Word: 12}},
 | |
| 	})
 | |
| 	spec.setPrecompile(3, &parityChainSpecBuiltin{
 | |
| 		Name: "ripemd160", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 600, Word: 120}},
 | |
| 	})
 | |
| 	spec.setPrecompile(4, &parityChainSpecBuiltin{
 | |
| 		Name: "identity", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 15, Word: 3}},
 | |
| 	})
 | |
| 	if genesis.Config.ByzantiumBlock != nil {
 | |
| 		blnum := math2.HexOrDecimal64(genesis.Config.ByzantiumBlock.Uint64())
 | |
| 		spec.setPrecompile(5, &parityChainSpecBuiltin{
 | |
| 			Name: "modexp", ActivateAt: blnum, Pricing: &parityChainSpecPricing{ModExp: &parityChainSpecModExpPricing{Divisor: 20}},
 | |
| 		})
 | |
| 		spec.setPrecompile(6, &parityChainSpecBuiltin{
 | |
| 			Name: "alt_bn128_add", ActivateAt: blnum, Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 500}},
 | |
| 		})
 | |
| 		spec.setPrecompile(7, &parityChainSpecBuiltin{
 | |
| 			Name: "alt_bn128_mul", ActivateAt: blnum, Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 40000}},
 | |
| 		})
 | |
| 		spec.setPrecompile(8, &parityChainSpecBuiltin{
 | |
| 			Name: "alt_bn128_pairing", ActivateAt: blnum, Pricing: &parityChainSpecPricing{AltBnPairing: &parityChainSpecAltBnPairingPricing{Base: 100000, Pair: 80000}},
 | |
| 		})
 | |
| 	}
 | |
| 	return spec, nil
 | |
| }
 | |
| 
 | |
| func (spec *parityChainSpec) setPrecompile(address byte, data *parityChainSpecBuiltin) {
 | |
| 	if spec.Accounts == nil {
 | |
| 		spec.Accounts = make(map[common.UnprefixedAddress]*parityChainSpecAccount)
 | |
| 	}
 | |
| 	a := common.UnprefixedAddress(common.BytesToAddress([]byte{address}))
 | |
| 	if _, exist := spec.Accounts[a]; !exist {
 | |
| 		spec.Accounts[a] = &parityChainSpecAccount{}
 | |
| 	}
 | |
| 	spec.Accounts[a].Builtin = data
 | |
| }
 | |
| 
 | |
| func (spec *parityChainSpec) setByzantium(num *big.Int) {
 | |
| 	spec.Engine.Ethash.Params.BlockReward[hexutil.EncodeBig(num)] = hexutil.EncodeBig(ethash.ByzantiumBlockReward)
 | |
| 	spec.Engine.Ethash.Params.DifficultyBombDelays[hexutil.EncodeBig(num)] = hexutil.EncodeUint64(3000000)
 | |
| 	n := hexutil.Uint64(num.Uint64())
 | |
| 	spec.Engine.Ethash.Params.EIP100bTransition = n
 | |
| 	spec.Params.EIP140Transition = n
 | |
| 	spec.Params.EIP211Transition = n
 | |
| 	spec.Params.EIP214Transition = n
 | |
| 	spec.Params.EIP658Transition = n
 | |
| }
 | |
| 
 | |
| func (spec *parityChainSpec) setConstantinople(num *big.Int) {
 | |
| 	spec.Engine.Ethash.Params.BlockReward[hexutil.EncodeBig(num)] = hexutil.EncodeBig(ethash.ConstantinopleBlockReward)
 | |
| 	spec.Engine.Ethash.Params.DifficultyBombDelays[hexutil.EncodeBig(num)] = hexutil.EncodeUint64(2000000)
 | |
| 	n := hexutil.Uint64(num.Uint64())
 | |
| 	spec.Params.EIP145Transition = n
 | |
| 	spec.Params.EIP1014Transition = n
 | |
| 	spec.Params.EIP1052Transition = n
 | |
| 	spec.Params.EIP1283Transition = n
 | |
| }
 | |
| 
 | |
| func (spec *parityChainSpec) setConstantinopleFix(num *big.Int) {
 | |
| 	spec.Params.EIP1283DisableTransition = hexutil.Uint64(num.Uint64())
 | |
| }
 | |
| 
 | |
| // pyEthereumGenesisSpec represents the genesis specification format used by the
 | |
| // Python Ethereum implementation.
 | |
| type pyEthereumGenesisSpec struct {
 | |
| 	Nonce      hexutil.Bytes     `json:"nonce"`
 | |
| 	Timestamp  hexutil.Uint64    `json:"timestamp"`
 | |
| 	ExtraData  hexutil.Bytes     `json:"extraData"`
 | |
| 	GasLimit   hexutil.Uint64    `json:"gasLimit"`
 | |
| 	Difficulty *hexutil.Big      `json:"difficulty"`
 | |
| 	Mixhash    common.Hash       `json:"mixhash"`
 | |
| 	Coinbase   common.Address    `json:"coinbase"`
 | |
| 	Alloc      core.GenesisAlloc `json:"alloc"`
 | |
| 	ParentHash common.Hash       `json:"parentHash"`
 | |
| }
 | |
| 
 | |
| // newPyEthereumGenesisSpec converts a go-ethereum genesis block into a Parity specific
 | |
| // chain specification format.
 | |
| func newPyEthereumGenesisSpec(network string, genesis *core.Genesis) (*pyEthereumGenesisSpec, error) {
 | |
| 	// Only ethash is currently supported between go-ethereum and pyethereum
 | |
| 	if genesis.Config.Ethash == nil {
 | |
| 		return nil, errors.New("unsupported consensus engine")
 | |
| 	}
 | |
| 	spec := &pyEthereumGenesisSpec{
 | |
| 		Timestamp:  (hexutil.Uint64)(genesis.Timestamp),
 | |
| 		ExtraData:  genesis.ExtraData,
 | |
| 		GasLimit:   (hexutil.Uint64)(genesis.GasLimit),
 | |
| 		Difficulty: (*hexutil.Big)(genesis.Difficulty),
 | |
| 		Mixhash:    genesis.Mixhash,
 | |
| 		Coinbase:   genesis.Coinbase,
 | |
| 		Alloc:      genesis.Alloc,
 | |
| 		ParentHash: genesis.ParentHash,
 | |
| 	}
 | |
| 	spec.Nonce = (hexutil.Bytes)(make([]byte, 8))
 | |
| 	binary.LittleEndian.PutUint64(spec.Nonce[:], genesis.Nonce)
 | |
| 
 | |
| 	return spec, nil
 | |
| }
 |