core/vm: fixed bugs, made basic blockchain tests pass

This commit is contained in:
Marius van der Wijden 2024-06-24 17:31:34 +02:00
parent 07db5b86b1
commit d1317f2f76
4 changed files with 29 additions and 9 deletions

View file

@ -473,8 +473,8 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block {
}
}
if conf.IsPrague(num, g.Timestamp) {
head.RequestsHash = &types.EmptyRequestsHash
requests = make(types.Requests, 0)
//head.RequestsHash = &types.EmptyRequestsHash
//requests = make(types.Requests, 0)
}
}
return types.NewBlock(head, &types.Body{Withdrawals: withdrawals, Requests: requests}, nil, trie.NewStackTrie(nil))

View file

@ -628,7 +628,7 @@ func enableEOF(jt *JumpTable) {
}
jt[RETF] = &operation{
execute: opRetf,
constantGas: GasFastishStep,
constantGas: GasFastestStep,
minStack: minStack(0, 0),
maxStack: maxStack(0, 0),
terminal: true,
@ -864,6 +864,7 @@ func opJumpf(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
}
scope.CodeSection = uint64(idx)
*pc = 0
*pc -= 1 // hacks xD
return nil, nil
}

View file

@ -350,7 +350,7 @@ func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
}
func opCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(scope.Contract.Code))))
scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(scope.Contract.CodeAt(scope.CodeSection)))))
return nil, nil
}
@ -365,7 +365,7 @@ func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
uint64CodeOffset = math.MaxUint64
}
codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64())
codeCopy := getData(scope.Contract.CodeAt(scope.CodeSection), uint64CodeOffset, length.Uint64())
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
return nil, nil
}
@ -890,7 +890,7 @@ func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
}
func opUndefined(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
return nil, &ErrInvalidOpCode{opcode: OpCode(scope.Contract.Code[*pc])}
return nil, &ErrInvalidOpCode{opcode: OpCode(scope.Contract.CodeAt(scope.CodeSection)[*pc])}
}
func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
@ -986,13 +986,14 @@ func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
func makePush(size uint64, pushByteSize int) executionFunc {
return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
var (
codeLen = len(scope.Contract.Code)
code = scope.Contract.CodeAt(scope.CodeSection)
codeLen = len(code)
start = min(codeLen, int(*pc+1))
end = min(codeLen, start+pushByteSize)
)
scope.Stack.push(new(uint256.Int).SetBytes(
common.RightPadBytes(
scope.Contract.Code[start:end],
code[start:end],
pushByteSize,
)),
)

View file

@ -259,7 +259,10 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
vmconfig.ExtraEips = eips
block := t.genesis(config).ToBlock()
st = MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter, scheme)
genesisAlloc := t.json.Pre
genesisAlloc[params.BeaconRootsAddress] = types.Account{Nonce: 1, Code: params.BeaconRootsCode}
//genesisAlloc[params.HistoryStorageAddress] = types.Account{Nonce: 1, Code: params.HistoryStorageCode}
st = MakePreState(rawdb.NewMemoryDatabase(), genesisAlloc, snapshotter, scheme)
var baseFee *big.Int
if config.IsLondon(new(big.Int)) {
@ -316,6 +319,11 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
if config.IsCancun(new(big.Int), block.Time()) && t.json.Env.ExcessBlobGas != nil {
context.BlobBaseFee = eip4844.CalcBlobFee(*t.json.Env.ExcessBlobGas)
}
{
evm := vm.NewEVM(context, vm.TxContext{}, st.StateDB, config, vmconfig)
core.ProcessBeaconBlockRoot(common.HexToHash("0x00"), evm, st.StateDB)
}
evm := vm.NewEVM(context, txContext, st.StateDB, config, vmconfig)
if tracer := vmconfig.Tracer; tracer != nil && tracer.OnTxStart != nil {
@ -325,6 +333,10 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
snapshot := st.StateDB.Snapshot()
gaspool := new(core.GasPool)
gaspool.AddGas(block.GasLimit())
for i := int(block.Number().Uint64() - 1); i >= 0; i-- {
core.ProcessParentBlockHash(vmTestBlockHash(uint64(i)), evm, st.StateDB)
}
vmRet, err := core.ApplyMessage(evm, msg, gaspool)
if err != nil {
st.StateDB.RevertToSnapshot(snapshot)
@ -339,6 +351,12 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
// the coinbase gets no txfee, so isn't created, and thus needs to be touched
st.StateDB.AddBalance(block.Coinbase(), new(uint256.Int), tracing.BalanceChangeUnspecified)
if config.IsPrague(new(big.Int), block.Time()) {
// Process the withdrawal requests contract execution
vmenv := vm.NewEVM(context, vm.TxContext{}, st.StateDB, config, evm.Config)
core.ProcessDequeueWithdrawalRequests(vmenv, st.StateDB)
}
// Commit state mutations into database.
root, _ = st.StateDB.Commit(block.NumberU64(), config.IsEIP158(block.Number()))
if tracer := evm.Config.Tracer; tracer != nil && tracer.OnTxEnd != nil {