Skip to content

Commit

Permalink
Merge pull request #139 from okx/zjg/meger-v2.0.0-beta18
Browse files Browse the repository at this point in the history
merge v2.0.0 beta18
  • Loading branch information
KamiD authored Sep 11, 2024
2 parents 6b149e0 + c481ad2 commit ea259cb
Show file tree
Hide file tree
Showing 33 changed files with 422 additions and 356 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ Sequencer specific config:
- `zkevm.executor-urls`: A csv list of the executor URLs. These will be used in a round robbin fashion by the sequencer
- `zkevm.executor-strict`: Defaulted to true, but can be set to false when running the sequencer without verifications (use with extreme caution)
- `zkevm.witness-full`: Defaulted to true. Controls whether the full or partial witness is used with the executor.
- `zkevm.reject-smart-contract-deployments`: Defaulted to false. Controls whether smart contract deployments are rejected by the TxPool.

Resource Utilisation config:
- `zkevm.smt-regenerate-in-memory`: As documented above, allows SMT regeneration in memory if machine has enough RAM, for a speedup in initial sync.
Expand Down
2 changes: 1 addition & 1 deletion cmd/rpcdaemon/commands/eth_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs
}
header := block.HeaderNoCopy()

caller, err := transactions.NewReusableCaller(engine, stateReader, nil, header, args, api.GasCap, latestNumOrHash, dbtx, api._blockReader, chainConfig, api.evmCallTimeout, api.VirtualCountersSmtReduction)
caller, err := transactions.NewReusableCaller(engine, stateReader, nil, header, args, api.GasCap, latestNumOrHash, dbtx, api._blockReader, chainConfig, api.evmCallTimeout, api.VirtualCountersSmtReduction, false)
if err != nil {
return 0, err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/rpcdaemon/commands/zkevm_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ func (api *ZkEvmAPIImpl) GetBatchByNumber(ctx context.Context, batchNumber rpc.B
}

// local exit root
localExitRoot, err := utils.GetBatchLocalExitRoot(batchNo, hermezDb, tx)
localExitRoot, err := utils.GetBatchLocalExitRootFromSCStorageForLatestBlock(batchNo, hermezDb, tx)
if err != nil {
return nil, err
}
Expand Down
15 changes: 15 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,11 @@ var (
Usage: "First block to start syncing from on the L1",
Value: 0,
}
L1ContractAddressCheckFlag = cli.BoolFlag{
Name: "zkevm.l1-contract-address-check",
Usage: "Check the contract address on the L1",
Value: true,
}
RebuildTreeAfterFlag = cli.Uint64Flag{
Name: "zkevm.rebuild-tree-after",
Usage: "Rebuild the state tree after this many blocks behind",
Expand Down Expand Up @@ -486,6 +491,11 @@ var (
Usage: "This is a maximum time that a batch verification could take. Including retries. This could be interpreted as maximum that that the sequencer can run without executor. Setting it to 0s will mean infinite timeout. Defaults to 30min",
Value: "30m",
}
SequencerTimeoutOnEmptyTxPool = cli.StringFlag{
Name: "zkevm.sequencer-timeout-on-empty-tx-pool",
Usage: "Timeout before requesting txs from the txpool if none were found before. Defaults to 250ms",
Value: "250ms",
}
SequencerHaltOnBatchNumber = cli.Uint64Flag{
Name: "zkevm.sequencer-halt-on-batch-number",
Usage: "Halt the sequencer on this batch number",
Expand Down Expand Up @@ -627,6 +637,11 @@ var (
Usage: "The URL of the pool manager. If set, eth_sendRawTransaction will be redirected there.",
Value: "",
}
TxPoolRejectSmartContractDeployments = cli.BoolFlag{
Name: "zkevm.reject-smart-contract-deployments",
Usage: "Reject smart contract deployments",
Value: false,
}
DisableVirtualCounters = cli.BoolFlag{
Name: "zkevm.disable-virtual-counters",
Usage: "Disable the virtual counters. This has an effect on on sequencer node and when external executor is not enabled.",
Expand Down
1 change: 0 additions & 1 deletion core/state/intra_block_state_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ type ReadOnlyHermezDb interface {
GetBatchGlobalExitRoots(fromBatchNum, toBatchNum uint64) (*[]dstypes.GerUpdate, error)
GetBlockGlobalExitRoot(l2BlockNo uint64) (libcommon.Hash, error)
GetBlockL1BlockHash(l2BlockNo uint64) (libcommon.Hash, error)
GetGerForL1BlockHash(l1BlockHash libcommon.Hash) (libcommon.Hash, error)
GetIntermediateTxStateRoot(blockNum uint64, txhash libcommon.Hash) (libcommon.Hash, error)
GetReusedL1InfoTreeIndex(blockNum uint64) (bool, error)
GetSequenceByBatchNo(batchNo uint64) (*zktypes.L1BatchInfo, error)
Expand Down
1 change: 0 additions & 1 deletion core/vm/eips_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ func enable2929_zkevm(jt *JumpTable) {
// factor here
jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150
jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929_zkevm
jt[SENDALL].dynamicGas = gasSelfdestructEIP2929_zkevm
}

func enable3529_zkevm(jt *JumpTable) {
Expand Down
138 changes: 138 additions & 0 deletions core/vm/instructions_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/common/hexutil"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/crypto"
"github.com/ledgerwatch/erigon/params"
)

Expand Down Expand Up @@ -379,3 +380,140 @@ func opDelegateCall_zkevm(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
interpreter.returnData = ret
return ret, nil
}

// OpCoded execution overrides that are used for executing the last opcode in case of an error
func opBlockhash_zkevm_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
num := scope.Stack.Peek()

ibs := interpreter.evm.IntraBlockState()
ibs.GetBlockStateRoot(num)

return nil, nil
}

func opCodeSize_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
return nil, nil
}

func opExtCodeSize_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
slot := scope.Stack.Peek()
interpreter.evm.IntraBlockState().GetCodeSize(slot.Bytes20())
return nil, nil
}

func opExtCodeCopy_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
var (
stack = scope.Stack
a = stack.Pop()
)
addr := libcommon.Address(a.Bytes20())
interpreter.evm.IntraBlockState().GetCode(addr)
return nil, nil
}

func opExtCodeHash_zkevm_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
slot := scope.Stack.Peek()
address := libcommon.Address(slot.Bytes20())
ibs := interpreter.evm.IntraBlockState()
ibs.GetCodeSize(address)
ibs.GetCodeHash(address)
return nil, nil
}

