From 60cdb1148c404218846fd39331690658168f4e04 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 12 Nov 2014 01:36:36 +0100 Subject: Transaction execution fixes --- vm/closure.go | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'vm/closure.go') diff --git a/vm/closure.go b/vm/closure.go index 8e54e9ce6..ef9bbca93 100644 --- a/vm/closure.go +++ b/vm/closure.go @@ -138,3 +138,7 @@ func (c *Closure) Object() *state.StateObject { func (c *Closure) Caller() ClosureRef { return c.caller } + +func (self *Closure) SetExecution(exe *Execution) { + self.exe = exe +} -- cgit v1.2.3 From a22056db5988bfa2b1354e0092eabb734c30701c Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 1 Dec 2014 20:49:56 +0100 Subject: Make an attempt to pay for the gas prior to expanding the mem. --- vm/closure.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'vm/closure.go') diff --git a/vm/closure.go b/vm/closure.go index ef9bbca93..5bd8c1bb8 100644 --- a/vm/closure.go +++ b/vm/closure.go @@ -64,7 +64,7 @@ func (c *Closure) GetOp(x int) OpCode { } func (c *Closure) GetByte(x int) byte { - if x < len(c.Code) { + if x > -1 && x < len(c.Code) { return c.Code[x] } -- cgit v1.2.3 From 99853ac3ce57807deb4822dd324186e1d2ee0821 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 3 Dec 2014 17:06:54 +0100 Subject: Moved execution from vm to chain. This moves call and create to the specified environments. Vms are no longer re-used. Vm uses environment's Call(Code) and Create in order to execute new contracts or transfer value between accounts. State transition now uses the same mechanism described above. --- vm/closure.go | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'vm/closure.go') diff --git a/vm/closure.go b/vm/closure.go index 5bd8c1bb8..2263236e7 100644 --- a/vm/closure.go +++ b/vm/closure.go @@ -12,7 +12,7 @@ import ( type ClosureRef interface { ReturnGas(*big.Int, *big.Int) Address() []byte - Object() *state.StateObject + SetCode([]byte) GetStorage(*big.Int) *ethutil.Value SetStorage(*big.Int, *ethutil.Value) } @@ -20,10 +20,9 @@ type ClosureRef interface { // Basic inline closure object which implement the 'closure' interface type Closure struct { caller ClosureRef - object *state.StateObject + object ClosureRef Code []byte message *state.Message - exe *Execution Gas, UsedGas, Price *big.Int @@ -31,7 +30,7 @@ type Closure struct { } // Create a new closure for the given data items -func NewClosure(msg *state.Message, caller ClosureRef, object *state.StateObject, code []byte, gas, price *big.Int) *Closure { +func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code []byte, gas, price *big.Int) *Closure { c := &Closure{message: msg, caller: caller, object: object, Code: code, Args: nil} // Gas should be a pointer so it can safely be reduced through the run @@ -89,6 +88,10 @@ func (c *Closure) Gets(x, y *big.Int) *ethutil.Value { return ethutil.NewValue(partial) } +func (self *Closure) SetCode(code []byte) { + self.Code = code +} + func (c *Closure) SetStorage(x *big.Int, val *ethutil.Value) { c.object.SetStorage(x, val) } @@ -97,6 +100,7 @@ func (c *Closure) Address() []byte { return c.object.Address() } +/* func (c *Closure) Call(vm VirtualMachine, args []byte) ([]byte, *big.Int, error) { c.Args = args @@ -104,6 +108,7 @@ func (c *Closure) Call(vm VirtualMachine, args []byte) ([]byte, *big.Int, error) return ret, c.UsedGas, err } +*/ func (c *Closure) Return(ret []byte) []byte { // Return the remaining gas to the caller @@ -131,14 +136,6 @@ func (c *Closure) ReturnGas(gas, price *big.Int) { c.UsedGas.Sub(c.UsedGas, gas) } -func (c *Closure) Object() *state.StateObject { - return c.object -} - func (c *Closure) Caller() ClosureRef { return c.caller } - -func (self *Closure) SetExecution(exe *Execution) { - self.exe = exe -} -- cgit v1.2.3 From b6cb5272de96185b424d5c6c4a817d99f536d29b Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 3 Dec 2014 17:35:57 +0100 Subject: Descriptive function names for closure getters --- vm/closure.go | 57 ++++++++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) (limited to 'vm/closure.go') diff --git a/vm/closure.go b/vm/closure.go index 2263236e7..5324ee1ec 100644 --- a/vm/closure.go +++ b/vm/closure.go @@ -1,7 +1,5 @@ package vm -// TODO Re write VM to use values instead of big integers? - import ( "math/big" @@ -17,7 +15,6 @@ type ClosureRef interface { SetStorage(*big.Int, *ethutil.Value) } -// Basic inline closure object which implement the 'closure' interface type Closure struct { caller ClosureRef object ClosureRef @@ -44,18 +41,8 @@ func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code [ return c } -// Retuns the x element in data slice -func (c *Closure) GetStorage(x *big.Int) *ethutil.Value { - m := c.object.GetStorage(x) - if m == nil { - return ethutil.EmptyValue() - } - - return m -} - -func (c *Closure) Get(x *big.Int) *ethutil.Value { - return c.Gets(x, big.NewInt(1)) +func (c *Closure) GetValue(x *big.Int) *ethutil.Value { + return c.GetRangeValue(x, big.NewInt(1)) } func (c *Closure) GetOp(x int) OpCode { @@ -78,7 +65,7 @@ func (c *Closure) GetBytes(x, y int) []byte { return c.Code[x : x+y] } -func (c *Closure) Gets(x, y *big.Int) *ethutil.Value { +func (c *Closure) GetRangeValue(x, y *big.Int) *ethutil.Value { if x.Int64() >= int64(len(c.Code)) || y.Int64() >= int64(len(c.Code)) { return ethutil.NewValue(0) } @@ -88,27 +75,21 @@ func (c *Closure) Gets(x, y *big.Int) *ethutil.Value { return ethutil.NewValue(partial) } -func (self *Closure) SetCode(code []byte) { - self.Code = code -} - +/* + * State storage functions + */ func (c *Closure) SetStorage(x *big.Int, val *ethutil.Value) { c.object.SetStorage(x, val) } -func (c *Closure) Address() []byte { - return c.object.Address() -} - -/* -func (c *Closure) Call(vm VirtualMachine, args []byte) ([]byte, *big.Int, error) { - c.Args = args - - ret, err := vm.RunClosure(c) +func (c *Closure) GetStorage(x *big.Int) *ethutil.Value { + m := c.object.GetStorage(x) + if m == nil { + return ethutil.EmptyValue() + } - return ret, c.UsedGas, err + return m } -*/ func (c *Closure) Return(ret []byte) []byte { // Return the remaining gas to the caller @@ -117,6 +98,9 @@ func (c *Closure) Return(ret []byte) []byte { return ret } +/* + * Gas functions + */ func (c *Closure) UseGas(gas *big.Int) bool { if c.Gas.Cmp(gas) < 0 { return false @@ -136,6 +120,17 @@ func (c *Closure) ReturnGas(gas, price *big.Int) { c.UsedGas.Sub(c.UsedGas, gas) } +/* + * Set / Get + */ func (c *Closure) Caller() ClosureRef { return c.caller } + +func (c *Closure) Address() []byte { + return c.object.Address() +} + +func (self *Closure) SetCode(code []byte) { + self.Code = code +} -- cgit v1.2.3 From 83663ed4b01480c628ce2c849e4e881ac04b5120 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 4 Dec 2014 10:53:49 +0100 Subject: 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 --- vm/closure.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'vm/closure.go') diff --git a/vm/closure.go b/vm/closure.go index 5324ee1ec..bd5268f96 100644 --- a/vm/closure.go +++ b/vm/closure.go @@ -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) } -- cgit v1.2.3 From 59ef6e36931c980ba15babfb3680514635faebf6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 19 Dec 2014 00:18:52 +0100 Subject: Cleaned up objects --- vm/closure.go | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) (limited to 'vm/closure.go') diff --git a/vm/closure.go b/vm/closure.go index bd5268f96..97b31ada0 100644 --- a/vm/closure.go +++ b/vm/closure.go @@ -3,7 +3,6 @@ package vm import ( "math/big" - "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/state" ) @@ -11,8 +10,6 @@ type ClosureRef interface { ReturnGas(*big.Int, *big.Int) Address() []byte SetCode([]byte) - GetStorage(*big.Int) *ethutil.Value - SetStorage(*big.Int, *ethutil.Value) } type Closure struct { @@ -41,10 +38,6 @@ func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code [ return c } -func (c *Closure) GetValue(x uint64) *ethutil.Value { - return c.GetRangeValue(x, 1) -} - func (c *Closure) GetOp(x uint64) OpCode { return OpCode(c.GetByte(x)) } @@ -65,30 +58,12 @@ func (c *Closure) GetBytes(x, y int) []byte { return c.Code[x : x+y] } -func (c *Closure) GetRangeValue(x, y uint64) *ethutil.Value { +func (c *Closure) GetRangeValue(x, y uint64) []byte { if x >= uint64(len(c.Code)) || y >= uint64(len(c.Code)) { - return ethutil.NewValue(0) - } - - partial := c.Code[x : x+y] - - return ethutil.NewValue(partial) -} - -/* - * State storage functions - */ -func (c *Closure) SetStorage(x *big.Int, val *ethutil.Value) { - c.object.SetStorage(x, val) -} - -func (c *Closure) GetStorage(x *big.Int) *ethutil.Value { - m := c.object.GetStorage(x) - if m == nil { - return ethutil.EmptyValue() + return nil } - return m + return c.Code[x : x+y] } func (c *Closure) Return(ret []byte) []byte { @@ -123,10 +98,6 @@ func (c *Closure) ReturnGas(gas, price *big.Int) { /* * Set / Get */ -func (c *Closure) Caller() ClosureRef { - return c.caller -} - func (c *Closure) Address() []byte { return c.object.Address() } -- cgit v1.2.3 From 29c887ef2c39e91951e1ae14e7c4276334c434a4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 30 Dec 2014 16:16:02 +0100 Subject: Removed incorrect range check for push --- vm/closure.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'vm/closure.go') diff --git a/vm/closure.go b/vm/closure.go index 97b31ada0..df216f2ae 100644 --- a/vm/closure.go +++ b/vm/closure.go @@ -1,8 +1,10 @@ package vm import ( + "math" "math/big" + "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/state" ) @@ -51,19 +53,14 @@ func (c *Closure) GetByte(x uint64) byte { } func (c *Closure) GetBytes(x, y int) []byte { - if x >= len(c.Code) || y >= len(c.Code) { - return nil - } - - return c.Code[x : x+y] + return c.GetRangeValue(uint64(x), uint64(y)) } -func (c *Closure) GetRangeValue(x, y uint64) []byte { - if x >= uint64(len(c.Code)) || y >= uint64(len(c.Code)) { - return nil - } +func (c *Closure) GetRangeValue(x, size uint64) []byte { + x = uint64(math.Min(float64(x), float64(len(c.Code)))) + y := uint64(math.Min(float64(x+size), float64(len(c.Code)))) - return c.Code[x : x+y] + return ethutil.LeftPadBytes(c.Code[x:y], int(size)) } func (c *Closure) Return(ret []byte) []byte { -- cgit v1.2.3 From 4dc7ee90879d7146c9e5004c04992c90ad78f632 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 2 Jan 2015 16:14:12 +0100 Subject: Closure => Context --- vm/closure.go | 104 ---------------------------------------------------------- 1 file changed, 104 deletions(-) delete mode 100644 vm/closure.go (limited to 'vm/closure.go') diff --git a/vm/closure.go b/vm/closure.go deleted file mode 100644 index df216f2ae..000000000 --- a/vm/closure.go +++ /dev/null @@ -1,104 +0,0 @@ -package vm - -import ( - "math" - "math/big" - - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" -) - -type ClosureRef interface { - ReturnGas(*big.Int, *big.Int) - Address() []byte - SetCode([]byte) -} - -type Closure struct { - caller ClosureRef - object ClosureRef - Code []byte - message *state.Message - - Gas, UsedGas, Price *big.Int - - Args []byte -} - -// Create a new closure for the given data items -func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code []byte, gas, price *big.Int) *Closure { - c := &Closure{message: msg, caller: caller, object: object, Code: code, Args: nil} - - // Gas should be a pointer so it can safely be reduced through the run - // This pointer will be off the state transition - c.Gas = gas //new(big.Int).Set(gas) - // In most cases price and value are pointers to transaction objects - // and we don't want the transaction's values to change. - c.Price = new(big.Int).Set(price) - c.UsedGas = new(big.Int) - - return c -} - -func (c *Closure) GetOp(x uint64) OpCode { - return OpCode(c.GetByte(x)) -} - -func (c *Closure) GetByte(x uint64) byte { - if x < uint64(len(c.Code)) { - return c.Code[x] - } - - return 0 -} - -func (c *Closure) GetBytes(x, y int) []byte { - return c.GetRangeValue(uint64(x), uint64(y)) -} - -func (c *Closure) GetRangeValue(x, size uint64) []byte { - x = uint64(math.Min(float64(x), float64(len(c.Code)))) - y := uint64(math.Min(float64(x+size), float64(len(c.Code)))) - - return ethutil.LeftPadBytes(c.Code[x:y], int(size)) -} - -func (c *Closure) Return(ret []byte) []byte { - // Return the remaining gas to the caller - c.caller.ReturnGas(c.Gas, c.Price) - - return ret -} - -/* - * Gas functions - */ -func (c *Closure) UseGas(gas *big.Int) bool { - if c.Gas.Cmp(gas) < 0 { - return false - } - - // Sub the amount of gas from the remaining - c.Gas.Sub(c.Gas, gas) - c.UsedGas.Add(c.UsedGas, gas) - - return true -} - -// Implement the caller interface -func (c *Closure) ReturnGas(gas, price *big.Int) { - // Return the gas to the closure - c.Gas.Add(c.Gas, gas) - c.UsedGas.Sub(c.UsedGas, gas) -} - -/* - * Set / Get - */ -func (c *Closure) Address() []byte { - return c.object.Address() -} - -func (self *Closure) SetCode(code []byte) { - self.Code = code -} -- cgit v1.2.3