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) { if conf.IsPrague(num, g.Timestamp) {
head.RequestsHash = &types.EmptyRequestsHash //head.RequestsHash = &types.EmptyRequestsHash
requests = make(types.Requests, 0) //requests = make(types.Requests, 0)
} }
} }
return types.NewBlock(head, &types.Body{Withdrawals: withdrawals, Requests: requests}, nil, trie.NewStackTrie(nil)) 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{ jt[RETF] = &operation{
execute: opRetf, execute: opRetf,
constantGas: GasFastishStep, constantGas: GasFastestStep,
minStack: minStack(0, 0), minStack: minStack(0, 0),
maxStack: maxStack(0, 0), maxStack: maxStack(0, 0),
terminal: true, terminal: true,
@ -864,6 +864,7 @@ func opJumpf(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
} }
scope.CodeSection = uint64(idx) scope.CodeSection = uint64(idx)
*pc = 0 *pc = 0
*pc -= 1 // hacks xD
return nil, nil 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) { 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 return nil, nil
} }
@ -365,7 +365,7 @@ func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
uint64CodeOffset = math.MaxUint64 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) scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
return nil, nil 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) { 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) { 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 { func makePush(size uint64, pushByteSize int) executionFunc {
return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
var ( var (
codeLen = len(scope.Contract.Code) code = scope.Contract.CodeAt(scope.CodeSection)
codeLen = len(code)
start = min(codeLen, int(*pc+1)) start = min(codeLen, int(*pc+1))
end = min(codeLen, start+pushByteSize) end = min(codeLen, start+pushByteSize)
) )
scope.Stack.push(new(uint256.Int).SetBytes( scope.Stack.push(new(uint256.Int).SetBytes(
common.RightPadBytes( common.RightPadBytes(
scope.Contract.Code[start:end], code[start:end],
pushByteSize, pushByteSize,
)), )),
) )

View file

@ -259,7 +259,10 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
vmconfig.ExtraEips = eips vmconfig.ExtraEips = eips
block := t.genesis(config).ToBlock() 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 var baseFee *big.Int
if config.IsLondon(new(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 { if config.IsCancun(new(big.Int), block.Time()) && t.json.Env.ExcessBlobGas != nil {
context.BlobBaseFee = eip4844.CalcBlobFee(*t.json.Env.ExcessBlobGas) 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) evm := vm.NewEVM(context, txContext, st.StateDB, config, vmconfig)
if tracer := vmconfig.Tracer; tracer != nil && tracer.OnTxStart != nil { 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() snapshot := st.StateDB.Snapshot()
gaspool := new(core.GasPool) gaspool := new(core.GasPool)
gaspool.AddGas(block.GasLimit()) 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) vmRet, err := core.ApplyMessage(evm, msg, gaspool)
if err != nil { if err != nil {
st.StateDB.RevertToSnapshot(snapshot) 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 // 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) 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. // Commit state mutations into database.
root, _ = st.StateDB.Commit(block.NumberU64(), config.IsEIP158(block.Number())) root, _ = st.StateDB.Commit(block.NumberU64(), config.IsEIP158(block.Number()))
if tracer := evm.Config.Tracer; tracer != nil && tracer.OnTxEnd != nil { if tracer := evm.Config.Tracer; tracer != nil && tracer.OnTxEnd != nil {