func opSelfBalance_lastOpCode(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) {
interpreter.evm.IntraBlockState().GetBalance(callContext.Contract.Address())
return nil, nil
}

func opBalance_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
slot := scope.Stack.Peek()
address := libcommon.Address(slot.Bytes20())
interpreter.evm.IntraBlockState().GetBalance(address)
return nil, nil
}

func opCreate_zkevm_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
if interpreter.readOnly {
return nil, ErrWriteProtection
}
var (
value = scope.Stack.Pop()
gas = scope.Contract.Gas
)
if interpreter.evm.ChainRules().IsTangerineWhistle {
gas -= gas / 64
}

caller := scope.Contract
address := crypto.CreateAddress(caller.Address(), interpreter.evm.IntraBlockState().GetNonce(caller.Address()))

interpreter.evm.IntraBlockState().GetBalance(caller.Address())
nonce := interpreter.evm.IntraBlockState().GetNonce(caller.Address())
interpreter.evm.IntraBlockState().SetNonce(caller.Address(), nonce+1)
interpreter.evm.IntraBlockState().AddAddressToAccessList(address)
interpreter.evm.IntraBlockState().GetCodeHash(address)
interpreter.evm.IntraBlockState().GetNonce(address)
interpreter.evm.IntraBlockState().CreateAccount(address, true)
interpreter.evm.IntraBlockState().SetNonce(address, 1)
interpreter.evm.IntraBlockState().SubBalance(caller.Address(), &value)
interpreter.evm.IntraBlockState().AddBalance(address, &value)
interpreter.evm.IntraBlockState().SetCode(address, []byte{0})

return nil, nil
}

func opCreate2_zkevm_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
if interpreter.readOnly {
return nil, ErrWriteProtection
}
var (
endowment = scope.Stack.Pop()
offset, size = scope.Stack.Pop(), scope.Stack.Pop()
salt = scope.Stack.Pop()
input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
)

