Merge branch 'develop' of github.com:ethereum/eth-go into develop
This commit is contained in:
commit
fba6de834e
@ -28,7 +28,7 @@ func Disassemble(script []byte) (asm []string) {
|
|||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
data = []byte{0}
|
data = []byte{0}
|
||||||
}
|
}
|
||||||
asm = append(asm, fmt.Sprintf("%#x", data))
|
asm = append(asm, fmt.Sprintf("0x%x", data))
|
||||||
|
|
||||||
pc.Add(pc, big.NewInt(a-1))
|
pc.Add(pc, big.NewInt(a-1))
|
||||||
}
|
}
|
||||||
|
@ -120,6 +120,8 @@ func (self *State) GetOrNewStateObject(addr []byte) *StateObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *State) NewStateObject(addr []byte) *StateObject {
|
func (self *State) NewStateObject(addr []byte) *StateObject {
|
||||||
|
ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(+) %x\n", addr)
|
||||||
|
|
||||||
stateObject := NewStateObject(addr)
|
stateObject := NewStateObject(addr)
|
||||||
self.stateObjects[string(addr)] = stateObject
|
self.stateObjects[string(addr)] = stateObject
|
||||||
|
|
||||||
|
@ -97,7 +97,6 @@ func (self *StateTransition) BuyGas() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//self.state.UpdateStateObject(coinbase)
|
|
||||||
|
|
||||||
self.AddGas(self.tx.Gas)
|
self.AddGas(self.tx.Gas)
|
||||||
sender.SubAmount(self.tx.GasValue())
|
sender.SubAmount(self.tx.GasValue())
|
||||||
@ -115,7 +114,7 @@ func (self *StateTransition) RefundGas() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) TransitionState() (err error) {
|
func (self *StateTransition) TransitionState() (err error) {
|
||||||
//snapshot := st.state.Snapshot()
|
ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(~) %x\n", self.tx.Hash())
|
||||||
|
|
||||||
/*
|
/*
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -132,8 +131,6 @@ func (self *StateTransition) TransitionState() (err error) {
|
|||||||
receiver *StateObject
|
receiver *StateObject
|
||||||
)
|
)
|
||||||
|
|
||||||
ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(~) %x\n", tx.Hash())
|
|
||||||
|
|
||||||
// Make sure this transaction's nonce is correct
|
// Make sure this transaction's nonce is correct
|
||||||
if sender.Nonce != tx.Nonce {
|
if sender.Nonce != tx.Nonce {
|
||||||
return NonceError(tx.Nonce, sender.Nonce)
|
return NonceError(tx.Nonce, sender.Nonce)
|
||||||
@ -146,26 +143,11 @@ func (self *StateTransition) TransitionState() (err error) {
|
|||||||
|
|
||||||
// XXX Transactions after this point are considered valid.
|
// XXX Transactions after this point are considered valid.
|
||||||
|
|
||||||
defer func() {
|
defer self.RefundGas()
|
||||||
self.RefundGas()
|
|
||||||
|
|
||||||
/*
|
|
||||||
if sender != nil {
|
|
||||||
self.state.UpdateStateObject(sender)
|
|
||||||
}
|
|
||||||
|
|
||||||
if receiver != nil {
|
|
||||||
self.state.UpdateStateObject(receiver)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.state.UpdateStateObject(self.Coinbase())
|
|
||||||
*/
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Increment the nonce for the next transaction
|
// Increment the nonce for the next transaction
|
||||||
sender.Nonce += 1
|
sender.Nonce += 1
|
||||||
|
|
||||||
// Get the receiver (TODO fix this, if coinbase is the receiver we need to save/retrieve)
|
|
||||||
receiver = self.Receiver()
|
receiver = self.Receiver()
|
||||||
|
|
||||||
// Transaction gas
|
// Transaction gas
|
||||||
@ -254,6 +236,7 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by
|
|||||||
Diff: block.Difficulty,
|
Diff: block.Difficulty,
|
||||||
Value: tx.Value,
|
Value: tx.Value,
|
||||||
})
|
})
|
||||||
|
vm.Verbose = true
|
||||||
ret, _, err = closure.Call(vm, tx.Data, nil)
|
ret, _, err = closure.Call(vm, tx.Data, nil)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -65,7 +65,7 @@ func (tx *Transaction) CreatesContract() bool {
|
|||||||
return tx.contractCreation
|
return tx.contractCreation
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Depricated */
|
/* Deprecated */
|
||||||
func (tx *Transaction) IsContract() bool {
|
func (tx *Transaction) IsContract() bool {
|
||||||
return tx.CreatesContract()
|
return tx.CreatesContract()
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ var opCodeToString = map[OpCode]string{
|
|||||||
func (o OpCode) String() string {
|
func (o OpCode) String() string {
|
||||||
str := opCodeToString[o]
|
str := opCodeToString[o]
|
||||||
if len(str) == 0 {
|
if len(str) == 0 {
|
||||||
return fmt.Sprintf("Missing opcode %#x", int(o))
|
return fmt.Sprintf("Missing opcode 0x%x", int(o))
|
||||||
}
|
}
|
||||||
|
|
||||||
return str
|
return str
|
||||||
|
115
ethchain/vm.go
115
ethchain/vm.go
@ -45,6 +45,10 @@ type Vm struct {
|
|||||||
state *State
|
state *State
|
||||||
|
|
||||||
stateManager *StateManager
|
stateManager *StateManager
|
||||||
|
|
||||||
|
Verbose bool
|
||||||
|
|
||||||
|
logStr string
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuntimeVars struct {
|
type RuntimeVars struct {
|
||||||
@ -58,6 +62,23 @@ type RuntimeVars struct {
|
|||||||
Value *big.Int
|
Value *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Vm) Printf(format string, v ...interface{}) *Vm {
|
||||||
|
if self.Verbose {
|
||||||
|
self.logStr += fmt.Sprintf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Vm) Endl() *Vm {
|
||||||
|
if self.Verbose {
|
||||||
|
ethutil.Config.Log.Infoln(self.logStr)
|
||||||
|
self.logStr = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
func NewVm(state *State, stateManager *StateManager, vars RuntimeVars) *Vm {
|
func NewVm(state *State, stateManager *StateManager, vars RuntimeVars) *Vm {
|
||||||
return &Vm{vars: vars, state: state, stateManager: stateManager}
|
return &Vm{vars: vars, state: state, stateManager: stateManager}
|
||||||
}
|
}
|
||||||
@ -76,7 +97,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ethutil.Config.Log.Debugf("[VM] Running closure %x\n", closure.object.Address())
|
ethutil.Config.Log.Debugf("[VM] Running %x\n", closure.object.Address())
|
||||||
|
|
||||||
// Memory for the current closure
|
// Memory for the current closure
|
||||||
mem := &Memory{}
|
mem := &Memory{}
|
||||||
@ -95,8 +116,6 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
step := 0
|
step := 0
|
||||||
prevStep := 0
|
prevStep := 0
|
||||||
|
|
||||||
ethutil.Config.Log.Debugf("# op\n")
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
prevStep = step
|
prevStep = step
|
||||||
// The base for all big integer arithmetic
|
// The base for all big integer arithmetic
|
||||||
@ -108,7 +127,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
// Get the opcode (it must be an opcode!)
|
// Get the opcode (it must be an opcode!)
|
||||||
op := OpCode(val.Uint())
|
op := OpCode(val.Uint())
|
||||||
|
|
||||||
ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
|
vm.Printf("(pc) %-3d -o- %-14s", pc, op.String())
|
||||||
|
//ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
|
||||||
|
|
||||||
gas := new(big.Int)
|
gas := new(big.Int)
|
||||||
addStepGasUsage := func(amount *big.Int) {
|
addStepGasUsage := func(amount *big.Int) {
|
||||||
@ -120,7 +140,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
var newMemSize uint64 = 0
|
var newMemSize uint64 = 0
|
||||||
switch op {
|
switch op {
|
||||||
case STOP:
|
case STOP:
|
||||||
|
gas.Set(ethutil.Big0)
|
||||||
case SUICIDE:
|
case SUICIDE:
|
||||||
|
gas.Set(ethutil.Big0)
|
||||||
case SLOAD:
|
case SLOAD:
|
||||||
gas.Set(GasSLoad)
|
gas.Set(GasSLoad)
|
||||||
case SSTORE:
|
case SSTORE:
|
||||||
@ -191,6 +213,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
return closure.Return(nil), fmt.Errorf("insufficient gas %v %v", closure.Gas, gas)
|
return closure.Return(nil), fmt.Errorf("insufficient gas %v %v", closure.Gas, gas)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm.Printf(" (g) %-3v (%v)", gas, closure.Gas)
|
||||||
|
|
||||||
mem.Resize(newMemSize)
|
mem.Resize(newMemSize)
|
||||||
|
|
||||||
switch op {
|
switch op {
|
||||||
@ -202,28 +226,28 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
// (x + y) % 2 ** 256
|
// (x + y) % 2 ** 256
|
||||||
base.Add(x, y)
|
base.Add(y, x)
|
||||||
// Pop result back on the stack
|
// Pop result back on the stack
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case SUB:
|
case SUB:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
// (x - y) % 2 ** 256
|
// (x - y) % 2 ** 256
|
||||||
base.Sub(x, y)
|
base.Sub(y, x)
|
||||||
// Pop result back on the stack
|
// Pop result back on the stack
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case MUL:
|
case MUL:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
// (x * y) % 2 ** 256
|
// (x * y) % 2 ** 256
|
||||||
base.Mul(x, y)
|
base.Mul(y, x)
|
||||||
// Pop result back on the stack
|
// Pop result back on the stack
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case DIV:
|
case DIV:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
// floor(x / y)
|
// floor(x / y)
|
||||||
base.Div(x, y)
|
base.Div(y, x)
|
||||||
// Pop result back on the stack
|
// Pop result back on the stack
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case SDIV:
|
case SDIV:
|
||||||
@ -246,7 +270,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
case MOD:
|
case MOD:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
base.Mod(x, y)
|
base.Mod(y, x)
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case SMOD:
|
case SMOD:
|
||||||
require(2)
|
require(2)
|
||||||
@ -268,7 +292,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
case EXP:
|
case EXP:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
base.Exp(x, y, Pow256)
|
base.Exp(y, x, Pow256)
|
||||||
|
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case NEG:
|
case NEG:
|
||||||
@ -277,7 +301,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case LT:
|
case LT:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
y, x := stack.Popn()
|
||||||
|
vm.Printf(" %v < %v", x, y)
|
||||||
// x < y
|
// x < y
|
||||||
if x.Cmp(y) < 0 {
|
if x.Cmp(y) < 0 {
|
||||||
stack.Push(ethutil.BigTrue)
|
stack.Push(ethutil.BigTrue)
|
||||||
@ -286,7 +311,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
}
|
}
|
||||||
case GT:
|
case GT:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
y, x := stack.Popn()
|
||||||
|
vm.Printf(" %v > %v", x, y)
|
||||||
|
|
||||||
// x > y
|
// x > y
|
||||||
if x.Cmp(y) > 0 {
|
if x.Cmp(y) > 0 {
|
||||||
stack.Push(ethutil.BigTrue)
|
stack.Push(ethutil.BigTrue)
|
||||||
@ -296,6 +323,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
case EQ:
|
case EQ:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
|
vm.Printf(" %v == %v", y, x)
|
||||||
|
|
||||||
// x == y
|
// x == y
|
||||||
if x.Cmp(y) == 0 {
|
if x.Cmp(y) == 0 {
|
||||||
stack.Push(ethutil.BigTrue)
|
stack.Push(ethutil.BigTrue)
|
||||||
@ -315,24 +344,21 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
case AND:
|
case AND:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
if (x.Cmp(ethutil.BigTrue) >= 0) && (y.Cmp(ethutil.BigTrue) >= 0) {
|
vm.Printf(" %v & %v", y, x)
|
||||||
stack.Push(ethutil.BigTrue)
|
|
||||||
} else {
|
|
||||||
stack.Push(ethutil.BigFalse)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
stack.Push(base.And(y, x))
|
||||||
case OR:
|
case OR:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
if (x.Cmp(ethutil.BigInt0) >= 0) || (y.Cmp(ethutil.BigInt0) >= 0) {
|
vm.Printf(" %v | %v", y, x)
|
||||||
stack.Push(ethutil.BigTrue)
|
|
||||||
} else {
|
stack.Push(base.Or(y, x))
|
||||||
stack.Push(ethutil.BigFalse)
|
|
||||||
}
|
|
||||||
case XOR:
|
case XOR:
|
||||||
require(2)
|
require(2)
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
stack.Push(base.Xor(x, y))
|
vm.Printf(" %v ^ %v", y, x)
|
||||||
|
|
||||||
|
stack.Push(base.Xor(y, x))
|
||||||
case BYTE:
|
case BYTE:
|
||||||
require(2)
|
require(2)
|
||||||
val, th := stack.Popn()
|
val, th := stack.Popn()
|
||||||
@ -357,7 +383,10 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
case ORIGIN:
|
case ORIGIN:
|
||||||
stack.Push(ethutil.BigD(vm.vars.Origin))
|
stack.Push(ethutil.BigD(vm.vars.Origin))
|
||||||
case CALLER:
|
case CALLER:
|
||||||
stack.Push(ethutil.BigD(closure.caller.Address()))
|
caller := closure.caller.Address()
|
||||||
|
stack.Push(ethutil.BigD(caller))
|
||||||
|
|
||||||
|
vm.Printf(" => %x", caller)
|
||||||
case CALLVALUE:
|
case CALLVALUE:
|
||||||
stack.Push(vm.vars.Value)
|
stack.Push(vm.vars.Value)
|
||||||
case CALLDATALOAD:
|
case CALLDATALOAD:
|
||||||
@ -365,15 +394,21 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
offset := stack.Pop().Int64()
|
offset := stack.Pop().Int64()
|
||||||
|
|
||||||
var data []byte
|
var data []byte
|
||||||
if len(closure.Args) >= int(offset+32) {
|
if len(closure.Args) >= int(offset) {
|
||||||
data = closure.Args[offset : offset+32]
|
l := int64(math.Min(float64(offset+32), float64(len(closure.Args))))
|
||||||
|
data = closure.Args[offset : offset+l]
|
||||||
} else {
|
} else {
|
||||||
data = []byte{0}
|
data = []byte{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm.Printf(" => 0x%x", data)
|
||||||
|
|
||||||
stack.Push(ethutil.BigD(data))
|
stack.Push(ethutil.BigD(data))
|
||||||
case CALLDATASIZE:
|
case CALLDATASIZE:
|
||||||
stack.Push(big.NewInt(int64(len(closure.Args))))
|
l := int64(len(closure.Args))
|
||||||
|
stack.Push(big.NewInt(l))
|
||||||
|
|
||||||
|
vm.Printf(" => %d", l)
|
||||||
case CALLDATACOPY:
|
case CALLDATACOPY:
|
||||||
case CODESIZE:
|
case CODESIZE:
|
||||||
case CODECOPY:
|
case CODECOPY:
|
||||||
@ -423,6 +458,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
pc.Add(pc, a.Sub(a, big.NewInt(1)))
|
pc.Add(pc, a.Sub(a, big.NewInt(1)))
|
||||||
|
|
||||||
step += int(op) - int(PUSH1) + 1
|
step += int(op) - int(PUSH1) + 1
|
||||||
|
|
||||||
|
vm.Printf(" => 0x%x", data.Bytes())
|
||||||
case POP:
|
case POP:
|
||||||
require(1)
|
require(1)
|
||||||
stack.Pop()
|
stack.Pop()
|
||||||
@ -443,38 +480,50 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
// Pop value of the stack
|
// Pop value of the stack
|
||||||
val, mStart := stack.Popn()
|
val, mStart := stack.Popn()
|
||||||
mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256))
|
mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256))
|
||||||
|
|
||||||
|
vm.Printf(" => 0x%x", val)
|
||||||
case MSTORE8:
|
case MSTORE8:
|
||||||
require(2)
|
require(2)
|
||||||
val, mStart := stack.Popn()
|
val, mStart := stack.Popn()
|
||||||
base.And(val, new(big.Int).SetInt64(0xff))
|
base.And(val, new(big.Int).SetInt64(0xff))
|
||||||
mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(base, 256))
|
mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(base, 256))
|
||||||
|
|
||||||
|
vm.Printf(" => 0x%x", val)
|
||||||
case SLOAD:
|
case SLOAD:
|
||||||
require(1)
|
require(1)
|
||||||
loc := stack.Pop()
|
loc := stack.Pop()
|
||||||
val := closure.GetMem(loc)
|
val := closure.GetMem(loc)
|
||||||
//fmt.Println("get", val.BigInt(), "@", loc)
|
|
||||||
stack.Push(val.BigInt())
|
stack.Push(val.BigInt())
|
||||||
|
|
||||||
|
vm.Printf(" {} 0x%x", val)
|
||||||
case SSTORE:
|
case SSTORE:
|
||||||
require(2)
|
require(2)
|
||||||
val, loc := stack.Popn()
|
val, loc := stack.Popn()
|
||||||
//fmt.Println("storing", val, "@", loc)
|
fmt.Println("storing", string(val.Bytes()), "@", string(loc.Bytes()))
|
||||||
closure.SetStorage(loc, ethutil.NewValue(val))
|
closure.SetStorage(loc, ethutil.NewValue(val))
|
||||||
|
|
||||||
// Add the change to manifest
|
// Add the change to manifest
|
||||||
vm.state.manifest.AddStorageChange(closure.Object(), loc.Bytes(), val)
|
vm.state.manifest.AddStorageChange(closure.Object(), loc.Bytes(), val)
|
||||||
|
|
||||||
|
vm.Printf(" => 0x%x", val)
|
||||||
case JUMP:
|
case JUMP:
|
||||||
require(1)
|
require(1)
|
||||||
pc = stack.Pop()
|
pc = stack.Pop()
|
||||||
// Reduce pc by one because of the increment that's at the end of this for loop
|
// Reduce pc by one because of the increment that's at the end of this for loop
|
||||||
//pc.Sub(pc, ethutil.Big1)
|
vm.Printf(" ~> %v", pc).Endl()
|
||||||
|
|
||||||
continue
|
continue
|
||||||
case JUMPI:
|
case JUMPI:
|
||||||
require(2)
|
require(2)
|
||||||
cond, pos := stack.Popn()
|
cond, pos := stack.Popn()
|
||||||
if cond.Cmp(ethutil.BigTrue) == 0 {
|
if cond.Cmp(ethutil.BigTrue) >= 0 {
|
||||||
pc = pos
|
pc = pos
|
||||||
//pc.Sub(pc, ethutil.Big1)
|
|
||||||
|
vm.Printf(" (t) ~> %v", pc).Endl()
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
} else {
|
||||||
|
vm.Printf(" (f)")
|
||||||
}
|
}
|
||||||
case PC:
|
case PC:
|
||||||
stack.Push(pc)
|
stack.Push(pc)
|
||||||
@ -599,6 +648,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||||||
|
|
||||||
pc.Add(pc, ethutil.Big1)
|
pc.Add(pc, ethutil.Big1)
|
||||||
|
|
||||||
|
vm.Endl()
|
||||||
|
|
||||||
if hook != nil {
|
if hook != nil {
|
||||||
if !hook(prevStep, op, mem, stack, closure.Object()) {
|
if !hook(prevStep, op, mem, stack, closure.Object()) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -170,11 +170,6 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, sc
|
|||||||
|
|
||||||
tx = ethchain.NewContractCreationTx(value, gas, gasPrice, script)
|
tx = ethchain.NewContractCreationTx(value, gas, gasPrice, script)
|
||||||
} else {
|
} else {
|
||||||
// Just in case it was submitted as a 0x prefixed string
|
|
||||||
if len(scriptStr) > 0 && scriptStr[0:2] == "0x" {
|
|
||||||
scriptStr = scriptStr[2:len(scriptStr)]
|
|
||||||
}
|
|
||||||
|
|
||||||
data := ethutil.StringToByteFunc(scriptStr, func(s string) (ret []byte) {
|
data := ethutil.StringToByteFunc(scriptStr, func(s string) (ret []byte) {
|
||||||
slice := strings.Split(s, "\n")
|
slice := strings.Split(s, "\n")
|
||||||
for _, dataItem := range slice {
|
for _, dataItem := range slice {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Number to bytes
|
// Number to bytes
|
||||||
@ -91,7 +92,7 @@ func IsHex(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) {
|
func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) {
|
||||||
if len(str) > 1 && str[0:2] == "0x" {
|
if len(str) > 1 && str[0:2] == "0x" && !strings.Contains(str, "\n") {
|
||||||
ret = FromHex(str[2:])
|
ret = FromHex(str[2:])
|
||||||
} else {
|
} else {
|
||||||
ret = cb(str)
|
ret = cb(str)
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
package ethutil
|
package ethutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -171,14 +176,34 @@ func TestTriePurge(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrieIt(t *testing.T) {
|
type TestItem struct {
|
||||||
_, trie := New()
|
Name string
|
||||||
trie.Update("c", LONG_WORD)
|
Inputs [][]string
|
||||||
trie.Update("ca", LONG_WORD)
|
Expectations string
|
||||||
trie.Update("cat", LONG_WORD)
|
}
|
||||||
|
|
||||||
it := trie.NewIterator()
|
func TestTrieIt(t *testing.T) {
|
||||||
it.Each(func(key string, node *Value) {
|
//_, trie := New()
|
||||||
fmt.Println(key, ":", node.Str())
|
resp, err := http.Get("https://raw.githubusercontent.com/ethereum/tests/master/trietest.json")
|
||||||
})
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
dec := json.NewDecoder(bytes.NewReader(body))
|
||||||
|
for {
|
||||||
|
var test TestItem
|
||||||
|
if err := dec.Decode(&test); err == io.EOF {
|
||||||
|
break
|
||||||
|
} else if err != nil {
|
||||||
|
t.Error("Fail something", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fmt.Println(test)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user