Renames for chain, updated VM, moved methods

* Renamed a couple more chain => core
* Updated VM `pc` to be uint64 rather than big int
* XEth interface cleanup
This commit is contained in:
obscuren 2014-12-04 10:53:49 +01:00
parent 9008b155d3
commit 83663ed4b0
9 changed files with 94 additions and 102 deletions

View File

@ -22,8 +22,8 @@ import (
"os"
"runtime"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
)

View File

@ -6,7 +6,7 @@ import (
"testing"
"time"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"

View File

@ -4,7 +4,7 @@ import (
"container/list"
"fmt"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"

View File

@ -3,7 +3,7 @@ package helper
import (
"math/big"
"github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
@ -66,9 +66,9 @@ func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error {
return vm.Transfer(from, to, amount)
}
func (self *Env) vm(addr, data []byte, gas, price, value *big.Int) *chain.Execution {
func (self *Env) vm(addr, data []byte, gas, price, value *big.Int) *core.Execution {
evm := vm.New(self, vm.DebugVmTy)
exec := chain.NewExecution(evm, addr, data, gas, price, value)
exec := core.NewExecution(evm, addr, data, gas, price, value)
exec.SkipTransfer = self.skipTransfer
return exec

View File

@ -6,7 +6,7 @@ import (
"strconv"
"testing"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/tests/helper"

View File

@ -6,17 +6,17 @@ import (
"github.com/ethereum/go-ethereum/ethutil"
)
func analyseJumpDests(code []byte) (dests map[int64]*big.Int) {
dests = make(map[int64]*big.Int)
func analyseJumpDests(code []byte) (dests map[uint64]*big.Int) {
dests = make(map[uint64]*big.Int)
lp := false
var lpv *big.Int
for pc := int64(0); pc < int64(len(code)); pc++ {
for pc := uint64(0); pc < uint64(len(code)); pc++ {
var op OpCode = OpCode(code[pc])
switch op {
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
a := int64(op) - int64(PUSH1) + 1
if int64(len(code)) > pc+1+a {
a := uint64(op) - uint64(PUSH1) + 1
if uint64(len(code)) > pc+1+a {
lpv = ethutil.BigD(code[pc+1 : pc+1+a])
}

View File

@ -41,16 +41,16 @@ func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code [
return c
}
func (c *Closure) GetValue(x *big.Int) *ethutil.Value {
return c.GetRangeValue(x, big.NewInt(1))
func (c *Closure) GetValue(x uint64) *ethutil.Value {
return c.GetRangeValue(x, 1)
}
func (c *Closure) GetOp(x int) OpCode {
func (c *Closure) GetOp(x uint64) OpCode {
return OpCode(c.GetByte(x))
}
func (c *Closure) GetByte(x int) byte {
if x > -1 && x < len(c.Code) {
func (c *Closure) GetByte(x uint64) byte {
if x < uint64(len(c.Code)) {
return c.Code[x]
}
@ -65,12 +65,12 @@ func (c *Closure) GetBytes(x, y int) []byte {
return c.Code[x : x+y]
}
func (c *Closure) GetRangeValue(x, y *big.Int) *ethutil.Value {
if x.Int64() >= int64(len(c.Code)) || y.Int64() >= int64(len(c.Code)) {
func (c *Closure) GetRangeValue(x, y uint64) *ethutil.Value {
if x >= uint64(len(c.Code)) || y >= uint64(len(c.Code)) {
return ethutil.NewValue(0)
}
partial := c.Code[x.Int64() : x.Int64()+y.Int64()]
partial := c.Code[x : x+y]
return ethutil.NewValue(partial)
}

View File

@ -75,35 +75,35 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
var (
op OpCode
destinations = analyseJumpDests(closure.Code)
mem = NewMemory()
stack = NewStack()
pc = big.NewInt(0)
step = 0
prevStep = 0
statedb = self.env.State()
require = func(m int) {
destinations = analyseJumpDests(closure.Code)
mem = NewMemory()
stack = NewStack()
pc uint64 = 0
step = 0
prevStep = 0
statedb = self.env.State()
require = func(m int) {
if stack.Len() < m {
panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, stack.Len(), m))
}
}
jump = func(from, to *big.Int) {
p := int(to.Int64())
jump = func(from uint64, to *big.Int) {
p := to.Uint64()
self.Printf(" ~> %v", to)
// Return to start
if p == 0 {
pc = big.NewInt(0)
pc = 0
} else {
nop := OpCode(closure.GetOp(p))
if !(nop == JUMPDEST || destinations[from.Int64()] != nil) {
if !(nop == JUMPDEST || destinations[from] != nil) {
panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p))
} else if nop == JUMP || nop == JUMPI {
panic(fmt.Sprintf("not allowed to JUMP(I) in to JUMP"))
}
pc = to
pc = to.Uint64()
}
@ -125,26 +125,28 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
step++
// Get the memory location of pc
op = closure.GetOp(int(pc.Uint64()))
op = closure.GetOp(pc)
// XXX Leave this Println intact. Don't change this to the log system.
// Used for creating diffs between implementations
if self.logTy == LogTyDiff {
switch op {
case STOP, RETURN, SUICIDE:
statedb.GetStateObject(closure.Address()).EachStorage(func(key string, value *ethutil.Value) {
value.Decode()
fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes())
})
/*
// XXX Leave this Println intact. Don't change this to the log system.
// Used for creating diffs between implementations
if self.logTy == LogTyDiff {
switch op {
case STOP, RETURN, SUICIDE:
statedb.GetStateObject(closure.Address()).EachStorage(func(key string, value *ethutil.Value) {
value.Decode()
fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes())
})
}
b := pc.Bytes()
if len(b) == 0 {
b = []byte{0}
}
fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes())
}
b := pc.Bytes()
if len(b) == 0 {
b = []byte{0}
}
fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes())
}
*/
gas := new(big.Int)
addStepGasUsage := func(amount *big.Int) {
@ -735,13 +737,15 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
// 0x50 range
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
a := big.NewInt(int64(op) - int64(PUSH1) + 1)
pc.Add(pc, ethutil.Big1)
data := closure.GetRangeValue(pc, a)
//a := big.NewInt(int64(op) - int64(PUSH1) + 1)
a := uint64(op - PUSH1 + 1)
//pc.Add(pc, ethutil.Big1)
data := closure.GetRangeValue(pc+1, a)
val := ethutil.BigD(data.Bytes())
// Push value to stack
stack.Push(val)
pc.Add(pc, a.Sub(a, big.NewInt(1)))
pc += a
//pc.Add(pc, a.Sub(a, big.NewInt(1)))
step += int(op) - int(PUSH1) + 1
@ -750,13 +754,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
stack.Pop()
case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
n := int(op - DUP1 + 1)
v := stack.Dupn(n)
stack.Dupn(n)
self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
if OpCode(closure.GetValue(new(big.Int).Add(pc, ethutil.Big1)).Uint()) == POP && OpCode(closure.GetValue(new(big.Int).Add(pc, big.NewInt(2))).Uint()) == POP {
fmt.Println(toValue(v))
}
case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
n := int(op - SWAP1 + 2)
x, y := stack.Swapn(n)
@ -811,7 +811,6 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
case JUMP:
jump(pc, stack.Pop())
continue
@ -826,7 +825,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
case JUMPDEST:
case PC:
stack.Push(pc)
stack.Push(big.NewInt(int64(pc)))
case MSIZE:
stack.Push(big.NewInt(int64(mem.Len())))
case GAS:
@ -940,13 +939,13 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
}
pc.Add(pc, ethutil.Big1)
pc++
self.Endl()
if self.Dbg != nil {
for _, instrNo := range self.Dbg.BreakPoints() {
if pc.Cmp(big.NewInt(instrNo)) == 0 {
if pc == uint64(instrNo) {
self.Stepping = true
if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {

View File

@ -39,6 +39,9 @@ func New(obj core.EthManager) *XEth {
return pipe
}
/*
* State / Account accessors
*/
func (self *XEth) Balance(addr []byte) *ethutil.Value {
return ethutil.NewValue(self.World().safeGet(addr).Balance)
}
@ -47,6 +50,31 @@ func (self *XEth) Nonce(addr []byte) uint64 {
return self.World().safeGet(addr).Nonce
}
func (self *XEth) Block(hash []byte) *types.Block {
return self.blockChain.GetBlock(hash)
}
func (self *XEth) Storage(addr, storageAddr []byte) *ethutil.Value {
return self.World().safeGet(addr).GetStorage(ethutil.BigD(storageAddr))
}
func (self *XEth) Exists(addr []byte) bool {
return self.World().Get(addr) != nil
}
// Converts the given private key to an address
func (self *XEth) ToAddress(priv []byte) []byte {
pair, err := crypto.NewKeyPairFromSec(priv)
if err != nil {
return nil
}
return pair.Address()
}
/*
* Execution helpers
*/
func (self *XEth) Execute(addr []byte, data []byte, value, gas, price *ethutil.Value) ([]byte, error) {
return self.ExecuteObject(&Object{self.World().safeGet(addr)}, data, value, gas, price)
}
@ -61,39 +89,11 @@ func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *
vmenv := NewEnv(self.Vm.State, block, value.BigInt(), initiator.Address())
return vmenv.Call(initiator, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt())
/*
evm := vm.New(, vm.Type(ethutil.Config.VmType))
msg := vm.NewExecution(evm, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt())
ret, err := msg.Exec(object.Address(), initiator)
fmt.Println("returned from call", ret, err)
return ret, err
*/
}
func (self *XEth) Block(hash []byte) *types.Block {
return self.blockChain.GetBlock(hash)
}
func (self *XEth) Storage(addr, storageAddr []byte) *ethutil.Value {
return self.World().safeGet(addr).GetStorage(ethutil.BigD(storageAddr))
}
func (self *XEth) ToAddress(priv []byte) []byte {
pair, err := crypto.NewKeyPairFromSec(priv)
if err != nil {
return nil
}
return pair.Address()
}
func (self *XEth) Exists(addr []byte) bool {
return self.World().Get(addr) != nil
}
/*
* Transactional methods
*/
func (self *XEth) TransactString(key *crypto.KeyPair, rec string, value, gas, price *ethutil.Value, data []byte) (*types.Transaction, error) {
// Check if an address is stored by this address
var hash []byte
@ -149,13 +149,6 @@ func (self *XEth) Transact(key *crypto.KeyPair, to []byte, value, gas, price *et
}
return tx, nil
//acc := self.blockManager.TransState().GetOrNewStateObject(key.Address())
//self.obj.TxPool().QueueTransaction(tx)
//acc.Nonce += 1
//self.blockManager.TransState().UpdateStateObject(acc)
}
func (self *XEth) PushTx(tx *types.Transaction) ([]byte, error) {