forked from cerc-io/plugeth
core: 4844 opcode and precompile (#27356)
* core: crypto: implement BLOBHASH and pointEval precompile * core: crypto: fixed nitpicks, moved precompile return value * core/vm: fix review comments
This commit is contained in:
parent
380fb4e249
commit
c537ace249
@ -128,6 +128,7 @@ func runCmd(ctx *cli.Context) error {
|
|||||||
receiver = common.BytesToAddress([]byte("receiver"))
|
receiver = common.BytesToAddress([]byte("receiver"))
|
||||||
genesisConfig *core.Genesis
|
genesisConfig *core.Genesis
|
||||||
preimages = ctx.Bool(DumpFlag.Name)
|
preimages = ctx.Bool(DumpFlag.Name)
|
||||||
|
blobHashes []common.Hash // TODO (MariusVanDerWijden) implement blob hashes in state tests
|
||||||
)
|
)
|
||||||
if ctx.Bool(MachineFlag.Name) {
|
if ctx.Bool(MachineFlag.Name) {
|
||||||
tracer = logger.NewJSONLogger(logconfig, os.Stdout)
|
tracer = logger.NewJSONLogger(logconfig, os.Stdout)
|
||||||
@ -217,6 +218,7 @@ func runCmd(ctx *cli.Context) error {
|
|||||||
Time: genesisConfig.Timestamp,
|
Time: genesisConfig.Timestamp,
|
||||||
Coinbase: genesisConfig.Coinbase,
|
Coinbase: genesisConfig.Coinbase,
|
||||||
BlockNumber: new(big.Int).SetUint64(genesisConfig.Number),
|
BlockNumber: new(big.Int).SetUint64(genesisConfig.Number),
|
||||||
|
BlobHashes: blobHashes,
|
||||||
EVMConfig: vm.Config{
|
EVMConfig: vm.Config{
|
||||||
Tracer: tracer,
|
Tracer: tracer,
|
||||||
},
|
},
|
||||||
|
@ -72,8 +72,9 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
|
|||||||
// NewEVMTxContext creates a new transaction context for a single transaction.
|
// NewEVMTxContext creates a new transaction context for a single transaction.
|
||||||
func NewEVMTxContext(msg *Message) vm.TxContext {
|
func NewEVMTxContext(msg *Message) vm.TxContext {
|
||||||
return vm.TxContext{
|
return vm.TxContext{
|
||||||
Origin: msg.From,
|
Origin: msg.From,
|
||||||
GasPrice: new(big.Int).Set(msg.GasPrice),
|
GasPrice: new(big.Int).Set(msg.GasPrice),
|
||||||
|
BlobHashes: msg.BlobHashes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +135,7 @@ type Message struct {
|
|||||||
GasTipCap *big.Int
|
GasTipCap *big.Int
|
||||||
Data []byte
|
Data []byte
|
||||||
AccessList types.AccessList
|
AccessList types.AccessList
|
||||||
|
BlobHashes []common.Hash
|
||||||
|
|
||||||
// When SkipAccountChecks is true, the message nonce is not checked against the
|
// When SkipAccountChecks is true, the message nonce is not checked against the
|
||||||
// account nonce in state. It also disables checking that the sender is an EOA.
|
// account nonce in state. It also disables checking that the sender is an EOA.
|
||||||
@ -155,6 +156,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
|
|||||||
Data: tx.Data(),
|
Data: tx.Data(),
|
||||||
AccessList: tx.AccessList(),
|
AccessList: tx.AccessList(),
|
||||||
SkipAccountChecks: false,
|
SkipAccountChecks: false,
|
||||||
|
BlobHashes: tx.BlobHashes(),
|
||||||
}
|
}
|
||||||
// If baseFee provided, set gasPrice to effectiveGasPrice.
|
// If baseFee provided, set gasPrice to effectiveGasPrice.
|
||||||
if baseFee != nil {
|
if baseFee != nil {
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@ -28,6 +29,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
||||||
"github.com/ethereum/go-ethereum/crypto/bls12381"
|
"github.com/ethereum/go-ethereum/crypto/bls12381"
|
||||||
"github.com/ethereum/go-ethereum/crypto/bn256"
|
"github.com/ethereum/go-ethereum/crypto/bn256"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"golang.org/x/crypto/ripemd160"
|
"golang.org/x/crypto/ripemd160"
|
||||||
)
|
)
|
||||||
@ -90,6 +92,21 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{
|
|||||||
common.BytesToAddress([]byte{9}): &blake2F{},
|
common.BytesToAddress([]byte{9}): &blake2F{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrecompiledContractsCancun contains the default set of pre-compiled Ethereum
|
||||||
|
// contracts used in the Cancun release.
|
||||||
|
var PrecompiledContractsCancun = 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{eip2565: true},
|
||||||
|
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
|
||||||
|
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
||||||
|
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
||||||
|
common.BytesToAddress([]byte{9}): &blake2F{},
|
||||||
|
common.BytesToAddress([]byte{20}): &kzgPointEvaluation{},
|
||||||
|
}
|
||||||
|
|
||||||
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
|
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
|
||||||
// contracts specified in EIP-2537. These are exported for testing purposes.
|
// contracts specified in EIP-2537. These are exported for testing purposes.
|
||||||
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
|
var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
|
||||||
@ -105,6 +122,7 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
PrecompiledAddressesCancun []common.Address
|
||||||
PrecompiledAddressesBerlin []common.Address
|
PrecompiledAddressesBerlin []common.Address
|
||||||
PrecompiledAddressesIstanbul []common.Address
|
PrecompiledAddressesIstanbul []common.Address
|
||||||
PrecompiledAddressesByzantium []common.Address
|
PrecompiledAddressesByzantium []common.Address
|
||||||
@ -124,11 +142,16 @@ func init() {
|
|||||||
for k := range PrecompiledContractsBerlin {
|
for k := range PrecompiledContractsBerlin {
|
||||||
PrecompiledAddressesBerlin = append(PrecompiledAddressesBerlin, k)
|
PrecompiledAddressesBerlin = append(PrecompiledAddressesBerlin, k)
|
||||||
}
|
}
|
||||||
|
for k := range PrecompiledContractsCancun {
|
||||||
|
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, 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:
|
||||||
|
return PrecompiledAddressesCancun
|
||||||
case rules.IsBerlin:
|
case rules.IsBerlin:
|
||||||
return PrecompiledAddressesBerlin
|
return PrecompiledAddressesBerlin
|
||||||
case rules.IsIstanbul:
|
case rules.IsIstanbul:
|
||||||
@ -1048,3 +1071,67 @@ func (c *bls12381MapG2) Run(input []byte) ([]byte, error) {
|
|||||||
// Encode the G2 point to 256 bytes
|
// Encode the G2 point to 256 bytes
|
||||||
return g.EncodePoint(r), nil
|
return g.EncodePoint(r), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// kzgPointEvaluation implements the EIP-4844 point evaluation precompile.
|
||||||
|
type kzgPointEvaluation struct{}
|
||||||
|
|
||||||
|
// RequiredGas estimates the gas required for running the point evaluation precompile.
|
||||||
|
func (b *kzgPointEvaluation) RequiredGas(input []byte) uint64 {
|
||||||
|
return params.BlobTxPointEvaluationPrecompileGas
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
blobVerifyInputLength = 192 // Max input length for the point evaluation precompile.
|
||||||
|
blobCommitmentVersionKZG uint8 = 0x01 // Version byte for the point evaluation precompile.
|
||||||
|
blobPrecompileReturnValue = "000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errBlobVerifyInvalidInputLength = errors.New("invalid input length")
|
||||||
|
errBlobVerifyMismatchedVersion = errors.New("mismatched versioned hash")
|
||||||
|
errBlobVerifyKZGProof = errors.New("error verifying kzg proof")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run executes the point evaluation precompile.
|
||||||
|
func (b *kzgPointEvaluation) Run(input []byte) ([]byte, error) {
|
||||||
|
if len(input) != blobVerifyInputLength {
|
||||||
|
return nil, errBlobVerifyInvalidInputLength
|
||||||
|
}
|
||||||
|
// versioned hash: first 32 bytes
|
||||||
|
var versionedHash common.Hash
|
||||||
|
copy(versionedHash[:], input[:])
|
||||||
|
|
||||||
|
var (
|
||||||
|
point kzg4844.Point
|
||||||
|
claim kzg4844.Claim
|
||||||
|
)
|
||||||
|
// Evaluation point: next 32 bytes
|
||||||
|
copy(point[:], input[32:])
|
||||||
|
// Expected output: next 32 bytes
|
||||||
|
copy(claim[:], input[64:])
|
||||||
|
|
||||||
|
// input kzg point: next 48 bytes
|
||||||
|
var commitment kzg4844.Commitment
|
||||||
|
copy(commitment[:], input[96:])
|
||||||
|
if kZGToVersionedHash(commitment) != versionedHash {
|
||||||
|
return nil, errBlobVerifyMismatchedVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proof: next 48 bytes
|
||||||
|
var proof kzg4844.Proof
|
||||||
|
copy(proof[:], input[144:])
|
||||||
|
|
||||||
|
if err := kzg4844.VerifyProof(commitment, point, claim, proof); err != nil {
|
||||||
|
return nil, fmt.Errorf("%w: %v", errBlobVerifyKZGProof, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return common.Hex2Bytes(blobPrecompileReturnValue), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// kZGToVersionedHash implements kzg_to_versioned_hash from EIP-4844
|
||||||
|
func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash {
|
||||||
|
h := sha256.Sum256(kzg[:])
|
||||||
|
h[0] = blobCommitmentVersionKZG
|
||||||
|
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
@ -65,6 +65,7 @@ var allPrecompiles = map[common.Address]PrecompiledContract{
|
|||||||
common.BytesToAddress([]byte{16}): &bls12381Pairing{},
|
common.BytesToAddress([]byte{16}): &bls12381Pairing{},
|
||||||
common.BytesToAddress([]byte{17}): &bls12381MapG1{},
|
common.BytesToAddress([]byte{17}): &bls12381MapG1{},
|
||||||
common.BytesToAddress([]byte{18}): &bls12381MapG2{},
|
common.BytesToAddress([]byte{18}): &bls12381MapG2{},
|
||||||
|
common.BytesToAddress([]byte{20}): &kzgPointEvaluation{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// EIP-152 test vectors
|
// EIP-152 test vectors
|
||||||
@ -311,6 +312,7 @@ func TestPrecompiledBLS12381G2MultiExp(t *testing.T) { testJson("blsG2MultiExp",
|
|||||||
func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "10", t) }
|
func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "10", t) }
|
||||||
func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "11", t) }
|
func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "11", t) }
|
||||||
func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "12", t) }
|
func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "12", t) }
|
||||||
|
func TestPrecompiledPointEvaluation(t *testing.T) { testJson("pointEvaluation", "14", t) }
|
||||||
|
|
||||||
func BenchmarkPrecompiledBLS12381G1Add(b *testing.B) { benchJson("blsG1Add", "0a", b) }
|
func BenchmarkPrecompiledBLS12381G1Add(b *testing.B) { benchJson("blsG1Add", "0a", b) }
|
||||||
func BenchmarkPrecompiledBLS12381G1Mul(b *testing.B) { benchJson("blsG1Mul", "0b", b) }
|
func BenchmarkPrecompiledBLS12381G1Mul(b *testing.B) { benchJson("blsG1Mul", "0b", b) }
|
||||||
|
@ -235,9 +235,32 @@ func opPush0(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ebnable3860 enables "EIP-3860: Limit and meter initcode"
|
// enable3860 enables "EIP-3860: Limit and meter initcode"
|
||||||
// https://eips.ethereum.org/EIPS/eip-3860
|
// https://eips.ethereum.org/EIPS/eip-3860
|
||||||
func enable3860(jt *JumpTable) {
|
func enable3860(jt *JumpTable) {
|
||||||
jt[CREATE].dynamicGas = gasCreateEip3860
|
jt[CREATE].dynamicGas = gasCreateEip3860
|
||||||
jt[CREATE2].dynamicGas = gasCreate2Eip3860
|
jt[CREATE2].dynamicGas = gasCreate2Eip3860
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// opBlobHash implements the BLOBHASH opcode
|
||||||
|
func opBlobHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||||
|
index := scope.Stack.peek()
|
||||||
|
if index.LtUint64(uint64(len(interpreter.evm.TxContext.BlobHashes))) {
|
||||||
|
blobHash := interpreter.evm.TxContext.BlobHashes[index.Uint64()]
|
||||||
|
index.SetBytes32(blobHash[:])
|
||||||
|
} else {
|
||||||
|
index.Clear()
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable4844 applies EIP-4844 (DATAHASH opcode)
|
||||||
|
func enable4844(jt *JumpTable) {
|
||||||
|
// New opcode
|
||||||
|
jt[BLOBHASH] = &operation{
|
||||||
|
execute: opBlobHash,
|
||||||
|
constantGas: GasFastestStep,
|
||||||
|
minStack: minStack(1, 1),
|
||||||
|
maxStack: maxStack(1, 1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -43,6 +43,8 @@ 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:
|
||||||
|
precompiles = PrecompiledContractsCancun
|
||||||
case evm.chainRules.IsBerlin:
|
case evm.chainRules.IsBerlin:
|
||||||
precompiles = PrecompiledContractsBerlin
|
precompiles = PrecompiledContractsBerlin
|
||||||
case evm.chainRules.IsIstanbul:
|
case evm.chainRules.IsIstanbul:
|
||||||
@ -81,8 +83,9 @@ type BlockContext struct {
|
|||||||
// All fields can change between transactions.
|
// All fields can change between transactions.
|
||||||
type TxContext struct {
|
type TxContext struct {
|
||||||
// Message information
|
// Message information
|
||||||
Origin common.Address // Provides information for ORIGIN
|
Origin common.Address // Provides information for ORIGIN
|
||||||
GasPrice *big.Int // Provides information for GASPRICE
|
GasPrice *big.Int // Provides information for GASPRICE
|
||||||
|
BlobHashes []common.Hash // Provides information for BLOBHASH
|
||||||
}
|
}
|
||||||
|
|
||||||
// EVM is the Ethereum Virtual Machine base object and provides
|
// EVM is the Ethereum Virtual Machine base object and provides
|
||||||
|
@ -746,3 +746,45 @@ func TestRandom(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBlobHash(t *testing.T) {
|
||||||
|
type testcase struct {
|
||||||
|
name string
|
||||||
|
idx uint64
|
||||||
|
expect common.Hash
|
||||||
|
hashes []common.Hash
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
zero = common.Hash{0}
|
||||||
|
one = common.Hash{1}
|
||||||
|
two = common.Hash{2}
|
||||||
|
three = common.Hash{3}
|
||||||
|
)
|
||||||
|
for _, tt := range []testcase{
|
||||||
|
{name: "[{1}]", idx: 0, expect: one, hashes: []common.Hash{one}},
|
||||||
|
{name: "[1,{2},3]", idx: 2, expect: three, hashes: []common.Hash{one, two, three}},
|
||||||
|
{name: "out-of-bounds (empty)", idx: 10, expect: zero, hashes: []common.Hash{}},
|
||||||
|
{name: "out-of-bounds", idx: 25, expect: zero, hashes: []common.Hash{one, two, three}},
|
||||||
|
{name: "out-of-bounds (nil)", idx: 25, expect: zero, hashes: nil},
|
||||||
|
} {
|
||||||
|
var (
|
||||||
|
env = NewEVM(BlockContext{}, TxContext{BlobHashes: tt.hashes}, nil, params.TestChainConfig, Config{})
|
||||||
|
stack = newstack()
|
||||||
|
pc = uint64(0)
|
||||||
|
evmInterpreter = env.interpreter
|
||||||
|
)
|
||||||
|
stack.push(uint256.NewInt(tt.idx))
|
||||||
|
opBlobHash(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
|
||||||
|
if len(stack.data) != 1 {
|
||||||
|
t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data))
|
||||||
|
}
|
||||||
|
actual := stack.pop()
|
||||||
|
expected, overflow := uint256.FromBig(new(big.Int).SetBytes(tt.expect.Bytes()))
|
||||||
|
if overflow {
|
||||||
|
t.Errorf("Testcase %v: invalid overflow", tt.name)
|
||||||
|
}
|
||||||
|
if actual.Cmp(expected) != 0 {
|
||||||
|
t.Errorf("Testcase %v: expected %x, got %x", tt.name, expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -56,6 +56,8 @@ 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.IsCancun:
|
||||||
|
table = &cancunInstructionSet
|
||||||
case evm.chainRules.IsShanghai:
|
case evm.chainRules.IsShanghai:
|
||||||
table = &shanghaiInstructionSet
|
table = &shanghaiInstructionSet
|
||||||
case evm.chainRules.IsMerge:
|
case evm.chainRules.IsMerge:
|
||||||
|
@ -56,6 +56,7 @@ var (
|
|||||||
londonInstructionSet = newLondonInstructionSet()
|
londonInstructionSet = newLondonInstructionSet()
|
||||||
mergeInstructionSet = newMergeInstructionSet()
|
mergeInstructionSet = newMergeInstructionSet()
|
||||||
shanghaiInstructionSet = newShanghaiInstructionSet()
|
shanghaiInstructionSet = newShanghaiInstructionSet()
|
||||||
|
cancunInstructionSet = newCancunInstructionSet()
|
||||||
)
|
)
|
||||||
|
|
||||||
// JumpTable contains the EVM opcodes supported at a given fork.
|
// JumpTable contains the EVM opcodes supported at a given fork.
|
||||||
@ -79,6 +80,12 @@ func validate(jt JumpTable) JumpTable {
|
|||||||
return jt
|
return jt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newCancunInstructionSet() JumpTable {
|
||||||
|
instructionSet := newShanghaiInstructionSet()
|
||||||
|
enable4844(&instructionSet) // BLOBHASH opcode
|
||||||
|
return validate(instructionSet)
|
||||||
|
}
|
||||||
|
|
||||||
func newShanghaiInstructionSet() JumpTable {
|
func newShanghaiInstructionSet() JumpTable {
|
||||||
instructionSet := newMergeInstructionSet()
|
instructionSet := newMergeInstructionSet()
|
||||||
enable3855(&instructionSet) // PUSH0 instruction
|
enable3855(&instructionSet) // PUSH0 instruction
|
||||||
|
@ -100,6 +100,7 @@ const (
|
|||||||
CHAINID OpCode = 0x46
|
CHAINID OpCode = 0x46
|
||||||
SELFBALANCE OpCode = 0x47
|
SELFBALANCE OpCode = 0x47
|
||||||
BASEFEE OpCode = 0x48
|
BASEFEE OpCode = 0x48
|
||||||
|
BLOBHASH OpCode = 0x49
|
||||||
)
|
)
|
||||||
|
|
||||||
// 0x50 range - 'storage' and execution.
|
// 0x50 range - 'storage' and execution.
|
||||||
@ -288,6 +289,7 @@ var opCodeToString = map[OpCode]string{
|
|||||||
CHAINID: "CHAINID",
|
CHAINID: "CHAINID",
|
||||||
SELFBALANCE: "SELFBALANCE",
|
SELFBALANCE: "SELFBALANCE",
|
||||||
BASEFEE: "BASEFEE",
|
BASEFEE: "BASEFEE",
|
||||||
|
BLOBHASH: "BLOBHASH",
|
||||||
|
|
||||||
// 0x50 range - 'storage' and execution.
|
// 0x50 range - 'storage' and execution.
|
||||||
POP: "POP",
|
POP: "POP",
|
||||||
@ -445,6 +447,7 @@ var stringToOp = map[string]OpCode{
|
|||||||
"CALLDATACOPY": CALLDATACOPY,
|
"CALLDATACOPY": CALLDATACOPY,
|
||||||
"CHAINID": CHAINID,
|
"CHAINID": CHAINID,
|
||||||
"BASEFEE": BASEFEE,
|
"BASEFEE": BASEFEE,
|
||||||
|
"BLOBHASH": BLOBHASH,
|
||||||
"DELEGATECALL": DELEGATECALL,
|
"DELEGATECALL": DELEGATECALL,
|
||||||
"STATICCALL": STATICCALL,
|
"STATICCALL": STATICCALL,
|
||||||
"CODESIZE": CODESIZE,
|
"CODESIZE": CODESIZE,
|
||||||
|
@ -23,8 +23,9 @@ import (
|
|||||||
|
|
||||||
func NewEnv(cfg *Config) *vm.EVM {
|
func NewEnv(cfg *Config) *vm.EVM {
|
||||||
txContext := vm.TxContext{
|
txContext := vm.TxContext{
|
||||||
Origin: cfg.Origin,
|
Origin: cfg.Origin,
|
||||||
GasPrice: cfg.GasPrice,
|
GasPrice: cfg.GasPrice,
|
||||||
|
BlobHashes: cfg.BlobHashes,
|
||||||
}
|
}
|
||||||
blockContext := vm.BlockContext{
|
blockContext := vm.BlockContext{
|
||||||
CanTransfer: core.CanTransfer,
|
CanTransfer: core.CanTransfer,
|
||||||
|
@ -44,6 +44,7 @@ type Config struct {
|
|||||||
Debug bool
|
Debug bool
|
||||||
EVMConfig vm.Config
|
EVMConfig vm.Config
|
||||||
BaseFee *big.Int
|
BaseFee *big.Int
|
||||||
|
BlobHashes []common.Hash
|
||||||
|
|
||||||
State *state.StateDB
|
State *state.StateDB
|
||||||
GetHashFn func(n uint64) common.Hash
|
GetHashFn func(n uint64) common.Hash
|
||||||
|
9
core/vm/testdata/precompiles/pointEvaluation.json
vendored
Normal file
9
core/vm/testdata/precompiles/pointEvaluation.json
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"Input": "013c03613f6fc558fb7e61e75602241ed9a2f04e36d8670aadd286e71b5ca9cc420000000000000000000000000000000000000000000000000000000000000031e5a2356cbc2ef6a733eae8d54bf48719ae3d990017ca787c419c7d369f8e3c83fac17c3f237fc51f90e2c660eb202a438bc2025baded5cd193c1a018c5885bc9281ba704d5566082e851235c7be763b2a99adff965e0a121ee972ebc472d02944a74f5c6243e14052e105124b70bf65faf85ad3a494325e269fad097842cba",
|
||||||
|
"Expected": "000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001",
|
||||||
|
"Name": "pointEvaluation1",
|
||||||
|
"Gas": 50000,
|
||||||
|
"NoBenchmark": false
|
||||||
|
}
|
||||||
|
]
|
@ -160,12 +160,13 @@ const (
|
|||||||
RefundQuotient uint64 = 2
|
RefundQuotient uint64 = 2
|
||||||
RefundQuotientEIP3529 uint64 = 5
|
RefundQuotientEIP3529 uint64 = 5
|
||||||
|
|
||||||
BlobTxHashVersion = 0x01 // Version byte of the commitment hash
|
BlobTxHashVersion = 0x01 // Version byte of the commitment hash
|
||||||
BlobTxMaxDataGasPerBlock = 1 << 19 // Maximum consumable data gas for data blobs per block
|
BlobTxMaxDataGasPerBlock = 1 << 19 // Maximum consumable data gas for data blobs per block
|
||||||
BlobTxTargetDataGasPerBlock = 1 << 18 // Target consumable data gas for data blobs per block (for 1559-like pricing)
|
BlobTxTargetDataGasPerBlock = 1 << 18 // Target consumable data gas for data blobs per block (for 1559-like pricing)
|
||||||
BlobTxDataGasPerBlob = 1 << 17 // Gas consumption of a single data blob (== blob byte size)
|
BlobTxDataGasPerBlob = 1 << 17 // Gas consumption of a single data blob (== blob byte size)
|
||||||
BlobTxMinDataGasprice = 1 // Minimum gas price for data blobs
|
BlobTxMinDataGasprice = 1 // Minimum gas price for data blobs
|
||||||
BlobTxDataGaspriceUpdateFraction = 2225652 // Controls the maximum rate of change for data gas price
|
BlobTxDataGaspriceUpdateFraction = 2225652 // Controls the maximum rate of change for data gas price
|
||||||
|
BlobTxPointEvaluationPrecompileGas = 50000 // Gas price for the point evaluation precompile.
|
||||||
)
|
)
|
||||||
|
|
||||||
// Gas discount table for BLS12-381 G1 and G2 multi exponentiation operations
|
// Gas discount table for BLS12-381 G1 and G2 multi exponentiation operations
|
||||||
|
Loading…
Reference in New Issue
Block a user