Skip to content

Commit

Permalink
Merge pull request #19 from ethoxy/feat/eip-articulation-multi
Browse files Browse the repository at this point in the history
Articulate EIP parameters and feature implementations
  • Loading branch information
sorpaas committed Jan 29, 2019
2 parents 8676543 + da85a44 commit 29e583b
Show file tree
Hide file tree
Showing 24 changed files with 958 additions and 267 deletions.
4 changes: 2 additions & 2 deletions cmd/puppeth/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ func (spec *parityChainSpec) setPrecompile(address byte, data *parityChainSpecBu
}

func (spec *parityChainSpec) setByzantium(num *big.Int) {
spec.Engine.Ethash.Params.BlockReward[hexutil.EncodeBig(num)] = hexutil.EncodeBig(ethash.ByzantiumBlockReward)
spec.Engine.Ethash.Params.BlockReward[hexutil.EncodeBig(num)] = hexutil.EncodeBig(ethash.EIP649FBlockReward)
spec.Engine.Ethash.Params.DifficultyBombDelays[hexutil.EncodeBig(num)] = hexutil.EncodeUint64(3000000)
n := hexutil.Uint64(num.Uint64())
spec.Engine.Ethash.Params.EIP100bTransition = n
Expand All @@ -432,7 +432,7 @@ func (spec *parityChainSpec) setByzantium(num *big.Int) {
}

func (spec *parityChainSpec) setConstantinople(num *big.Int) {
spec.Engine.Ethash.Params.BlockReward[hexutil.EncodeBig(num)] = hexutil.EncodeBig(ethash.ConstantinopleBlockReward)
spec.Engine.Ethash.Params.BlockReward[hexutil.EncodeBig(num)] = hexutil.EncodeBig(ethash.EIP1234FBlockReward)
spec.Engine.Ethash.Params.DifficultyBombDelays[hexutil.EncodeBig(num)] = hexutil.EncodeUint64(2000000)
n := hexutil.Uint64(num.Uint64())
spec.Params.EIP145Transition = n
Expand Down
2 changes: 1 addition & 1 deletion consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro
// rewards given, and returns the final block.
func (c *Clique) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
// No block rewards in PoA, so the state remains as is and uncles are dropped
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.Root = state.IntermediateRoot(chain.Config().IsEIP161F(header.Number))
header.UncleHash = types.CalcUncleHash(nil)

// Assemble and return the final block for sealing
Expand Down
56 changes: 32 additions & 24 deletions consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,30 @@ import (

// Ethash proof-of-work protocol constants.
var (
FrontierBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
ByzantiumBlockReward = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
ConstantinopleBlockReward = big.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople
SocialBlockReward = new(big.Int).Mul(big.NewInt(50), big.NewInt(1e+18)) // Block reward in wei for successfully mining a block upward for Ethereum Social
EthersocialBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block upward for Ethersocial Network
maxUncles = 2 // Maximum number of uncles allowed in a single block
allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks
DisinflationRateQuotient = big.NewInt(4) // Disinflation rate quotient for ECIP1017
DisinflationRateDivisor = big.NewInt(5) // Disinflation rate divisor for ECIP1017
ExpDiffPeriod = big.NewInt(100000) // Exponential diff period for ECIP1010

// calcDifficultyConstantinople is the difficulty adjustment algorithm for Constantinople.
FrontierBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
EIP649FBlockReward = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
EIP1234FBlockReward = big.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople
SocialBlockReward = new(big.Int).Mul(big.NewInt(50), big.NewInt(1e+18)) // Block reward in wei for successfully mining a block upward for Ethereum Social
EthersocialBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block upward for Ethersocial Network
maxUncles = 2 // Maximum number of uncles allowed in a single block
allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks
DisinflationRateQuotient = big.NewInt(4) // Disinflation rate quotient for ECIP1017
DisinflationRateDivisor = big.NewInt(5) // Disinflation rate divisor for ECIP1017
ExpDiffPeriod = big.NewInt(100000) // Exponential diff period for ECIP1010

// calcDifficultyEIP1234 is the difficulty adjustment algorithm for Constantinople.
// It returns the difficulty that a new block should have when created at time given the
// parent block's time and difficulty. The calculation uses the Byzantium rules, but with
// bomb offset 5M.
// Specification EIP-1234: https://eips.ethereum.org/EIPS/eip-1234
calcDifficultyConstantinople = makeDifficultyCalculator(big.NewInt(5000000))
calcDifficultyEIP1234 = makeDifficultyCalculator(big.NewInt(5000000))

// calcDifficultyByzantium is the difficulty adjustment algorithm. It returns
// calcDifficultyByzantium is the difficulty adjustment algorithm for Byzantium. It returns
// the difficulty that a new block should have when created at time given the
// parent block's time and difficulty. The calculation uses the Byzantium rules.
// Specification EIP-649: https://eips.ethereum.org/EIPS/eip-649
// Related meta-ish EIP-669: https://github.com/ethereum/EIPs/pull/669
// Note that this calculator also includes the change from EIP100.
calcDifficultyByzantium = makeDifficultyCalculator(big.NewInt(3000000))
)

Expand Down Expand Up @@ -320,13 +322,19 @@ func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Heade
switch {
case config.IsBombDisposal(next):
return calcDifficultyBombDisposal(time, parent)
case config.IsConstantinople(next):
return calcDifficultyConstantinople(time, parent)
case config.IsByzantium(next):
return calcDifficultyByzantium(time, parent)
case config.IsECIP1010(next):
return calcDifficultyECIP1010(time, parent, next, config.ECIP1010PauseBlock, config.ECIP1010Length)
case config.IsHomestead(next):
case config.IsEIP1234F(next):
return calcDifficultyEIP1234(time, parent)
case config.IsByzantium(next) || (config.IsEIP649F(next) && config.IsEIP100F(next)):
return calcDifficultyByzantium(time, parent)
case config.IsEIP649F(next):
// TODO (#22): calculator for only EIP649:difficulty bomb delay (without EIP100:mean time adjustment)
panic("not implemented")
case config.IsEIP100F(next):
// TODO (#23): calculator for only EIP100:mean time adjustment (without EIP649:difficulty bomb delay)
panic("not implemented")
case config.IsEIP2F(next):
return calcDifficultyHomestead(time, parent)
default:
return calcDifficultyFrontier(time, parent)
Expand Down Expand Up @@ -725,7 +733,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header)
func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
// Accumulate any block and uncle rewards and commit the final state root
accumulateRewards(chain.Config(), state, header, uncles)
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.Root = state.IntermediateRoot(chain.Config().IsEIP161F(header.Number))

// Header seems complete, assemble into a block and return
return types.NewBlock(header, txs, uncles, receipts), nil
Expand Down Expand Up @@ -766,11 +774,11 @@ var (
func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
// Select the correct block reward based on chain progression
blockReward := FrontierBlockReward
if config.IsByzantium(header.Number) {
blockReward = ByzantiumBlockReward
if config.IsEIP649F(header.Number) {
blockReward = EIP649FBlockReward
}
if config.IsConstantinople(header.Number) {
blockReward = ConstantinopleBlockReward
if config.IsEIP1234F(header.Number) {
blockReward = EIP1234FBlockReward
}
if config.IsSocial(header.Number) {
blockReward = SocialBlockReward
Expand Down
2 changes: 1 addition & 1 deletion core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat
}
// Validate the state root against the received state root and throw
// an error if they don't match.
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
if root := statedb.IntermediateRoot(v.config.IsEIP161F(header.Number)); header.Root != root {
return fmt.Errorf("invalid merkle root (remote: %x local: %x)", header.Root, root)
}
return nil
Expand Down
4 changes: 2 additions & 2 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
"github.com/hashicorp/golang-lru"
lru "github.com/hashicorp/golang-lru"
)

var (
Expand Down Expand Up @@ -946,7 +946,7 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
}
rawdb.WriteBlock(bc.db, block)

root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number()))
root, err := state.Commit(bc.chainConfig.IsEIP161F(block.Number()))
if err != nil {
return NonStatTy, err
}
Expand Down
4 changes: 2 additions & 2 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
block, _ := b.engine.Finalize(chainreader, b.header, statedb, b.txs, b.uncles, b.receipts)

// Write state changes to db
root, err := statedb.Commit(config.IsEIP158(b.header.Number))
root, err := statedb.Commit(config.IsEIP161F(b.header.Number))
if err != nil {
panic(fmt.Sprintf("state write error: %v", err))
}
Expand Down Expand Up @@ -233,7 +233,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
}

return &types.Header{
Root: state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())),
Root: state.IntermediateRoot(chain.Config().IsEIP161F(parent.Number())),
ParentHash: parent.Hash(),
Coinbase: parent.Coinbase(),
Difficulty: engine.CalcDifficulty(chain, time.Uint64(), &types.Header{
Expand Down
4 changes: 2 additions & 2 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
}
// Update the state with pending changes
var root []byte
if config.IsByzantium(header.Number) {
if config.IsEIP658F(header.Number) {
statedb.Finalise(true)
} else {
root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
root = statedb.IntermediateRoot(config.IsEIP161F(header.Number)).Bytes()
}
*usedGas += gas

Expand Down
4 changes: 2 additions & 2 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,11 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo
}
msg := st.msg
sender := vm.AccountRef(msg.From())
homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber)
eip2f := st.evm.ChainConfig().IsEIP2F(st.evm.BlockNumber)
contractCreation := msg.To() == nil

// Pay intrinsic gas
gas, err := IntrinsicGas(st.data, contractCreation, homestead)
gas, err := IntrinsicGas(st.data, contractCreation, eip2f)
if err != nil {
return nil, 0, false, err
}
Expand Down
8 changes: 4 additions & 4 deletions core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ type TxPool struct {

wg sync.WaitGroup // for shutdown sync

homestead bool
eip2f bool
}

// NewTxPool creates a new transaction pool to gather, sort and filter inbound
Expand Down Expand Up @@ -308,8 +308,8 @@ func (pool *TxPool) loop() {
case ev := <-pool.chainHeadCh:
if ev.Block != nil {
pool.mu.Lock()
if pool.chainconfig.IsHomestead(ev.Block.Number()) {
pool.homestead = true
if pool.chainconfig.IsEIP2F(ev.Block.Number()) {
pool.eip2f = true
}
pool.reset(head.Header(), ev.Block.Header())
head = ev.Block
Expand Down Expand Up @@ -618,7 +618,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 {
return ErrInsufficientFunds
}
intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead)
intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.eip2f)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion core/types/transaction_signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
switch {
case config.IsEIP155(blockNumber):
signer = NewEIP155Signer(config.ChainID)
case config.IsHomestead(blockNumber):
case config.IsEIP2F(blockNumber):
signer = HomesteadSigner{}
default:
signer = FrontierSigner{}
Expand Down
36 changes: 22 additions & 14 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,34 @@ type PrecompiledContract interface {
Run(input []byte) ([]byte, error) // Run runs the precompiled contract
}

// PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum
// contracts used in the Frontier and Homestead releases.
var PrecompiledContractsHomestead = map[common.Address]PrecompiledContract{
var basePrecompiledContracts = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
}

// PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum
// contracts used in the Byzantium release.
var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{},
common.BytesToAddress([]byte{6}): &bn256Add{},
common.BytesToAddress([]byte{7}): &bn256ScalarMul{},
common.BytesToAddress([]byte{8}): &bn256Pairing{},
// PrecompiledContractsForConfig returns a map containing valid precompiled contracts for a given point in a chain config.
func PrecompiledContractsForConfig(config *params.ChainConfig, bn *big.Int) map[common.Address]PrecompiledContract {
// Copying to a new map is necessary because assigning to the original map
// creates a memory reference. Further, setting the vals to nil in case of nonconfiguration causes
// a panic during tests because they run asynchronously (also a valid reason for using an explicit copy).
precompileds := make(map[common.Address]PrecompiledContract)
for k, v := range basePrecompiledContracts {
precompileds[k] = v
}
if config.IsEIP198F(bn) {
precompileds[common.BytesToAddress([]byte{5})] = &bigModExp{}
}
if config.IsEIP213F(bn) {
precompileds[common.BytesToAddress([]byte{6})] = &bn256Add{}
precompileds[common.BytesToAddress([]byte{7})] = &bn256ScalarMul{}
}
if config.IsEIP212F(bn) {
precompileds[common.BytesToAddress([]byte{8})] = &bn256Pairing{}
}

return precompileds
}

// RunPrecompiledContract runs and evaluates the output of a precompiled contract.
Expand Down
Loading

0 comments on commit 29e583b

Please sign in to comment.