diff options
author | obscuren <geffobscura@gmail.com> | 2014-08-21 21:46:26 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2014-08-21 21:46:26 +0800 |
commit | 0af0f0d890120e007ce42f072e1ee179a62115d3 (patch) | |
tree | 5ae9ecafbb729d1636fadfcfa49fd9100959560c /ethvm/vm.go | |
parent | d761af84c83ae8d9d723e6766abb7950ff59cdf3 (diff) | |
parent | c173e9f4ab463cf3a44d35215bc29d846d6f6b02 (diff) | |
download | dexon-0af0f0d890120e007ce42f072e1ee179a62115d3.tar.gz dexon-0af0f0d890120e007ce42f072e1ee179a62115d3.tar.zst dexon-0af0f0d890120e007ce42f072e1ee179a62115d3.zip |
Merge branch 'release/0.6.3'
Diffstat (limited to 'ethvm/vm.go')
-rw-r--r-- | ethvm/vm.go | 89 |
1 files changed, 70 insertions, 19 deletions
diff --git a/ethvm/vm.go b/ethvm/vm.go index a93b56e60..ddad0d366 100644 --- a/ethvm/vm.go +++ b/ethvm/vm.go @@ -2,11 +2,12 @@ package ethvm import ( "fmt" + "math" + "math/big" + "github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethutil" - "math" - "math/big" ) type Debugger interface { @@ -51,6 +52,7 @@ type Environment interface { Time() int64 Difficulty() *big.Int Value() *big.Int + BlockHash() []byte } type Object interface { @@ -128,14 +130,14 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes()) }) } + */ - b := pc.Bytes() - if len(b) == 0 { - b = []byte{0} - } + 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()) - */ + fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes()) } gas := new(big.Int) @@ -244,6 +246,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { base.Add(y, x) + ensure256(base) + self.Printf(" = %v", base) // Pop result back on the stack stack.Push(base) @@ -254,6 +258,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { base.Sub(y, x) + ensure256(base) + self.Printf(" = %v", base) // Pop result back on the stack stack.Push(base) @@ -264,6 +270,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { base.Mul(y, x) + ensure256(base) + self.Printf(" = %v", base) // Pop result back on the stack stack.Push(base) @@ -276,6 +284,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { base.Div(y, x) } + ensure256(base) + self.Printf(" = %v", base) // Pop result back on the stack stack.Push(base) @@ -288,6 +298,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { base.Div(y, x) } + ensure256(base) + self.Printf(" = %v", base) // Pop result back on the stack stack.Push(base) @@ -299,6 +311,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { base.Mod(y, x) + ensure256(base) + self.Printf(" = %v", base) stack.Push(base) case SMOD: @@ -309,6 +323,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { base.Mod(y, x) + ensure256(base) + self.Printf(" = %v", base) stack.Push(base) @@ -320,6 +336,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { base.Exp(y, x, Pow256) + ensure256(base) + self.Printf(" = %v", base) stack.Push(base) @@ -627,8 +645,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { val, loc := stack.Popn() closure.SetStorage(loc, ethutil.NewValue(val)) - // Add the change to manifest - self.env.State().Manifest().AddStorageChange(closure.Object(), loc.Bytes(), val) + closure.message.AddStorageChange(loc.Bytes()) self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) case JUMP: @@ -679,27 +696,35 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" (*) %x", addr).Endl() + msg := self.env.State().Manifest().AddMessage(ðstate.Message{ + To: addr, From: closure.Address(), + Origin: self.env.Origin(), + Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(), + Value: value, + }) + // Create a new contract contract := self.env.State().NewStateObject(addr) - if contract.Amount.Cmp(value) >= 0 { + if contract.Balance.Cmp(value) >= 0 { closure.object.SubAmount(value) contract.AddAmount(value) // Set the init script initCode := mem.Get(offset.Int64(), size.Int64()) - //fmt.Printf("%x\n", initCode) + msg.Input = initCode + // Transfer all remaining gas to the new // contract so it may run the init script gas := new(big.Int).Set(closure.Gas) closure.UseGas(closure.Gas) // Create the closure - c := NewClosure(closure, contract, initCode, gas, closure.Price) + c := NewClosure(msg, closure, contract, initCode, gas, closure.Price) // Call the closure and set the return value as // main script. contract.Code, _, err = c.Call(self, nil) } else { - err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount) + err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance) } if err != nil { @@ -711,7 +736,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf("CREATE err %v", err) } else { stack.Push(ethutil.BigD(addr)) - self.Printf("CREATE success") + + msg.Output = contract.Code } self.Endl() @@ -735,8 +761,16 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { // Get the arguments from the memory args := mem.Get(inOffset.Int64(), inSize.Int64()) - if closure.object.Amount.Cmp(value) < 0 { - vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount) + msg := self.env.State().Manifest().AddMessage(ðstate.Message{ + To: addr.Bytes(), From: closure.Address(), + Input: args, + Origin: self.env.Origin(), + Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(), + Value: value, + }) + + if closure.object.Balance.Cmp(value) < 0 { + vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance) closure.ReturnGas(gas, nil) @@ -750,7 +784,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { stateObject.AddAmount(value) // Create a new callable closure - c := NewClosure(closure, stateObject, stateObject.Code, gas, closure.Price) + c := NewClosure(msg, closure, stateObject, stateObject.Code, gas, closure.Price) // Executer the closure and get the return value (if any) ret, _, err := c.Call(self, args) if err != nil { @@ -765,6 +799,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { mem.Set(retOffset.Int64(), retSize.Int64(), ret) } + msg.Output = ret + // Debug hook if self.Dbg != nil { self.Dbg.SetCode(closure.Code) @@ -783,7 +819,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { receiver := self.env.State().GetOrNewStateObject(stack.Pop().Bytes()) - receiver.AddAmount(closure.object.Amount) + receiver.AddAmount(closure.object.Balance) closure.object.MarkForDeletion() @@ -837,3 +873,18 @@ func (self *Vm) Endl() *Vm { return self } + +func ensure256(x *big.Int) { + //max, _ := big.NewInt(0).SetString("115792089237316195423570985008687907853269984665640564039457584007913129639936", 0) + //if x.Cmp(max) >= 0 { + d := big.NewInt(1) + d.Lsh(d, 256).Sub(d, big.NewInt(1)) + x.And(x, d) + //} + + // Could have done this with an OR, but big ints are costly. + + if x.Cmp(new(big.Int)) < 0 { + x.SetInt64(0) + } +} |