From 4dc7ee90879d7146c9e5004c04992c90ad78f632 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 2 Jan 2015 16:14:12 +0100 Subject: Closure => Context --- vm/context.go | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 vm/context.go (limited to 'vm/context.go') diff --git a/vm/context.go b/vm/context.go new file mode 100644 index 000000000..ccbadabda --- /dev/null +++ b/vm/context.go @@ -0,0 +1,104 @@ +package vm + +import ( + "math" + "math/big" + + "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/state" +) + +type ContextRef interface { + ReturnGas(*big.Int, *big.Int) + Address() []byte + SetCode([]byte) +} + +type Context struct { + caller ContextRef + object ContextRef + Code []byte + message *state.Message + + Gas, UsedGas, Price *big.Int + + Args []byte +} + +// Create a new context for the given data items +func NewContext(msg *state.Message, caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context { + c := &Context{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 *Context) GetOp(x uint64) OpCode { + return OpCode(c.GetByte(x)) +} + +func (c *Context) GetByte(x uint64) byte { + if x < uint64(len(c.Code)) { + return c.Code[x] + } + + return 0 +} + +func (c *Context) GetBytes(x, y int) []byte { + return c.GetRangeValue(uint64(x), uint64(y)) +} + +func (c *Context) 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 *Context) Return(ret []byte) []byte { + // Return the remaining gas to the caller + c.caller.ReturnGas(c.Gas, c.Price) + + return ret +} + +/* + * Gas functions + */ +func (c *Context) 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 *Context) ReturnGas(gas, price *big.Int) { + // Return the gas to the context + c.Gas.Add(c.Gas, gas) + c.UsedGas.Sub(c.UsedGas, gas) +} + +/* + * Set / Get + */ +func (c *Context) Address() []byte { + return c.object.Address() +} + +func (self *Context) SetCode(code []byte) { + self.Code = code +} -- cgit v1.2.3 From bd0c267cbe9db805b5a272d29ef8860c62ddafe5 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 3 Jan 2015 17:29:08 +0100 Subject: Cleanup old code --- vm/context.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'vm/context.go') diff --git a/vm/context.go b/vm/context.go index ccbadabda..d995c92c7 100644 --- a/vm/context.go +++ b/vm/context.go @@ -5,7 +5,6 @@ import ( "math/big" "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" ) type ContextRef interface { @@ -15,10 +14,9 @@ type ContextRef interface { } type Context struct { - caller ContextRef - object ContextRef - Code []byte - message *state.Message + caller ContextRef + object ContextRef + Code []byte Gas, UsedGas, Price *big.Int @@ -26,8 +24,8 @@ type Context struct { } // Create a new context for the given data items -func NewContext(msg *state.Message, caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context { - c := &Context{message: msg, caller: caller, object: object, Code: code, Args: nil} +func NewContext(caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context { + c := &Context{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 -- cgit v1.2.3 From 09841b1c9b2553a4572590128580df37c8fa83ad Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 4 Jan 2015 14:20:16 +0100 Subject: Cleaned up some of that util --- vm/context.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'vm/context.go') diff --git a/vm/context.go b/vm/context.go index d995c92c7..d14df1aa7 100644 --- a/vm/context.go +++ b/vm/context.go @@ -38,13 +38,13 @@ func NewContext(caller ContextRef, object ContextRef, code []byte, gas, price *b return c } -func (c *Context) GetOp(x uint64) OpCode { - return OpCode(c.GetByte(x)) +func (c *Context) GetOp(n uint64) OpCode { + return OpCode(c.GetByte(n)) } -func (c *Context) GetByte(x uint64) byte { - if x < uint64(len(c.Code)) { - return c.Code[x] +func (c *Context) GetByte(n uint64) byte { + if n < uint64(len(c.Code)) { + return c.Code[n] } return 0 -- cgit v1.2.3 From 00348756bce00c2d19f16ce8df5eff7a62f5cfc6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 12 Jan 2015 13:49:47 +0100 Subject: updated tests --- vm/context.go | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'vm/context.go') diff --git a/vm/context.go b/vm/context.go index d14df1aa7..b48f1a657 100644 --- a/vm/context.go +++ b/vm/context.go @@ -61,6 +61,13 @@ func (c *Context) GetRangeValue(x, size uint64) []byte { return ethutil.LeftPadBytes(c.Code[x:y], int(size)) } +func (c *Context) GetCode(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.RightPadBytes(c.Code[x:y], int(size)) +} + func (c *Context) Return(ret []byte) []byte { // Return the remaining gas to the caller c.caller.ReturnGas(c.Gas, c.Price) -- cgit v1.2.3