Print SSTORE on SSTORE and SLOAD on SLOAD

The next step is to actually hook up these opcodes to native SLOAD and
SSTORE
This commit is contained in:
Mason Fischer 2020-01-22 14:15:47 -05:00
parent 4bfe04325e
commit 1cf19d88e1
2 changed files with 35 additions and 5 deletions

View file

@ -17,6 +17,7 @@
package vm package vm
import ( import (
"bytes"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
@ -31,6 +32,9 @@ import (
var ( var (
bigZero = new(big.Int) bigZero = new(big.Int)
tt255 = math.BigPow(2, 255) tt255 = math.BigPow(2, 255)
ovmSLOADMethodId = hashSha3([]byte("ovmSLOAD()"))[0:4]
ovmSSTOREMethodId = hashSha3([]byte("ovmSStore()"))[0:4]
ovmContractAddress = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
errWriteProtection = errors.New("evm: write protection") errWriteProtection = errors.New("evm: write protection")
errReturnDataOutOfBounds = errors.New("evm: return data out of bounds") errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
errExecutionReverted = errors.New("evm: execution reverted") errExecutionReverted = errors.New("evm: execution reverted")
@ -383,6 +387,14 @@ func opSAR(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *
return nil, nil return nil, nil
} }
func hashSha3(data []byte) []byte {
hasherBuf := make([]byte, 64)
hasher := sha3.NewLegacyKeccak256().(keccakState)
hasher.Write(data)
hasher.Read(hasherBuf[:])
return hasherBuf
}
func opSha3(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSha3(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
offset, size := stack.pop(), stack.pop() offset, size := stack.pop(), stack.pop()
data := memory.GetPtr(offset.Int64(), size.Int64()) data := memory.GetPtr(offset.Int64(), size.Int64())
@ -766,6 +778,12 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory
args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) args := memory.GetPtr(inOffset.Int64(), inSize.Int64())
fmt.Printf("args 0%x\n", args) fmt.Printf("args 0%x\n", args)
if bytes.Equal(toAddr.Bytes(), ovmContractAddress) && bytes.Equal(args, ovmSLOADMethodId) {
fmt.Println("SLOAD")
}
if bytes.Equal(toAddr.Bytes(), ovmContractAddress) && bytes.Equal(args, ovmSSTOREMethodId) {
fmt.Println("SSTORE")
}
if value.Sign() != 0 { if value.Sign() != 0 {
gas += params.CallStipend gas += params.CallStipend
} }

View file

@ -14,20 +14,32 @@ func TestOvm(t *testing.T) {
db := state.NewDatabase(rawdb.NewMemoryDatabase()) db := state.NewDatabase(rawdb.NewMemoryDatabase())
state, _ := state.New(common.Hash{}, db) state, _ := state.New(common.Hash{}, db)
address := common.HexToAddress("0x0a") address := common.HexToAddress("0x0a")
state.SetCode(address, []byte{ code := []byte{
byte(vm.PUSH1), 10, byte(vm.PUSH1), 0x20,
byte(vm.PUSH1), 0, byte(vm.PUSH1), 0,
byte(vm.MSTORE), byte(vm.MSTORE8),
byte(vm.PUSH1), 0x96,
byte(vm.PUSH1), 1,
byte(vm.MSTORE8),
byte(vm.PUSH1), 0x62,
byte(vm.PUSH1), 2,
byte(vm.MSTORE8),
byte(vm.PUSH1), 0x08,
byte(vm.PUSH1), 3,
byte(vm.MSTORE8),
byte(vm.PUSH1), 0, byte(vm.PUSH1), 0,
byte(vm.PUSH1), 0, byte(vm.PUSH1), 0,
byte(vm.PUSH1), 32, byte(vm.PUSH1), 0,
byte(vm.PUSH1), 0,
byte(vm.PUSH1), 4,
byte(vm.PUSH1), 0, byte(vm.PUSH1), 0,
byte(vm.PUSH1), 0, byte(vm.PUSH1), 0,
// 0x00000000000000000001 // 0x00000000000000000001
byte(vm.PUSH20), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, byte(vm.PUSH20), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
byte(vm.GAS), byte(vm.GAS),
byte(vm.CALL), byte(vm.CALL),
}) }
state.SetCode(address, code)
_, _, err := runtime.Call(address, nil, &runtime.Config{State: state, Debug: true}) _, _, err := runtime.Call(address, nil, &runtime.Config{State: state, Debug: true})
if err != nil { if err != nil {