feat: config several forks opcodes & precompiles (#780)

* add Curie & Descartes InstructionSet; update LondonInstructionSet

* update core/vm/runtime/runtime.go

* update core/vm/opcodes.go

* update tests/init.go

* update core/vm/contracts.go

* update eth/tracers/js/tracer_test.go

* update core/state_processor_test.go

* london: update core/types/transaction_signing.go

* update tests/init.go

* update core/txpool/validation.go

* update tests/state_test_util.go

* remove selfdestruct
This commit is contained in:
HAOYUatHZ 2024-06-01 16:22:31 +08:00 committed by GitHub
parent f3c8cc1cb7
commit b0b4608450
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 268 additions and 46 deletions

View file

@ -64,6 +64,9 @@ func TestStateProcessorErrors(t *testing.T) {
TerminalTotalDifficultyPassed: true, TerminalTotalDifficultyPassed: true,
ShanghaiTime: new(uint64), ShanghaiTime: new(uint64),
CancunTime: new(uint64), CancunTime: new(uint64),
BernoulliBlock: big.NewInt(0),
CurieBlock: big.NewInt(0),
DescartesBlock: big.NewInt(0),
} }
signer = types.LatestSigner(config) signer = types.LatestSigner(config)
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")

View file

@ -59,10 +59,10 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
} }
// Ensure only transactions that have been enabled are accepted // Ensure only transactions that have been enabled are accepted
if !opts.Config.IsCurie(head.Number) && tx.Type() != types.LegacyTxType { if !opts.Config.IsCurie(head.Number) && tx.Type() != types.LegacyTxType {
return fmt.Errorf("%w: type %d rejected, pool not yet in Berlin", core.ErrTxTypeNotSupported, tx.Type()) return fmt.Errorf("%w: type %d rejected, pool not yet in Curie", core.ErrTxTypeNotSupported, tx.Type())
} }
if !opts.Config.IsCurie(head.Number) && tx.Type() == types.DynamicFeeTxType { if !opts.Config.IsCurie(head.Number) && tx.Type() == types.DynamicFeeTxType {
return fmt.Errorf("%w: type %d rejected, pool not yet in London", core.ErrTxTypeNotSupported, tx.Type()) return fmt.Errorf("%w: type %d rejected, pool not yet in Curie", core.ErrTxTypeNotSupported, tx.Type())
} }
if !opts.Config.IsCancun(head.Number, head.Time) && tx.Type() == types.BlobTxType { if !opts.Config.IsCancun(head.Number, head.Time) && tx.Type() == types.BlobTxType {
return fmt.Errorf("%w: type %d rejected, pool not yet in Cancun", core.ErrTxTypeNotSupported, tx.Type()) return fmt.Errorf("%w: type %d rejected, pool not yet in Cancun", core.ErrTxTypeNotSupported, tx.Type())

View file

@ -40,10 +40,12 @@ type sigCache struct {
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer { func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer {
var signer Signer var signer Signer
switch { switch {
case config.IsCurie(blockNumber):
signer = NewLondonSignerWithEIP4844(config.ChainID)
case config.IsCancun(blockNumber, blockTime): case config.IsCancun(blockNumber, blockTime):
signer = NewCancunSigner(config.ChainID) signer = NewCancunSigner(config.ChainID)
case config.IsLondon(blockNumber): case config.IsLondon(blockNumber):
signer = NewLondonSigner(config.ChainID) signer = NewLondonSignerWithEIP4844(config.ChainID)
case config.IsBerlin(blockNumber): case config.IsBerlin(blockNumber):
signer = NewEIP2930Signer(config.ChainID) signer = NewEIP2930Signer(config.ChainID)
case config.IsEIP155(blockNumber): case config.IsEIP155(blockNumber):
@ -69,7 +71,7 @@ func LatestSigner(config *params.ChainConfig) Signer {
return NewCancunSigner(config.ChainID) return NewCancunSigner(config.ChainID)
} }
if config.LondonBlock != nil { if config.LondonBlock != nil {
return NewLondonSigner(config.ChainID) return NewLondonSignerWithEIP4844(config.ChainID)
} }
if config.BerlinBlock != nil { if config.BerlinBlock != nil {
return NewEIP2930Signer(config.ChainID) return NewEIP2930Signer(config.ChainID)
@ -253,6 +255,75 @@ func (s cancunSigner) Hash(tx *Transaction) common.Hash {
}) })
} }
type londonSignerWithEIP4844 struct{ londonSigner }
// NewLondonSignerWithEIP4844 returns a signer that accepts
// - EIP-4844 blob transactions
// - EIP-1559 dynamic fee transactions
// - EIP-2930 access list transactions,
// - EIP-155 replay protected transactions, and
// - legacy Homestead transactions.
func NewLondonSignerWithEIP4844(chainId *big.Int) Signer {
return londonSignerWithEIP4844{londonSigner{eip2930Signer{NewEIP155Signer(chainId)}}}
}
func (s londonSignerWithEIP4844) Sender(tx *Transaction) (common.Address, error) {
if tx.Type() != BlobTxType {
return s.londonSigner.Sender(tx)
}
V, R, S := tx.RawSignatureValues()
// Blob txs are defined to use 0 and 1 as their recovery
// id, add 27 to become equivalent to unprotected Homestead signatures.
V = new(big.Int).Add(V, big.NewInt(27))
if tx.ChainId().Cmp(s.chainId) != 0 {
return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId)
}
return recoverPlain(s.Hash(tx), R, S, V, true)
}
func (s londonSignerWithEIP4844) Equal(s2 Signer) bool {
x, ok := s2.(londonSignerWithEIP4844)
return ok && x.chainId.Cmp(s.chainId) == 0
}
func (s londonSignerWithEIP4844) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) {
txdata, ok := tx.inner.(*BlobTx)
if !ok {
return s.londonSigner.SignatureValues(tx, sig)
}
// Check that chain ID of tx matches the signer. We also accept ID zero here,
// because it indicates that the chain ID was not specified in the tx.
if txdata.ChainID.Sign() != 0 && txdata.ChainID.ToBig().Cmp(s.chainId) != 0 {
return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId)
}
R, S, _ = decodeSignature(sig)
V = big.NewInt(int64(sig[64]))
return R, S, V, nil
}
// Hash returns the hash to be signed by the sender.
// It does not uniquely identify the transaction.
func (s londonSignerWithEIP4844) Hash(tx *Transaction) common.Hash {
if tx.Type() != BlobTxType {
return s.londonSigner.Hash(tx)
}
return prefixedRlpHash(
tx.Type(),
[]interface{}{
s.chainId,
tx.Nonce(),
tx.GasTipCap(),
tx.GasFeeCap(),
tx.Gas(),
tx.To(),
tx.Value(),
tx.Data(),
tx.AccessList(),
tx.BlobGasFeeCap(),
tx.BlobHashes(),
})
}
type londonSigner struct{ eip2930Signer } type londonSigner struct{ eip2930Signer }
// NewLondonSigner returns a signer that accepts // NewLondonSigner returns a signer that accepts

