Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Archimedes hard fork: Disable sha2, ripemd, blake2f precompiles #280

Merged
merged 15 commits into from May 9, 2023
19 changes: 15 additions & 4 deletions core/vm/contracts.go
Expand Up @@ -92,6 +92,11 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{9}): &blake2F{},
}

var PrecompiledContractsPlaceholder = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{4}): &dataCopy{},
}

// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
// contracts specified in EIP-2537. These are exported for testing purposes.
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
Expand All @@ -107,10 +112,11 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
}

var (
PrecompiledAddressesBerlin []common.Address
PrecompiledAddressesIstanbul []common.Address
PrecompiledAddressesByzantium []common.Address
PrecompiledAddressesHomestead []common.Address
PrecompiledAddressesPlaceholder []common.Address
PrecompiledAddressesBerlin []common.Address
PrecompiledAddressesIstanbul []common.Address
PrecompiledAddressesByzantium []common.Address
PrecompiledAddressesHomestead []common.Address
)

func init() {
Expand All @@ -126,11 +132,16 @@ func init() {
for k := range PrecompiledContractsBerlin {
PrecompiledAddressesBerlin = append(PrecompiledAddressesBerlin, k)
}
for k := range PrecompiledContractsPlaceholder {
PrecompiledAddressesPlaceholder = append(PrecompiledAddressesPlaceholder, k)
}
}

// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules params.Rules) []common.Address {
switch {
case rules.IsPlaceholder:
return PrecompiledAddressesPlaceholder
case rules.IsBerlin:
return PrecompiledAddressesBerlin
case rules.IsIstanbul:
Expand Down
2 changes: 2 additions & 0 deletions core/vm/evm.go
Expand Up @@ -46,6 +46,8 @@ type (
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
var precompiles map[common.Address]PrecompiledContract
switch {
case evm.chainRules.IsPlaceholder:
precompiles = PrecompiledContractsPlaceholder
case evm.chainRules.IsBerlin:
precompiles = PrecompiledContractsBerlin
case evm.chainRules.IsIstanbul:
Expand Down
1 change: 1 addition & 0 deletions core/vm/runtime/runtime.go
Expand Up @@ -68,6 +68,7 @@ func setDefaults(cfg *Config) {
MuirGlacierBlock: new(big.Int),
BerlinBlock: new(big.Int),
LondonBlock: new(big.Int),
PlaceholderBlock: new(big.Int),
}
}

Expand Down
32 changes: 32 additions & 0 deletions eth/tracers/js/tracer_test.go
Expand Up @@ -201,6 +201,7 @@ func TestIsPrecompile(t *testing.T) {
chaincfg.ByzantiumBlock = big.NewInt(100)
chaincfg.IstanbulBlock = big.NewInt(200)
chaincfg.BerlinBlock = big.NewInt(300)
chaincfg.PlaceholderBlock = big.NewInt(400)
txCtx := vm.TxContext{GasPrice: big.NewInt(100000)}
tracer, err := newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil)
if err != nil {
Expand All @@ -225,6 +226,37 @@ func TestIsPrecompile(t *testing.T) {
if string(res) != "true" {
t.Errorf("Tracer should consider blake2f as precompile in istanbul")
}

// placeholder fork should only have identity and ecrecover and no other precompiles
tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil)
blockCtx = vm.BlockContext{BlockNumber: big.NewInt(450)}
res, err = runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg)
if err != nil {
t.Error(err)
}
if string(res) != "false" {
t.Errorf("Tracer should not consider blake2f as precompile in istanbul")
}

tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000001'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil)
blockCtx = vm.BlockContext{BlockNumber: big.NewInt(450)}
res, err = runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg)
if err != nil {
t.Error(err)
}
if string(res) != "true" {
t.Errorf("Tracer should keep ecrecover as precompile in scroll alpha")
}

tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000004'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil)
blockCtx = vm.BlockContext{BlockNumber: big.NewInt(450)}
res, err = runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg)
if err != nil {
t.Error(err)
}
if string(res) != "true" {
t.Errorf("Tracer should keep identity as precompile in scroll alpha")
}
}