caller := scope.Contract
codeAndHash := &codeAndHash{code: input}
address := crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes())

interpreter.evm.IntraBlockState().GetBalance(caller.Address())
nonce := interpreter.evm.IntraBlockState().GetNonce(caller.Address())
interpreter.evm.IntraBlockState().SetNonce(caller.Address(), nonce+1)
interpreter.evm.IntraBlockState().AddAddressToAccessList(address)
interpreter.evm.IntraBlockState().GetCodeHash(address)
interpreter.evm.IntraBlockState().GetNonce(address)
interpreter.evm.IntraBlockState().CreateAccount(address, true)
interpreter.evm.IntraBlockState().SetNonce(address, 1)
interpreter.evm.IntraBlockState().SubBalance(caller.Address(), &endowment)
interpreter.evm.IntraBlockState().AddBalance(address, &endowment)
interpreter.evm.IntraBlockState().SetCode(address, []byte{0})

return nil, nil
}

func opReturn_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
return nil, nil
}

func opUndefined_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
return nil, nil
}

func opSload_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
loc := scope.Stack.Peek()
interpreter.hasherBuf = loc.Bytes32()
interpreter.evm.IntraBlockState().GetState(scope.Contract.Address(), &interpreter.hasherBuf, loc)
return nil, nil
}

func opSstore_lastOpCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
if interpreter.readOnly {
return nil, ErrWriteProtection
}
loc := scope.Stack.Pop()
val := scope.Stack.Pop()
interpreter.hasherBuf = loc.Bytes32()
interpreter.evm.IntraBlockState().SetState(scope.Contract.Address(), &interpreter.hasherBuf, val)
return nil, nil
}
11 changes: 10 additions & 1 deletion core/vm/interpreter_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ func getJumpTable(cr *chain.Rules) *JumpTable {
return jt
}

func overrideJumpTableForLastOpcode(jt *JumpTable, cr *chain.Rules) {
// currently an opcode execution does not change in any fork from 4 do 12.
// If, in future, there is a change then we can override it based on fork id
overrideJumpTableForLastOpcodeForkId12(jt)
}

func shouldExecuteLastOpCode(op OpCode) bool {
switch op {
case BLOCKHASH:
Expand Down Expand Up @@ -213,7 +219,10 @@ func (in *EVMInterpreter) RunZk(contract *Contract, input []byte, readOnly bool)
// we can safely use pc here instead of pcCopy,
// because pc and pcCopy can be different only if the main loop finishes normally without error
// but is it finishes normally without error then "ret" != nil and the .execute below will never be invoked at all
in.jt[op].execute(pc, in, callContext)

jtForLastOpCode := copyJumpTable(in.jt)
overrideJumpTableForLastOpcode(jtForLastOpCode, in.evm.ChainRules())
jtForLastOpCode[op].execute(pc, in, callContext)
}
}()