View file

@ -97,20 +97,6 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{9}): &blake2F{}, common.BytesToAddress([]byte{9}): &blake2F{},
} }
// PrecompiledContractsArchimedes contains the default set of pre-compiled Ethereum
// contracts used in the Archimedes release. Same as Berlin but without sha2, blake2f, ripemd160
var PrecompiledContractsArchimedes = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hashDisabled{},
common.BytesToAddress([]byte{3}): &ripemd160hashDisabled{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2FDisabled{},
}
// PrecompiledContractsCancun contains the default set of pre-compiled Ethereum // PrecompiledContractsCancun contains the default set of pre-compiled Ethereum
// contracts used in the Cancun release. // contracts used in the Cancun release.
var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{ var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{
@ -140,9 +126,38 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{18}): &bls12381MapG2{}, common.BytesToAddress([]byte{18}): &bls12381MapG2{},
} }
// PrecompiledContractsArchimedes contains the default set of pre-compiled Ethereum
// contracts used in the Archimedes release. Same as Berlin but without sha2, blake2f, ripemd160
var PrecompiledContractsArchimedes = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hashDisabled{},
common.BytesToAddress([]byte{3}): &ripemd160hashDisabled{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2FDisabled{},
}
// PrecompiledContractsBernoulli contains the default set of pre-compiled Ethereum
// contracts used in the Bernoulli release. Same as Archimedes but with sha256hash enabled again
var PrecompiledContractsBernoulli = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hashDisabled{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2FDisabled{},
}
var ( var (
PrecompiledAddressesCancun []common.Address PrecompiledAddressesBernoulli []common.Address
PrecompiledAddressesArchimedes []common.Address PrecompiledAddressesArchimedes []common.Address
PrecompiledAddressesCancun []common.Address
PrecompiledAddressesBerlin []common.Address PrecompiledAddressesBerlin []common.Address
PrecompiledAddressesIstanbul []common.Address PrecompiledAddressesIstanbul []common.Address
PrecompiledAddressesByzantium []common.Address PrecompiledAddressesByzantium []common.Address
@ -168,15 +183,23 @@ func init() {
for k := range PrecompiledContractsCancun { for k := range PrecompiledContractsCancun {
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k) PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
} }
for k := range PrecompiledContractsArchimedes {
PrecompiledAddressesArchimedes = append(PrecompiledAddressesArchimedes, k)
}
for k := range PrecompiledContractsBernoulli {
PrecompiledAddressesBernoulli = append(PrecompiledAddressesBernoulli, k)
}
} }
// ActivePrecompiles returns the precompiles enabled with the current configuration. // ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules params.Rules) []common.Address { func ActivePrecompiles(rules params.Rules) []common.Address {
switch { switch {
case rules.IsCancun: case rules.IsBernoulli:
return PrecompiledAddressesCancun return PrecompiledAddressesBernoulli
case rules.IsArchimedes: case rules.IsArchimedes:
return PrecompiledAddressesArchimedes return PrecompiledAddressesArchimedes
case rules.IsCancun:
return PrecompiledAddressesCancun
case rules.IsBerlin: case rules.IsBerlin:
return PrecompiledAddressesBerlin return PrecompiledAddressesBerlin
case rules.IsIstanbul: case rules.IsIstanbul:

View file

@ -27,7 +27,7 @@ import (
var activators = map[int]func(*JumpTable){ var activators = map[int]func(*JumpTable){
5656: enable5656, 5656: enable5656,
6780: enable6780, // 6780: enable6780, // SELFDESTRUCT is disabled in Scroll
3855: enable3855, 3855: enable3855,
3860: enable3860, 3860: enable3860,
3529: enable3529, 3529: enable3529,
@ -147,10 +147,9 @@ func enable2929(jt *JumpTable) {
jt[DELEGATECALL].constantGas = params.WarmStorageReadCostEIP2929 jt[DELEGATECALL].constantGas = params.WarmStorageReadCostEIP2929
jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929 jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929
// This was previously part of the dynamic cost, but we're using it as a constantGas // SELFDESTRUCT is disabled in Scroll
// factor here // jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150
jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150 // jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929
jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929
} }
// enable3529 enabled "EIP-3529: Reduction in refunds": // enable3529 enabled "EIP-3529: Reduction in refunds":
@ -159,7 +158,9 @@ func enable2929(jt *JumpTable) {
// - Reduces max refunds to 20% gas // - Reduces max refunds to 20% gas
func enable3529(jt *JumpTable) { func enable3529(jt *JumpTable) {
jt[SSTORE].dynamicGas = gasSStoreEIP3529 jt[SSTORE].dynamicGas = gasSStoreEIP3529
jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP3529
// SELFDESTRUCT is disabled in Scroll
// jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP3529
} }
// enable3198 applies EIP-3198 (BASEFEE Opcode) // enable3198 applies EIP-3198 (BASEFEE Opcode)
@ -309,6 +310,8 @@ func enable7516(jt *JumpTable) {
} }
} }
// SELFDESTRUCT is disabled in Scroll.
/*
// enable6780 applies EIP-6780 (deactivate SELFDESTRUCT) // enable6780 applies EIP-6780 (deactivate SELFDESTRUCT)
func enable6780(jt *JumpTable) { func enable6780(jt *JumpTable) {
jt[SELFDESTRUCT] = &operation{ jt[SELFDESTRUCT] = &operation{
@ -319,3 +322,4 @@ func enable6780(jt *JumpTable) {
maxStack: maxStack(1, 0), maxStack: maxStack(1, 0),
} }
} }
*/

View file

@ -40,10 +40,12 @@ type (
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
var precompiles map[common.Address]PrecompiledContract var precompiles map[common.Address]PrecompiledContract
switch { switch {
case evm.chainRules.IsCancun: case evm.chainRules.IsBernoulli:
precompiles = PrecompiledContractsCancun precompiles = PrecompiledContractsBernoulli
case evm.chainRules.IsArchimedes: case evm.chainRules.IsArchimedes:
precompiles = PrecompiledContractsArchimedes precompiles = PrecompiledContractsArchimedes
case evm.chainRules.IsCancun:
precompiles = PrecompiledContractsCancun
case evm.chainRules.IsBerlin: case evm.chainRules.IsBerlin:
precompiles = PrecompiledContractsBerlin precompiles = PrecompiledContractsBerlin
case evm.chainRules.IsIstanbul: case evm.chainRules.IsIstanbul:

View file

@ -455,6 +455,8 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo
return gas, nil return gas, nil
} }
// SELFDESTRUCT is disabled in Scroll.
/*
func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
var gas uint64 var gas uint64
// EIP150 homestead gas reprice fork: // EIP150 homestead gas reprice fork:
@ -477,3 +479,4 @@ func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me
} }
return gas, nil return gas, nil
} }
*/

View file

@ -56,6 +56,10 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter {
// If jump table was not initialised we set the default one. // If jump table was not initialised we set the default one.
var table *JumpTable var table *JumpTable
switch { switch {
case evm.chainRules.IsDescartes:
table = &descartesInstructionSet
case evm.chainRules.IsCurie:
table = &curieInstructionSet
case evm.chainRules.IsCancun: case evm.chainRules.IsCancun:
table = &cancunInstructionSet table = &cancunInstructionSet
case evm.chainRules.IsShanghai: case evm.chainRules.IsShanghai:

View file

@ -57,6 +57,8 @@ var (
mergeInstructionSet = newMergeInstructionSet() mergeInstructionSet = newMergeInstructionSet()
shanghaiInstructionSet = newShanghaiInstructionSet() shanghaiInstructionSet = newShanghaiInstructionSet()
cancunInstructionSet = newCancunInstructionSet() cancunInstructionSet = newCancunInstructionSet()
curieInstructionSet = newCurieInstructionSet()
descartesInstructionSet = newDescartesInstructionSet()
) )
// JumpTable contains the EVM opcodes supported at a given fork. // JumpTable contains the EVM opcodes supported at a given fork.
@ -80,13 +82,31 @@ func validate(jt JumpTable) JumpTable {
return jt return jt
} }
// newDescartesInstructionSet returns the frontier, homestead, byzantium,
// contantinople, istanbul, petersburg, berlin, london, shanghai, curie, and descartes instructions.
func newDescartesInstructionSet() JumpTable {
instructionSet := newCurieInstructionSet()
return instructionSet
}
// newCurieInstructionSet returns the frontier, homestead, byzantium,
// contantinople, istanbul, petersburg, berlin, london, shanghai, and curie instructions.
func newCurieInstructionSet() JumpTable {
instructionSet := newShanghaiInstructionSet()
enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198
enable5656(&instructionSet) // EIP-5656 (MCOPY opcode)
enable1153(&instructionSet) // EIP-1153 (TLOAD, TSTORE opcodes)
return instructionSet
}
func newCancunInstructionSet() JumpTable { func newCancunInstructionSet() JumpTable {
instructionSet := newShanghaiInstructionSet() instructionSet := newShanghaiInstructionSet()
enable4844(&instructionSet) // EIP-4844 (BLOBHASH opcode) enable4844(&instructionSet) // EIP-4844 (BLOBHASH opcode)
enable7516(&instructionSet) // EIP-7516 (BLOBBASEFEE opcode) enable7516(&instructionSet) // EIP-7516 (BLOBBASEFEE opcode)
enable1153(&instructionSet) // EIP-1153 "Transient Storage" enable1153(&instructionSet) // EIP-1153 "Transient Storage"
enable5656(&instructionSet) // EIP-5656 (MCOPY opcode) enable5656(&instructionSet) // EIP-5656 (MCOPY opcode)
enable6780(&instructionSet) // EIP-6780 SELFDESTRUCT only in same transaction // SELFDESTRUCT is disabled in Scroll.
// enable6780(&instructionSet) // EIP-6780 SELFDESTRUCT only in same transaction
return validate(instructionSet) return validate(instructionSet)
} }
@ -114,7 +134,7 @@ func newMergeInstructionSet() JumpTable {
func newLondonInstructionSet() JumpTable { func newLondonInstructionSet() JumpTable {
instructionSet := newBerlinInstructionSet() instructionSet := newBerlinInstructionSet()
enable3529(&instructionSet) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529 enable3529(&instructionSet) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529
enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198 // enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198
return validate(instructionSet) return validate(instructionSet)
} }
@ -1046,12 +1066,9 @@ func newFrontierInstructionSet() JumpTable {
maxStack: maxStack(2, 0), maxStack: maxStack(2, 0),
memorySize: memoryReturn, memorySize: memoryReturn,
}, },
SELFDESTRUCT: { // SELFDESTRUCT is disabled in Scroll.
execute: opSelfdestruct, // SELFDESTRUCT has the same behavior as INVALID.
dynamicGas: gasSelfdestruct, SELFDESTRUCT: nil,
minStack: minStack(1, 0),
maxStack: maxStack(1, 0),
},
} }
// Fill all unassigned slots with opUndefined. // Fill all unassigned slots with opUndefined.

View file

@ -286,7 +286,12 @@ var opCodeToString = map[OpCode]string{
GASLIMIT: "GASLIMIT", GASLIMIT: "GASLIMIT",
CHAINID: "CHAINID", CHAINID: "CHAINID",
SELFBALANCE: "SELFBALANCE", SELFBALANCE: "SELFBALANCE",
BASEFEE: "BASEFEE",
// we temporarily comment this out, since ccc expects
// the "opcode 0x%x not defined" string in the traces,
// should uncomment once ccc supports the string version.
// BASEFEE: "BASEFEE",
BLOBHASH: "BLOBHASH", BLOBHASH: "BLOBHASH",
BLOBBASEFEE: "BLOBBASEFEE", BLOBBASEFEE: "BLOBBASEFEE",
@ -303,10 +308,15 @@ var opCodeToString = map[OpCode]string{
MSIZE: "MSIZE", MSIZE: "MSIZE",
GAS: "GAS", GAS: "GAS",
JUMPDEST: "JUMPDEST", JUMPDEST: "JUMPDEST",
TLOAD: "TLOAD",
TSTORE: "TSTORE", // we temporarily comment these out, since ccc expects
MCOPY: "MCOPY", // the "opcode 0x%x not defined" string in the traces,
PUSH0: "PUSH0", // should uncomment once ccc supports the string version.
// TLOAD: "TLOAD",
// TSTORE: "TSTORE",
// MCOPY: "MCOPY",
PUSH0: "PUSH0",
// 0x60 range - pushes. // 0x60 range - pushes.
PUSH1: "PUSH1", PUSH1: "PUSH1",

View file

@ -196,9 +196,10 @@ var (
gasDelegateCallEIP2929 = makeCallVariantGasCallEIP2929(gasDelegateCall) gasDelegateCallEIP2929 = makeCallVariantGasCallEIP2929(gasDelegateCall)
gasStaticCallEIP2929 = makeCallVariantGasCallEIP2929(gasStaticCall) gasStaticCallEIP2929 = makeCallVariantGasCallEIP2929(gasStaticCall)
gasCallCodeEIP2929 = makeCallVariantGasCallEIP2929(gasCallCode) gasCallCodeEIP2929 = makeCallVariantGasCallEIP2929(gasCallCode)
gasSelfdestructEIP2929 = makeSelfdestructGasFn(true) // SELFDESTRUCT is disabled in Scroll.
// gasSelfdestructEIP3529 implements the changes in EIP-2539 (no refunds) // gasSelfdestructEIP2929 = makeSelfdestructGasFn(true)
gasSelfdestructEIP3529 = makeSelfdestructGasFn(false) // // gasSelfdestructEIP3529 implements the changes in EIP-2539 (no refunds)
// gasSelfdestructEIP3529 = makeSelfdestructGasFn(false)
// gasSStoreEIP2929 implements gas cost for SSTORE according to EIP-2929 // gasSStoreEIP2929 implements gas cost for SSTORE according to EIP-2929
// //
@ -219,6 +220,8 @@ var (
gasSStoreEIP3529 = makeGasSStoreFunc(params.SstoreClearsScheduleRefundEIP3529) gasSStoreEIP3529 = makeGasSStoreFunc(params.SstoreClearsScheduleRefundEIP3529)
) )
// SELFDESTRUCT is disabled in Scroll.
/*
// makeSelfdestructGasFn can create the selfdestruct dynamic gas function for EIP-2929 and EIP-2539 // makeSelfdestructGasFn can create the selfdestruct dynamic gas function for EIP-2929 and EIP-2539
func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { func makeSelfdestructGasFn(refundsEnabled bool) gasFunc {
gasFunc := func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { gasFunc := func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
@ -242,3 +245,4 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc {
} }
return gasFunc return gasFunc
} }
*/

View file

@ -71,6 +71,10 @@ func setDefaults(cfg *Config) {
BerlinBlock: new(big.Int), BerlinBlock: new(big.Int),
LondonBlock: new(big.Int), LondonBlock: new(big.Int),
ArchimedesBlock: new(big.Int), ArchimedesBlock: new(big.Int),
ShanghaiTime: new(uint64),
BernoulliBlock: new(big.Int),
CurieBlock: new(big.Int),
DescartesBlock: new(big.Int),
} }
} }

View file

@ -233,6 +233,7 @@ func TestIsPrecompile(t *testing.T) {
chaincfg.ByzantiumBlock = big.NewInt(100) chaincfg.ByzantiumBlock = big.NewInt(100)
chaincfg.IstanbulBlock = big.NewInt(200) chaincfg.IstanbulBlock = big.NewInt(200)
chaincfg.BerlinBlock = big.NewInt(300) chaincfg.BerlinBlock = big.NewInt(300)
chaincfg.ArchimedesBlock = big.NewInt(400)
txCtx := vm.TxContext{GasPrice: big.NewInt(100000)} 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, nil) tracer, err := newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil, nil)
if err != nil { if err != nil {
@ -257,6 +258,47 @@ func TestIsPrecompile(t *testing.T) {
if string(res) != "true" { if string(res) != "true" {
t.Errorf("tracer should consider blake2f as precompile in istanbul") t.Errorf("tracer should consider blake2f as precompile in istanbul")
} }
// test sha disabled in archimedes
tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000002'), 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 archimedes")
}
tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000003'), 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 ripemd as precompile in archimedes")
}
// test blake2f disabled in archimedes
tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil)
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 archimedes")
}
// test ecrecover enabled in archimedes
tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000001'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil)
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 archimedes")
}
} }
func TestEnterExit(t *testing.T) { func TestEnterExit(t *testing.T) {

View file

@ -337,6 +337,41 @@ var Forks = map[string]*params.ChainConfig{
ShanghaiTime: u64(0), ShanghaiTime: u64(0),
CancunTime: u64(15_000), CancunTime: u64(15_000),
}, },
"Archimedes": {
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),
ArchimedesBlock: big.NewInt(0),
},
"Curie": {
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),
ArchimedesBlock: big.NewInt(0),
ShanghaiTime: u64(0),
BernoulliBlock: big.NewInt(0),
CurieBlock: big.NewInt(0),
},
} }
// AvailableForks returns the set of defined fork names // AvailableForks returns the set of defined fork names

View file

@ -240,7 +240,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
triedb, snaps, statedb := MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter, scheme) triedb, snaps, statedb := MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter, scheme)
var baseFee *big.Int var baseFee *big.Int
if config.IsLondon(new(big.Int)) { if config.IsCurie(new(big.Int)) {
baseFee = t.json.Env.BaseFee baseFee = t.json.Env.BaseFee
if baseFee == nil { if baseFee == nil {
// Retesteth uses `0x10` for genesis baseFee. Therefore, it defaults to // Retesteth uses `0x10` for genesis baseFee. Therefore, it defaults to