func TestEnterExit(t *testing.T) {
Expand Down
24 changes: 17 additions & 7 deletions params/config.go
Thegaram marked this conversation as resolved.
Show resolved Hide resolved
Expand Up @@ -292,7 +292,7 @@ var (
//
// 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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), 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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil,
ScrollConfig{
UseZktrie: false,
FeeVaultAddress: nil,
Expand All @@ -306,7 +306,7 @@ var (
//
// 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), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000},
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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000},
ScrollConfig{
UseZktrie: false,
FeeVaultAddress: nil,
Expand All @@ -315,7 +315,7 @@ var (
MaxTxPerBlock: 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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), 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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil,
ScrollConfig{
UseZktrie: false,
FeeVaultAddress: &common.Address{123},
Expand All @@ -325,7 +325,7 @@ var (
}}
TestRules = TestChainConfig.Rules(new(big.Int))

TestNoL1feeChainConfig = &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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil,
TestNoL1feeChainConfig = &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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil,
ScrollConfig{
UseZktrie: false,
FeeVaultAddress: nil,
Expand Down Expand Up @@ -411,7 +411,7 @@ type ChainConfig struct {
BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin)
LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london)
ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated)

PlaceholderBlock *big.Int `json:"placeholderBlock,omitempty"` // Placeholder switch block (nil = no fork, 0 = already on placeholder)
// TerminalTotalDifficulty is the amount of total difficulty reached by
// the network that triggers the consensus upgrade.
TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"`
Expand Down Expand Up @@ -498,7 +498,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, Berlin: %v, London: %v, Arrow Glacier: %v, Engine: %v, Scroll config: %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, Berlin: %v, London: %v, Arrow Glacier: %v, Placeholder: %v,Engine: %v, Scroll config: %v}",
c.ChainID,
c.HomesteadBlock,
c.DAOForkBlock,
Expand All @@ -514,6 +514,7 @@ func (c *ChainConfig) String() string {
c.BerlinBlock,
c.LondonBlock,
c.ArrowGlacierBlock,
c.PlaceholderBlock,
engine,
c.Scroll,
)
Expand Down Expand Up @@ -586,6 +587,10 @@ func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool {
return isForked(c.ArrowGlacierBlock, num)
}

func (c *ChainConfig) IsPlaceholder(num *big.Int) bool {
return isForked(c.PlaceholderBlock, num)
}

// IsTerminalPoWBlock returns whether the given block is the last block of PoW stage.
func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool {
if c.TerminalTotalDifficulty == nil {
Expand Down Expand Up @@ -635,6 +640,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
{name: "berlinBlock", block: c.BerlinBlock},
{name: "londonBlock", block: c.LondonBlock},
{name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true},
{name: "placeholderBlock", block: c.PlaceholderBlock, optional: true},
} {
if lastFork.name != "" {
// Next one must be higher number
Expand Down Expand Up @@ -707,6 +713,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
if isForkIncompatible(c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock, head) {
return newCompatError("Arrow Glacier fork block", c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock)
}
if isForkIncompatible(c.PlaceholderBlock, newcfg.PlaceholderBlock, head) {
return newCompatError("Placeholder fork block", c.PlaceholderBlock, newcfg.PlaceholderBlock)
}
return nil
}

Expand Down Expand Up @@ -774,7 +783,7 @@ type Rules struct {
ChainID *big.Int
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
IsBerlin, IsLondon bool
IsBerlin, IsLondon, IsPlaceholder bool
}

// Rules ensures c's ChainID is not nil.
Expand All @@ -795,5 +804,6 @@ func (c *ChainConfig) Rules(num *big.Int) Rules {
IsIstanbul: c.IsIstanbul(num),
IsBerlin: c.IsBerlin(num),
IsLondon: c.IsLondon(num),
IsPlaceholder: c.IsPlaceholder(num),
}
}
16 changes: 16 additions & 0 deletions tests/init.go
Expand Up @@ -197,6 +197,22 @@ var Forks = map[string]*params.ChainConfig{
LondonBlock: big.NewInt(0),
ArrowGlacierBlock: big.NewInt(0),
},
"Placeholder": {
ChainID: big.NewInt(1),
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),
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
ArrowGlacierBlock: big.NewInt(0),
PlaceholderBlock: big.NewInt(0),
},
}

// Returns the set of defined fork names
Expand Down