Expand Down
24 changes: 20 additions & 4 deletions core/vm/jump_table_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ func newForkID4InstructionSet() JumpTable {

instructionSet[EXTCODEHASH].execute = opExtCodeHash_zkevm

instructionSet[SENDALL] = &operation{
instructionSet[SENDALL] = instructionSet[INVALID]

// SELFDESTRUCT is replaces by SENDALL
instructionSet[SELFDESTRUCT] = &operation{
execute: opSendAll_zkevm,
dynamicGas: gasSelfdestruct_zkevm,
numPop: 1,
numPush: 0,
}

// SELFDESTRUCT is replaces by SENDALL
instructionSet[SELFDESTRUCT] = instructionSet[SENDALL]

validateAndFillMaxStack(&instructionSet)
return instructionSet
}
Expand Down Expand Up @@ -80,3 +80,19 @@ func newForkID8InstructionSet() JumpTable {
validateAndFillMaxStack(&instructionSet)
return instructionSet
}

func overrideJumpTableForLastOpcodeForkId12(jt *JumpTable) {
jt[BLOCKHASH].execute = opBlockhash_zkevm_lastOpCode
jt[CODESIZE].execute = opCodeSize_lastOpCode
jt[EXTCODESIZE].execute = opExtCodeSize_lastOpCode
jt[EXTCODECOPY].execute = opExtCodeCopy_lastOpCode
jt[EXTCODEHASH].execute = opExtCodeHash_zkevm_lastOpCode
jt[SELFBALANCE].execute = opSelfBalance_lastOpCode
jt[BALANCE].execute = opBalance_lastOpCode
jt[CREATE].execute = opCreate_zkevm_lastOpCode
jt[RETURN].execute = opReturn_lastOpCode
jt[CREATE2].execute = opCreate2_zkevm_lastOpCode
jt[SENDALL].execute = opUndefined_lastOpCode
jt[SLOAD].execute = opSload_lastOpCode
jt[SSTORE].execute = opSstore_lastOpCode
}
2 changes: 1 addition & 1 deletion core/vm/zk_batch_counters.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func (bcc *BatchCounterCollector) CombineCollectors(verifyMerkleProof bool) (Cou
return combined, nil
}

// CombineCollectors takes the batch level data from all transactions and combines these counters with each transactions'
// CombineCollectorsNoChanges takes the batch level data from all transactions and combines these counters with each transactions'
// rlp level counters and execution level counters
// this one returns the counters as they are so far, without adding processBatchLevelData, processChangeL2Block and decodeChangeL2BlockTx
// used to save batch counter progress without adding the said counters twice
Expand Down
1 change: 0 additions & 1 deletion core/vm/zk_counters.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,6 @@ func SimpleCounterOperations(cc *CounterCollector) *[256]executionFunc {
CREATE2: cc.opCreate2,
RETURN: cc.opReturn,
REVERT: cc.opRevert,
SENDALL: cc.opSendAll,
SELFDESTRUCT: cc.opSendAll,
INVALID: cc.opInvalid,
ADDRESS: cc.opAddress,
Expand Down
16 changes: 10 additions & 6 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ import (
zkStages "github.com/ledgerwatch/erigon/zk/stages"
"github.com/ledgerwatch/erigon/zk/syncer"
txpool2 "github.com/ledgerwatch/erigon/zk/txpool"
"github.com/ledgerwatch/erigon/zk/utils"
"github.com/ledgerwatch/erigon/zk/witness"
"github.com/ledgerwatch/erigon/zkevm/etherman"
"github.com/ledgerwatch/erigon/zk/utils"
)

// Config contains the configuration options of the ETH protocol.
Expand Down Expand Up @@ -853,12 +853,16 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
)

// check contract addresses in config against L1
success, err := l1ContractAddressCheck(ctx, cfg.Zk, backend.l1Syncer)
if !success || err != nil {
//log.Warn("Contract address check failed", "success", success, "err", err)
panic("Contract address check failed")
if cfg.Zk.L1ContractAddressCheck {
success, err := l1ContractAddressCheck(ctx, cfg.Zk, backend.l1Syncer)
if !success || err != nil {
//log.Warn("Contract address check failed", "success", success, "err", err)
panic("Contract address check failed")
}
log.Info("Contract address check passed")
} else {
log.Info("Contract address check skipped")
}
log.Info("Contract address check passed")

l1InfoTreeSyncer := syncer.NewL1Syncer(
ctx,
Expand Down
3 changes: 3 additions & 0 deletions eth/ethconfig/config_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Zk struct {
AddressRollup common.Address
AddressZkevm common.Address
AddressGerManager common.Address
L1ContractAddressCheck bool
L1RollupId uint64
L1BlockRange uint64
L1QueryDelay uint64
Expand All @@ -35,6 +36,7 @@ type Zk struct {
SequencerBlockSealTime time.Duration
SequencerBatchSealTime time.Duration
SequencerBatchVerificationTimeout time.Duration
SequencerTimeoutOnEmptyTxPool time.Duration
SequencerHaltOnBatchNumber uint64
ExecutorUrls []string
ExecutorStrictMode bool
Expand Down Expand Up @@ -76,6 +78,7 @@ type Zk struct {
DisableVirtualCounters bool
VirtualCountersSmtReduction float64
ExecutorPayloadOutput string
TxPoolRejectSmartContractDeployments bool

// For X Layer
XLayer XLayerConfig
Expand Down
Loading

0 comments on commit ea259cb

Please sign in to comment.