From 5f2355acf3cf3af20326d73f3fc4bd3244cd9823 Mon Sep 17 00:00:00 2001 From: lightclient Date: Fri, 18 Jul 2025 08:57:24 -0600 Subject: [PATCH] params,internal: add eth_config --- core/vm/contracts.go | 85 ++++++++++++++++++++++++++++++++++++++ internal/ethapi/api.go | 28 +++++++++++++ internal/jsre/deps/web3.js | 4 ++ params/config.go | 59 ++++++++++++++++++++++++++ 4 files changed, 176 insertions(+) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index b65dff602ca..edb49b8b68b 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -46,6 +46,7 @@ import ( type PrecompiledContract interface { RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use Run(input []byte) ([]byte, error) // Run runs the precompiled contract + Name() string } // PrecompiledContracts contains the precompiled contracts supported at the given fork. @@ -308,6 +309,10 @@ func (c *ecrecover) Run(input []byte) ([]byte, error) { return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32), nil } +func (c *ecrecover) Name() string { + return "ECREC" +} + // SHA256 implemented as a native contract. type sha256hash struct{} @@ -323,6 +328,10 @@ func (c *sha256hash) Run(input []byte) ([]byte, error) { return h[:], nil } +func (c *sha256hash) Name() string { + return "SHA256" +} + // RIPEMD160 implemented as a native contract. type ripemd160hash struct{} @@ -339,6 +348,10 @@ func (c *ripemd160hash) Run(input []byte) ([]byte, error) { return common.LeftPadBytes(ripemd.Sum(nil), 32), nil } +func (c *ripemd160hash) Name() string { + return "RIPEMD160" +} + // data copy implemented as a native contract. type dataCopy struct{} @@ -353,6 +366,10 @@ func (c *dataCopy) Run(in []byte) ([]byte, error) { return common.CopyBytes(in), nil } +func (c *dataCopy) Name() string { + return "ID" +} + // bigModExp implements a native big integer exponential modular operation. type bigModExp struct { eip2565 bool @@ -537,6 +554,10 @@ func (c *bigModExp) Run(input []byte) ([]byte, error) { return common.LeftPadBytes(v, int(modLen)), nil } +func (c *bigModExp) Name() string { + return "MODEXP" +} + // newCurvePoint unmarshals a binary blob into a bn256 elliptic curve point, // returning it, or an error if the point is invalid. func newCurvePoint(blob []byte) (*bn256.G1, error) { @@ -586,6 +607,10 @@ func (c *bn256AddIstanbul) Run(input []byte) ([]byte, error) { return runBn256Add(input) } +func (c *bn256AddIstanbul) Name() string { + return "BN256_ADD" +} + // bn256AddByzantium implements a native elliptic curve point addition // conforming to Byzantium consensus rules. type bn256AddByzantium struct{} @@ -599,6 +624,10 @@ func (c *bn256AddByzantium) Run(input []byte) ([]byte, error) { return runBn256Add(input) } +func (c *bn256AddByzantium) Name() string { + return "BN256_ADD" +} + // runBn256ScalarMul implements the Bn256ScalarMul precompile, referenced by // both Byzantium and Istanbul operations. func runBn256ScalarMul(input []byte) ([]byte, error) { @@ -624,6 +653,10 @@ func (c *bn256ScalarMulIstanbul) Run(input []byte) ([]byte, error) { return runBn256ScalarMul(input) } +func (c *bn256ScalarMulIstanbul) Name() string { + return "BN256_MUL" +} + // bn256ScalarMulByzantium implements a native elliptic curve scalar // multiplication conforming to Byzantium consensus rules. type bn256ScalarMulByzantium struct{} @@ -637,6 +670,10 @@ func (c *bn256ScalarMulByzantium) Run(input []byte) ([]byte, error) { return runBn256ScalarMul(input) } +func (c *bn256ScalarMulByzantium) Name() string { + return "BN256_MUL" +} + var ( // true32Byte is returned if the bn256 pairing check succeeds. true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} @@ -692,6 +729,10 @@ func (c *bn256PairingIstanbul) Run(input []byte) ([]byte, error) { return runBn256Pairing(input) } +func (c *bn256PairingIstanbul) Name() string { + return "BN256_PAIRING" +} + // bn256PairingByzantium implements a pairing pre-compile for the bn256 curve // conforming to Byzantium consensus rules. type bn256PairingByzantium struct{} @@ -705,6 +746,10 @@ func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) { return runBn256Pairing(input) } +func (c *bn256PairingByzantium) Name() string { + return "BN256_PAIRING" +} + type blake2F struct{} func (c *blake2F) RequiredGas(input []byte) uint64 { @@ -766,6 +811,10 @@ func (c *blake2F) Run(input []byte) ([]byte, error) { return output, nil } +func (c *blake2F) Name() string { + return "BLAKE2F" +} + var ( errBLS12381InvalidInputLength = errors.New("invalid input length") errBLS12381InvalidFieldElementTopBytes = errors.New("invalid field element top bytes") @@ -809,6 +858,10 @@ func (c *bls12381G1Add) Run(input []byte) ([]byte, error) { return encodePointG1(p0), nil } +func (c *bls12381G1Add) Name() string { + return "BLS12_G1ADD" +} + // bls12381G1MultiExp implements EIP-2537 G1MultiExp precompile. type bls12381G1MultiExp struct{} @@ -869,6 +922,10 @@ func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) { return encodePointG1(r), nil } +func (c *bls12381G1MultiExp) Name() string { + return "BLS12_G1MSM" +} + // bls12381G2Add implements EIP-2537 G2Add precompile. type bls12381G2Add struct{} @@ -906,6 +963,10 @@ func (c *bls12381G2Add) Run(input []byte) ([]byte, error) { return encodePointG2(r), nil } +func (c *bls12381G2Add) Name() string { + return "BLS12_G2ADD" +} + // bls12381G2MultiExp implements EIP-2537 G2MultiExp precompile. type bls12381G2MultiExp struct{} @@ -966,6 +1027,10 @@ func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) { return encodePointG2(r), nil } +func (c *bls12381G2MultiExp) Name() string { + return "BLS12_G2MSM" +} + // bls12381Pairing implements EIP-2537 Pairing precompile. type bls12381Pairing struct{} @@ -1029,6 +1094,10 @@ func (c *bls12381Pairing) Run(input []byte) ([]byte, error) { return out, nil } +func (c *bls12381Pairing) Name() string { + return "BLS12_PAIRING_CHECK" +} + func decodePointG1(in []byte) (*bls12381.G1Affine, error) { if len(in) != 128 { return nil, errors.New("invalid g1 point length") @@ -1147,6 +1216,10 @@ func (c *bls12381MapG1) Run(input []byte) ([]byte, error) { return encodePointG1(&r), nil } +func (c *bls12381MapG1) Name() string { + return "BLS12_MAP_FP_TO_G1" +} + // bls12381MapG2 implements EIP-2537 MapG2 precompile. type bls12381MapG2 struct{} @@ -1180,6 +1253,10 @@ func (c *bls12381MapG2) Run(input []byte) ([]byte, error) { return encodePointG2(&r), nil } +func (c *bls12381MapG2) Name() string { + return "BLS12_MAP_FP2_TO_G2" +} + // kzgPointEvaluation implements the EIP-4844 point evaluation precompile. type kzgPointEvaluation struct{} @@ -1236,6 +1313,10 @@ func (b *kzgPointEvaluation) Run(input []byte) ([]byte, error) { return common.Hex2Bytes(blobPrecompileReturnValue), nil } +func (c *kzgPointEvaluation) Name() string { + return "KZG_POINT_EVALUATION" +} + // kZGToVersionedHash implements kzg_to_versioned_hash from EIP-4844 func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash { h := sha256.Sum256(kzg[:]) @@ -1271,3 +1352,7 @@ func (c *p256Verify) Run(input []byte) ([]byte, error) { } return nil, nil } + +func (c *p256Verify) Name() string { + return "P256VERIFY" +} diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 51b6ca3c442..e6df59bcd18 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1135,6 +1135,34 @@ func (api *BlockChainAPI) CreateAccessList(ctx context.Context, args Transaction return result, nil } +type config struct { + ActivationTime uint64 `json:"activationTime"` + BlobSchedule *params.BlobConfig `json:"blobSchedule"` + ChainId *hexutil.Big `json:"chainId"` + Precompiles map[common.Address]string `json:"precompiles"` + SystemContracts map[string]common.Address `json:"systemContracts"` +} + +// Config implements the EIP-7910 eth_config method. +func (api *BlockChainAPI) Config(ctx context.Context) config { + var ( + c = api.b.ChainConfig() + h = api.b.CurrentBlock() + rules = c.Rules(h.Number, true, h.Time) + precompiles = make(map[common.Address]string) + ) + for addr, c := range vm.ActivePrecompiledContracts(rules) { + precompiles[addr] = c.Name() + } + return config{ + ActivationTime: c.NextForkTime(h.Time), + BlobSchedule: c.BlobConfig(c.LatestFork(h.Time)), + ChainId: (*hexutil.Big)(c.ChainID), + Precompiles: precompiles, + SystemContracts: c.ActiveSystemContracts(h.Time), + } +} + // AccessList creates an access list for the given transaction. // If the accesslist creation fails an error is returned. // If the transaction itself fails, an vmErr is returned. diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index 3a19dce06c2..91a05eda758 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -5490,6 +5490,10 @@ var properties = function () { new Property({ name: 'protocolVersion', getter: 'eth_protocolVersion' + }), + new Property({ + name: 'config', + getter: 'eth_config' }) ]; }; diff --git a/params/config.go b/params/config.go index 85619bbe222..f53709b5f3b 100644 --- a/params/config.go +++ b/params/config.go @@ -985,6 +985,65 @@ func (c *ChainConfig) LatestFork(time uint64) forks.Fork { } } +// NextFork returns the next fork to activate or nil if the last defined fork is +// active. +func (c *ChainConfig) NextForkTime(time uint64) uint64 { + // Assume last non-time-based fork has passed. + london := c.LondonBlock + next := newUint64(0) + + switch { + case c.IsOsaka(london, time): + next = c.OsakaTime + case c.IsPrague(london, time): + next = c.OsakaTime + case c.IsCancun(london, time): + next = c.PragueTime + case c.IsShanghai(london, time): + next = c.CancunTime + default: + next = c.ShanghaiTime + } + if next == nil { + return 0 + } + return *next +} + +// BlobConfig returns the blob config associated with the provided fork. +func (c *ChainConfig) BlobConfig(fork forks.Fork) *BlobConfig { + switch fork { + case forks.Osaka: + return DefaultOsakaBlobConfig + case forks.Prague: + return DefaultPragueBlobConfig + case forks.Cancun: + return DefaultCancunBlobConfig + default: + return nil + } +} + +// ActiveSystemContracts returns the currently active system contracts at the +// given timestamp. +func (c *ChainConfig) ActiveSystemContracts(time uint64) map[string]common.Address { + fork := c.LatestFork(time) + active := make(map[string]common.Address) + if fork >= forks.Osaka { + // no new system contracts + } + if fork >= forks.Prague { + active["CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS"] = ConsolidationQueueAddress + active["DEPOSIT_CONTRACT_ADDRESS"] = c.DepositContractAddress + active["HISTORY_STORAGE_ADDRESS"] = HistoryStorageAddress + active["WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS"] = WithdrawalQueueAddress + } + if fork >= forks.Cancun { + active["BEACON_ROOTS_ADDRESS"] = BeaconRootsAddress + } + return active +} + // Timestamp returns the timestamp associated with the fork or returns nil if // the fork isn't defined or isn't a time-based fork. func (c *ChainConfig) Timestamp(fork forks.Fork) *uint64 {