From cebf4e3697dcd20e290ff56ad6e5dfca2059c063 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 13 Jun 2014 12:58:01 +0200 Subject: Refactored state transitioning to its own model --- ethchain/state_transition.go | 206 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 ethchain/state_transition.go (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go new file mode 100644 index 000000000..6ec9205e9 --- /dev/null +++ b/ethchain/state_transition.go @@ -0,0 +1,206 @@ +package ethchain + +import ( + "fmt" + "github.com/ethereum/eth-go/ethutil" + "math/big" +) + +type StateTransition struct { + coinbase []byte + tx *Transaction + gas *big.Int + state *State + block *Block + + cb, rec, sen *StateObject +} + +func NewStateTransition(coinbase []byte, tx *Transaction, state *State, block *Block) *StateTransition { + return &StateTransition{coinbase, tx, new(big.Int), state, block, nil, nil, nil} +} + +func (self *StateTransition) Coinbase() *StateObject { + if self.cb != nil { + return self.cb + } + + self.cb = self.state.GetAccount(self.coinbase) + return self.cb +} +func (self *StateTransition) Sender() *StateObject { + if self.sen != nil { + return self.sen + } + + self.sen = self.state.GetAccount(self.tx.Sender()) + return self.sen +} +func (self *StateTransition) Receiver() *StateObject { + if self.tx.CreatesContract() { + return nil + } + + if self.rec != nil { + return self.rec + } + + self.rec = self.state.GetAccount(self.tx.Recipient) + return self.rec +} + +func (self *StateTransition) MakeStateObject(state *State, tx *Transaction) *StateObject { + contract := MakeContract(tx, state) + if contract != nil { + state.states[string(tx.CreationAddress())] = contract.state + + return contract + } + + return nil +} + +func (self *StateTransition) UseGas(amount *big.Int) error { + if self.gas.Cmp(amount) < 0 { + return OutOfGasError() + } + self.gas.Sub(self.gas, amount) + + return nil +} + +func (self *StateTransition) AddGas(amount *big.Int) { + self.gas.Add(self.gas, amount) +} + +func (self *StateTransition) BuyGas() error { + var err error + + sender := self.Sender() + if sender.Amount.Cmp(self.tx.GasValue()) < 0 { + return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), self.tx.Value) + } + + coinbase := self.Coinbase() + err = coinbase.BuyGas(self.tx.Gas, self.tx.GasPrice) + if err != nil { + return err + } + self.state.UpdateStateObject(coinbase) + + self.AddGas(self.tx.Gas) + sender.SubAmount(self.tx.GasValue()) + + return nil +} + +func (self *StateTransition) TransitionState() (err error) { + //snapshot := st.state.Snapshot() + + defer func() { + if r := recover(); r != nil { + ethutil.Config.Log.Infoln(r) + err = fmt.Errorf("%v", r) + } + }() + + var ( + tx = self.tx + sender = self.Sender() + receiver *StateObject + ) + + if sender.Nonce != tx.Nonce { + return NonceError(tx.Nonce, sender.Nonce) + } + + sender.Nonce += 1 + defer func() { + // Notify all subscribers + //self.Ethereum.Reactor().Post("newTx:post", tx) + }() + + if err = self.BuyGas(); err != nil { + return err + } + + receiver = self.Receiver() + + if err = self.UseGas(GasTx); err != nil { + return err + } + + dataPrice := big.NewInt(int64(len(tx.Data))) + dataPrice.Mul(dataPrice, GasData) + if err = self.UseGas(dataPrice); err != nil { + return err + } + + if receiver == nil { // Contract + receiver = self.MakeStateObject(self.state, tx) + if receiver == nil { + return fmt.Errorf("ERR. Unable to create contract with transaction %v", tx) + } + } + + if err = self.transferValue(sender, receiver); err != nil { + return err + } + + if tx.CreatesContract() { + fmt.Println(Disassemble(receiver.Init())) + // Evaluate the initialization script + // and use the return value as the + // script section for the state object. + //script, gas, err = sm.Eval(state, contract.Init(), contract, tx, block) + code, err := self.Eval(receiver.Init(), receiver) + if err != nil { + return fmt.Errorf("Error during init script run %v", err) + } + + receiver.script = code + } + + self.state.UpdateStateObject(sender) + self.state.UpdateStateObject(receiver) + + return nil +} + +func (self *StateTransition) transferValue(sender, receiver *StateObject) error { + if sender.Amount.Cmp(self.tx.Value) < 0 { + return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.tx.Value, sender.Amount) + } + + // Subtract the amount from the senders account + sender.SubAmount(self.tx.Value) + // Add the amount to receivers account which should conclude this transaction + receiver.AddAmount(self.tx.Value) + + ethutil.Config.Log.Debugf("%x => %x (%v) %x\n", sender.Address()[:4], receiver.Address()[:4], self.tx.Value, self.tx.Hash()) + + return nil +} + +func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []byte, err error) { + var ( + tx = self.tx + block = self.block + initiator = self.Sender() + state = self.state + ) + + closure := NewClosure(initiator, context, script, state, self.gas, tx.GasPrice) + vm := NewVm(state, nil, RuntimeVars{ + Origin: initiator.Address(), + BlockNumber: block.BlockInfo().Number, + PrevHash: block.PrevHash, + Coinbase: block.Coinbase, + Time: block.Time, + Diff: block.Difficulty, + Value: tx.Value, + }) + ret, _, err = closure.Call(vm, tx.Data, nil) + + return +} -- cgit v1.2.3 From c734dde982c4ce778afa074e94efb09e552dbd84 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 13 Jun 2014 13:06:27 +0200 Subject: comments & refactor --- ethchain/state_transition.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 6ec9205e9..1256d019c 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -6,6 +6,22 @@ import ( "math/big" ) +/* + * The State transitioning model + * + * A state transition is a change made when a transaction is applied to the current world state + * The state transitioning model does all all the necessary work to work out a valid new state root. + * 1) Nonce handling + * 2) Pre pay / buy gas of the coinbase (miner) + * 3) Create a new state object if the recipient is \0*32 + * 4) Value transfer + * == If contract creation == + * 4a) Attempt to run transaction data + * 4b) If valid, use result as code for the new state object + * == end == + * 5) Run Script section + * 6) Derive new state root + */ type StateTransition struct { coinbase []byte tx *Transaction @@ -115,10 +131,6 @@ func (self *StateTransition) TransitionState() (err error) { } sender.Nonce += 1 - defer func() { - // Notify all subscribers - //self.Ethereum.Reactor().Post("newTx:post", tx) - }() if err = self.BuyGas(); err != nil { return err -- cgit v1.2.3 From 81245473486dd680b7121d4b227ca8a57d07b4b1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 13 Jun 2014 16:06:27 +0200 Subject: Moving a head closer to interop --- ethchain/state_transition.go | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 1256d019c..a080c5602 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -116,7 +116,7 @@ func (self *StateTransition) TransitionState() (err error) { defer func() { if r := recover(); r != nil { ethutil.Config.Log.Infoln(r) - err = fmt.Errorf("%v", r) + err = fmt.Errorf("state transition err %v", r) } }() @@ -126,41 +126,51 @@ func (self *StateTransition) TransitionState() (err error) { receiver *StateObject ) + // Make sure this transaction's nonce is correct if sender.Nonce != tx.Nonce { return NonceError(tx.Nonce, sender.Nonce) } + // Increment the nonce for the next transaction sender.Nonce += 1 + // Pre-pay gas / Buy gas of the coinbase account if err = self.BuyGas(); err != nil { return err } + // Get the receiver (TODO fix this, if coinbase is the receiver we need to save/retrieve) receiver = self.Receiver() + // Transaction gas if err = self.UseGas(GasTx); err != nil { return err } + // Pay data gas dataPrice := big.NewInt(int64(len(tx.Data))) dataPrice.Mul(dataPrice, GasData) if err = self.UseGas(dataPrice); err != nil { return err } - if receiver == nil { // Contract + // If the receiver is nil it's a contract (\0*32). + if receiver == nil { + // Create a new state object for the contract receiver = self.MakeStateObject(self.state, tx) if receiver == nil { return fmt.Errorf("ERR. Unable to create contract with transaction %v", tx) } } + // Transfer value from sender to receiver if err = self.transferValue(sender, receiver); err != nil { return err } + // Process the init code and create 'valid' contract if tx.CreatesContract() { - fmt.Println(Disassemble(receiver.Init())) + //fmt.Println(Disassemble(receiver.Init())) // Evaluate the initialization script // and use the return value as the // script section for the state object. @@ -173,6 +183,10 @@ func (self *StateTransition) TransitionState() (err error) { receiver.script = code } + // Return remaining gas + remaining := new(big.Int).Mul(self.gas, tx.GasPrice) + sender.AddAmount(remaining) + self.state.UpdateStateObject(sender) self.state.UpdateStateObject(receiver) @@ -184,12 +198,14 @@ func (self *StateTransition) transferValue(sender, receiver *StateObject) error return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.tx.Value, sender.Amount) } - // Subtract the amount from the senders account - sender.SubAmount(self.tx.Value) - // Add the amount to receivers account which should conclude this transaction - receiver.AddAmount(self.tx.Value) + if self.tx.Value.Cmp(ethutil.Big0) > 0 { + // Subtract the amount from the senders account + sender.SubAmount(self.tx.Value) + // Add the amount to receivers account which should conclude this transaction + receiver.AddAmount(self.tx.Value) - ethutil.Config.Log.Debugf("%x => %x (%v) %x\n", sender.Address()[:4], receiver.Address()[:4], self.tx.Value, self.tx.Hash()) + ethutil.Config.Log.Debugf("%x => %x (%v) %x\n", sender.Address()[:4], receiver.Address()[:4], self.tx.Value, self.tx.Hash()) + } return nil } -- cgit v1.2.3 From 63883bf27d8b87f601e1603e9024a279b91bffb7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 14 Jun 2014 11:46:09 +0200 Subject: Moving closer to interop --- ethchain/state_transition.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index a080c5602..5ded0cddd 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -131,14 +131,21 @@ func (self *StateTransition) TransitionState() (err error) { return NonceError(tx.Nonce, sender.Nonce) } - // Increment the nonce for the next transaction - sender.Nonce += 1 - // Pre-pay gas / Buy gas of the coinbase account if err = self.BuyGas(); err != nil { return err } + // XXX Transactions after this point are considered valid. + + defer func() { + self.state.UpdateStateObject(sender) + self.state.UpdateStateObject(receiver) + }() + + // Increment the nonce for the next transaction + sender.Nonce += 1 + // Get the receiver (TODO fix this, if coinbase is the receiver we need to save/retrieve) receiver = self.Receiver() @@ -187,9 +194,6 @@ func (self *StateTransition) TransitionState() (err error) { remaining := new(big.Int).Mul(self.gas, tx.GasPrice) sender.AddAmount(remaining) - self.state.UpdateStateObject(sender) - self.state.UpdateStateObject(receiver) - return nil } -- cgit v1.2.3 From d80f999a215b74e23d21f3548486f996c3eb028d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 15 Jun 2014 00:11:06 +0200 Subject: Run contracts --- ethchain/state_transition.go | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 5ded0cddd..2e2a51f72 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -188,6 +188,13 @@ func (self *StateTransition) TransitionState() (err error) { } receiver.script = code + } else { + if len(receiver.Script()) > 0 { + _, err := self.Eval(receiver.Script(), receiver) + if err != nil { + return fmt.Errorf("Error during code execution %v", err) + } + } } // Return remaining gas -- cgit v1.2.3 From 1d76e433f7866763674e4ef06a4a4d9463276490 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 16 Jun 2014 10:40:21 +0200 Subject: Removed some comments --- ethchain/state_transition.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 2e2a51f72..94546e556 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -102,7 +102,7 @@ func (self *StateTransition) BuyGas() error { if err != nil { return err } - self.state.UpdateStateObject(coinbase) + //self.state.UpdateStateObject(coinbase) self.AddGas(self.tx.Gas) sender.SubAmount(self.tx.GasValue()) @@ -177,7 +177,6 @@ func (self *StateTransition) TransitionState() (err error) { // Process the init code and create 'valid' contract if tx.CreatesContract() { - //fmt.Println(Disassemble(receiver.Init())) // Evaluate the initialization script // and use the return value as the // script section for the state object. -- cgit v1.2.3 From 9f62d441a7c785b88f89d52643a9deaa822af15e Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 16 Jun 2014 11:14:01 +0200 Subject: Moved gas limit err check to buy gas --- ethchain/state_transition.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 94546e556..76936aa7c 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -32,8 +32,8 @@ type StateTransition struct { cb, rec, sen *StateObject } -func NewStateTransition(coinbase []byte, tx *Transaction, state *State, block *Block) *StateTransition { - return &StateTransition{coinbase, tx, new(big.Int), state, block, nil, nil, nil} +func NewStateTransition(coinbase *StateObject, tx *Transaction, state *State, block *Block) *StateTransition { + return &StateTransition{coinbase.Address(), tx, new(big.Int), state, block, coinbase, nil, nil} } func (self *StateTransition) Coinbase() *StateObject { -- cgit v1.2.3 From 48bca30e61f869a00111abe5d818ac7379854616 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 16 Jun 2014 11:51:16 +0200 Subject: Fixed minor issue with the gas pool --- ethchain/state_transition.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 76936aa7c..5beef61b4 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -113,12 +113,14 @@ func (self *StateTransition) BuyGas() error { func (self *StateTransition) TransitionState() (err error) { //snapshot := st.state.Snapshot() - defer func() { - if r := recover(); r != nil { - ethutil.Config.Log.Infoln(r) - err = fmt.Errorf("state transition err %v", r) - } - }() + /* + defer func() { + if r := recover(); r != nil { + ethutil.Config.Log.Infoln(r) + err = fmt.Errorf("state transition err %v", r) + } + }() + */ var ( tx = self.tx -- cgit v1.2.3 From 8b15732c1e8a1a666ae7469bc43d989918ce754a Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 16 Jun 2014 12:04:56 +0200 Subject: Check for nil receiver --- ethchain/state_transition.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 5beef61b4..c88f4727f 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -141,8 +141,13 @@ func (self *StateTransition) TransitionState() (err error) { // XXX Transactions after this point are considered valid. defer func() { - self.state.UpdateStateObject(sender) - self.state.UpdateStateObject(receiver) + if sender != nil { + self.state.UpdateStateObject(sender) + } + + if receiver != nil { + self.state.UpdateStateObject(receiver) + } }() // Increment the nonce for the next transaction -- cgit v1.2.3 From 0d7763283952a57e5421565cdda19ecabe3222f7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 16 Jun 2014 12:25:18 +0200 Subject: Refund gas --- ethchain/state_transition.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index c88f4727f..25efd64cc 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -110,6 +110,15 @@ func (self *StateTransition) BuyGas() error { return nil } +func (self *StateTransition) RefundGas() { + coinbase, sender := self.Coinbase(), self.Sender() + coinbase.RefundGas(self.gas, self.tx.GasPrice) + + // Return remaining gas + remaining := new(big.Int).Mul(self.gas, self.tx.GasPrice) + sender.AddAmount(remaining) +} + func (self *StateTransition) TransitionState() (err error) { //snapshot := st.state.Snapshot() @@ -141,6 +150,8 @@ func (self *StateTransition) TransitionState() (err error) { // XXX Transactions after this point are considered valid. defer func() { + self.RefundGas() + if sender != nil { self.state.UpdateStateObject(sender) } @@ -148,6 +159,8 @@ func (self *StateTransition) TransitionState() (err error) { if receiver != nil { self.state.UpdateStateObject(receiver) } + + self.state.UpdateStateObject(self.Coinbase()) }() // Increment the nonce for the next transaction @@ -203,10 +216,6 @@ func (self *StateTransition) TransitionState() (err error) { } } - // Return remaining gas - remaining := new(big.Int).Mul(self.gas, tx.GasPrice) - sender.AddAmount(remaining) - return nil } -- cgit v1.2.3 From 53e30f750dd0c91279bfebe01bb12fd170cb74ff Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Jun 2014 11:06:06 +0200 Subject: Removal of manual updating of state objects * You'll only ever need to update the state by calling Update. Update will take care of the updating of it's child state objects. --- ethchain/state_transition.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 25efd64cc..23175b0f3 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -67,13 +67,8 @@ func (self *StateTransition) Receiver() *StateObject { func (self *StateTransition) MakeStateObject(state *State, tx *Transaction) *StateObject { contract := MakeContract(tx, state) - if contract != nil { - state.states[string(tx.CreationAddress())] = contract.state - return contract - } - - return nil + return contract } func (self *StateTransition) UseGas(amount *big.Int) error { @@ -137,6 +132,8 @@ func (self *StateTransition) TransitionState() (err error) { receiver *StateObject ) + ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(~) %x\n", tx.Hash()) + // Make sure this transaction's nonce is correct if sender.Nonce != tx.Nonce { return NonceError(tx.Nonce, sender.Nonce) @@ -152,15 +149,17 @@ func (self *StateTransition) TransitionState() (err error) { defer func() { self.RefundGas() - if sender != nil { - self.state.UpdateStateObject(sender) - } + /* + if sender != nil { + self.state.UpdateStateObject(sender) + } - if receiver != nil { - self.state.UpdateStateObject(receiver) - } + if receiver != nil { + self.state.UpdateStateObject(receiver) + } - self.state.UpdateStateObject(self.Coinbase()) + self.state.UpdateStateObject(self.Coinbase()) + */ }() // Increment the nonce for the next transaction @@ -209,6 +208,7 @@ func (self *StateTransition) TransitionState() (err error) { receiver.script = code } else { if len(receiver.Script()) > 0 { + fmt.Println(receiver.Script()) _, err := self.Eval(receiver.Script(), receiver) if err != nil { return fmt.Errorf("Error during code execution %v", err) -- cgit v1.2.3 From 34c8045d5be6488e9800c24e1e696e1b912f344c Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Jun 2014 18:05:46 +0200 Subject: Fixed issue where JUMPI would do an equally check with 1 instead of GT --- ethchain/state_transition.go | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 23175b0f3..dc465bbbd 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -97,7 +97,6 @@ func (self *StateTransition) BuyGas() error { if err != nil { return err } - //self.state.UpdateStateObject(coinbase) self.AddGas(self.tx.Gas) sender.SubAmount(self.tx.GasValue()) @@ -115,7 +114,7 @@ func (self *StateTransition) RefundGas() { } func (self *StateTransition) TransitionState() (err error) { - //snapshot := st.state.Snapshot() + ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(~) %x\n", self.tx.Hash()) /* defer func() { @@ -132,8 +131,6 @@ func (self *StateTransition) TransitionState() (err error) { receiver *StateObject ) - ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(~) %x\n", tx.Hash()) - // Make sure this transaction's nonce is correct if sender.Nonce != tx.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. - defer func() { - self.RefundGas() - - /* - if sender != nil { - self.state.UpdateStateObject(sender) - } - - if receiver != nil { - self.state.UpdateStateObject(receiver) - } - - self.state.UpdateStateObject(self.Coinbase()) - */ - }() + defer self.RefundGas() // Increment the nonce for the next transaction sender.Nonce += 1 - // Get the receiver (TODO fix this, if coinbase is the receiver we need to save/retrieve) receiver = self.Receiver() // Transaction gas -- cgit v1.2.3 From ca79360fd7621a96382c0304e74e0d1f39b739fc Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Jun 2014 18:49:26 +0200 Subject: Verbose logging for VM --- ethchain/state_transition.go | 1 + 1 file changed, 1 insertion(+) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index dc465bbbd..c70dc54b4 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -236,6 +236,7 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by Diff: block.Difficulty, Value: tx.Value, }) + vm.Verbose = true ret, _, err = closure.Call(vm, tx.Data, nil) return -- cgit v1.2.3 From f911087eab6b31fcdbc22a9a74c0be410e8f0177 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Jun 2014 13:48:42 +0200 Subject: Logging --- ethchain/state_transition.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index c70dc54b4..8a6565e56 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -89,7 +89,7 @@ func (self *StateTransition) BuyGas() error { sender := self.Sender() if sender.Amount.Cmp(self.tx.GasValue()) < 0 { - return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), self.tx.Value) + return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Amount) } coinbase := self.Coinbase() @@ -181,7 +181,8 @@ func (self *StateTransition) TransitionState() (err error) { // Evaluate the initialization script // and use the return value as the // script section for the state object. - //script, gas, err = sm.Eval(state, contract.Init(), contract, tx, block) + ethutil.Config.Log.Println(ethutil.LogLevelSystem, receiver.Init()) + code, err := self.Eval(receiver.Init(), receiver) if err != nil { return fmt.Errorf("Error during init script run %v", err) @@ -190,7 +191,8 @@ func (self *StateTransition) TransitionState() (err error) { receiver.script = code } else { if len(receiver.Script()) > 0 { - fmt.Println(receiver.Script()) + ethutil.Config.Log.Println(ethutil.LogLevelSystem, receiver.Script()) + _, err := self.Eval(receiver.Script(), receiver) if err != nil { return fmt.Errorf("Error during code execution %v", err) -- cgit v1.2.3 From 731f55a05db44fcd5191bd7af6c99f4a4433e342 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 19 Jun 2014 13:41:17 +0200 Subject: Reset state when a transition fails --- ethchain/state_transition.go | 132 ++++++++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 45 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 8a6565e56..8757246a0 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -23,17 +23,36 @@ import ( * 6) Derive new state root */ type StateTransition struct { - coinbase []byte - tx *Transaction - gas *big.Int - state *State - block *Block + coinbase, receiver []byte + tx *Transaction + gas, gasPrice *big.Int + value *big.Int + data []byte + state *State + block *Block cb, rec, sen *StateObject } +func Transition(coinbase, sender, receiver, data []byte, gas, gasPrice, value *big.Int, state *State, block *Block) (ret []byte, err error) { + stateTransition := &StateTransition{ + coinbase: coinbase, + receiver: receiver, + cb: state.GetOrNewStateObject(coinbase), + rec: state.GetOrNewStateObject(receiver), + sen: state.GetOrNewStateObject(sender), + gas: gas, + gasPrice: gasPrice, + value: value, + state: state, + block: block, + } + + return stateTransition.Transition() +} + func NewStateTransition(coinbase *StateObject, tx *Transaction, state *State, block *Block) *StateTransition { - return &StateTransition{coinbase.Address(), tx, new(big.Int), state, block, coinbase, nil, nil} + return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil} } func (self *StateTransition) Coinbase() *StateObject { @@ -53,7 +72,7 @@ func (self *StateTransition) Sender() *StateObject { return self.sen } func (self *StateTransition) Receiver() *StateObject { - if self.tx.CreatesContract() { + if self.tx != nil && self.tx.CreatesContract() { return nil } @@ -113,6 +132,25 @@ func (self *StateTransition) RefundGas() { sender.AddAmount(remaining) } +func (self *StateTransition) preCheck() (err error) { + var ( + tx = self.tx + sender = self.Sender() + ) + + // Make sure this transaction's nonce is correct + if sender.Nonce != tx.Nonce { + return NonceError(tx.Nonce, sender.Nonce) + } + + // Pre-pay gas / Buy gas of the coinbase account + if err = self.BuyGas(); err != nil { + return err + } + + return nil +} + func (self *StateTransition) TransitionState() (err error) { ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(~) %x\n", self.tx.Hash()) @@ -125,26 +163,25 @@ func (self *StateTransition) TransitionState() (err error) { }() */ + // XXX Transactions after this point are considered valid. + if err = self.preCheck(); err != nil { + return + } + + defer self.RefundGas() + + _, err = self.Transition() + + return +} + +func (self *StateTransition) Transition() (ret []byte, err error) { var ( tx = self.tx sender = self.Sender() receiver *StateObject ) - // Make sure this transaction's nonce is correct - if sender.Nonce != tx.Nonce { - return NonceError(tx.Nonce, sender.Nonce) - } - - // Pre-pay gas / Buy gas of the coinbase account - if err = self.BuyGas(); err != nil { - return err - } - - // XXX Transactions after this point are considered valid. - - defer self.RefundGas() - // Increment the nonce for the next transaction sender.Nonce += 1 @@ -152,14 +189,14 @@ func (self *StateTransition) TransitionState() (err error) { // Transaction gas if err = self.UseGas(GasTx); err != nil { - return err + return } // Pay data gas - dataPrice := big.NewInt(int64(len(tx.Data))) + dataPrice := big.NewInt(int64(len(self.data))) dataPrice.Mul(dataPrice, GasData) if err = self.UseGas(dataPrice); err != nil { - return err + return } // If the receiver is nil it's a contract (\0*32). @@ -167,25 +204,28 @@ func (self *StateTransition) TransitionState() (err error) { // Create a new state object for the contract receiver = self.MakeStateObject(self.state, tx) if receiver == nil { - return fmt.Errorf("ERR. Unable to create contract with transaction %v", tx) + return nil, fmt.Errorf("Unable to create contract") } } // Transfer value from sender to receiver if err = self.transferValue(sender, receiver); err != nil { - return err + return } // Process the init code and create 'valid' contract - if tx.CreatesContract() { + if IsContractAddr(self.receiver) { // Evaluate the initialization script // and use the return value as the // script section for the state object. + self.data = nil ethutil.Config.Log.Println(ethutil.LogLevelSystem, receiver.Init()) code, err := self.Eval(receiver.Init(), receiver) if err != nil { - return fmt.Errorf("Error during init script run %v", err) + self.state.ResetStateObject(receiver) + + return nil, fmt.Errorf("Error during init script run %v", err) } receiver.script = code @@ -193,53 +233,55 @@ func (self *StateTransition) TransitionState() (err error) { if len(receiver.Script()) > 0 { ethutil.Config.Log.Println(ethutil.LogLevelSystem, receiver.Script()) - _, err := self.Eval(receiver.Script(), receiver) + ret, err = self.Eval(receiver.Script(), receiver) if err != nil { - return fmt.Errorf("Error during code execution %v", err) + self.state.ResetStateObject(receiver) + + return nil, fmt.Errorf("Error during code execution %v", err) } } } - return nil + return } func (self *StateTransition) transferValue(sender, receiver *StateObject) error { - if sender.Amount.Cmp(self.tx.Value) < 0 { - return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.tx.Value, sender.Amount) + if sender.Amount.Cmp(self.value) < 0 { + return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount) } - if self.tx.Value.Cmp(ethutil.Big0) > 0 { - // Subtract the amount from the senders account - sender.SubAmount(self.tx.Value) - // Add the amount to receivers account which should conclude this transaction - receiver.AddAmount(self.tx.Value) + //if self.value.Cmp(ethutil.Big0) > 0 { + // Subtract the amount from the senders account + sender.SubAmount(self.value) + // Add the amount to receivers account which should conclude this transaction + receiver.AddAmount(self.value) - ethutil.Config.Log.Debugf("%x => %x (%v) %x\n", sender.Address()[:4], receiver.Address()[:4], self.tx.Value, self.tx.Hash()) - } + //ethutil.Config.Log.Debugf("%x => %x (%v)\n", sender.Address()[:4], receiver.Address()[:4], self.value) + //} return nil } func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []byte, err error) { var ( - tx = self.tx block = self.block initiator = self.Sender() state = self.state ) - closure := NewClosure(initiator, context, script, state, self.gas, tx.GasPrice) + closure := NewClosure(initiator, context, script, state, self.gas, self.gasPrice) vm := NewVm(state, nil, RuntimeVars{ Origin: initiator.Address(), - BlockNumber: block.BlockInfo().Number, + Block: block, + BlockNumber: block.Number, PrevHash: block.PrevHash, Coinbase: block.Coinbase, Time: block.Time, Diff: block.Difficulty, - Value: tx.Value, + Value: self.value, }) vm.Verbose = true - ret, _, err = closure.Call(vm, tx.Data, nil) + ret, _, err = closure.Call(vm, self.data, nil) return } -- cgit v1.2.3 From 8f29f6a4d4e2c62d3eff0dfd84cc8cab59dd28e8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Jun 2014 00:42:26 +0200 Subject: Removed some logging --- ethchain/state_transition.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 8757246a0..5f4588e48 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -219,25 +219,23 @@ func (self *StateTransition) Transition() (ret []byte, err error) { // and use the return value as the // script section for the state object. self.data = nil - ethutil.Config.Log.Println(ethutil.LogLevelSystem, receiver.Init()) - code, err := self.Eval(receiver.Init(), receiver) - if err != nil { + code, err, deepErr := self.Eval(receiver.Init(), receiver) + if err != nil || deepErr { self.state.ResetStateObject(receiver) - return nil, fmt.Errorf("Error during init script run %v", err) + return nil, fmt.Errorf("Error during init script run %v (deepErr = %v)", err, deepErr) } receiver.script = code } else { if len(receiver.Script()) > 0 { - ethutil.Config.Log.Println(ethutil.LogLevelSystem, receiver.Script()) - - ret, err = self.Eval(receiver.Script(), receiver) + var deepErr bool + ret, err, deepErr = self.Eval(receiver.Script(), receiver) if err != nil { self.state.ResetStateObject(receiver) - return nil, fmt.Errorf("Error during code execution %v", err) + return nil, fmt.Errorf("Error during code execution %v (deepErr = %v)", err, deepErr) } } } @@ -262,7 +260,7 @@ func (self *StateTransition) transferValue(sender, receiver *StateObject) error return nil } -func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []byte, err error) { +func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []byte, err error, deepErr bool) { var ( block = self.block initiator = self.Sender() @@ -282,6 +280,7 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by }) vm.Verbose = true ret, _, err = closure.Call(vm, self.data, nil) + deepErr = vm.err != nil return } -- cgit v1.2.3 From 09f37bd0235198145974db6430da0c429d2a0e79 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Jun 2014 00:45:44 +0200 Subject: Returned to single method --- ethchain/state_transition.go | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 5f4588e48..1f5b4f959 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -34,23 +34,6 @@ type StateTransition struct { cb, rec, sen *StateObject } -func Transition(coinbase, sender, receiver, data []byte, gas, gasPrice, value *big.Int, state *State, block *Block) (ret []byte, err error) { - stateTransition := &StateTransition{ - coinbase: coinbase, - receiver: receiver, - cb: state.GetOrNewStateObject(coinbase), - rec: state.GetOrNewStateObject(receiver), - sen: state.GetOrNewStateObject(sender), - gas: gas, - gasPrice: gasPrice, - value: value, - state: state, - block: block, - } - - return stateTransition.Transition() -} - func NewStateTransition(coinbase *StateObject, tx *Transaction, state *State, block *Block) *StateTransition { return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil} } @@ -168,20 +151,14 @@ func (self *StateTransition) TransitionState() (err error) { return } - defer self.RefundGas() - - _, err = self.Transition() - - return -} - -func (self *StateTransition) Transition() (ret []byte, err error) { var ( tx = self.tx sender = self.Sender() receiver *StateObject ) + defer self.RefundGas() + // Increment the nonce for the next transaction sender.Nonce += 1 @@ -204,7 +181,7 @@ func (self *StateTransition) Transition() (ret []byte, err error) { // Create a new state object for the contract receiver = self.MakeStateObject(self.state, tx) if receiver == nil { - return nil, fmt.Errorf("Unable to create contract") + return fmt.Errorf("Unable to create contract") } } @@ -224,18 +201,18 @@ func (self *StateTransition) Transition() (ret []byte, err error) { if err != nil || deepErr { self.state.ResetStateObject(receiver) - return nil, fmt.Errorf("Error during init script run %v (deepErr = %v)", err, deepErr) + return fmt.Errorf("Error during init script run %v (deepErr = %v)", err, deepErr) } receiver.script = code } else { if len(receiver.Script()) > 0 { var deepErr bool - ret, err, deepErr = self.Eval(receiver.Script(), receiver) + _, err, deepErr = self.Eval(receiver.Script(), receiver) if err != nil { self.state.ResetStateObject(receiver) - return nil, fmt.Errorf("Error during code execution %v (deepErr = %v)", err, deepErr) + return fmt.Errorf("Error during code execution %v (deepErr = %v)", err, deepErr) } } } -- cgit v1.2.3 From b9e8a3e02493d5bbf23cfcab259e66f6ae166612 Mon Sep 17 00:00:00 2001 From: zelig Date: Mon, 23 Jun 2014 12:54:10 +0100 Subject: modified logging API - package vars for tagged loggers - weed out spurious fmt.PrintX and log.PrintX logging - tried to second guess loglevel for some :) --- ethchain/state_transition.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 1f5b4f959..f84c3486b 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -2,7 +2,6 @@ package ethchain import ( "fmt" - "github.com/ethereum/eth-go/ethutil" "math/big" ) @@ -135,12 +134,12 @@ func (self *StateTransition) preCheck() (err error) { } func (self *StateTransition) TransitionState() (err error) { - ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(~) %x\n", self.tx.Hash()) + statelogger.Infof("(~) %x\n", self.tx.Hash()) /* defer func() { if r := recover(); r != nil { - ethutil.Config.Log.Infoln(r) + logger.Infoln(r) err = fmt.Errorf("state transition err %v", r) } }() @@ -231,7 +230,7 @@ func (self *StateTransition) transferValue(sender, receiver *StateObject) error // Add the amount to receivers account which should conclude this transaction receiver.AddAmount(self.value) - //ethutil.Config.Log.Debugf("%x => %x (%v)\n", sender.Address()[:4], receiver.Address()[:4], self.value) + //statelogger.Debugf("%x => %x (%v)\n", sender.Address()[:4], receiver.Address()[:4], self.value) //} return nil -- cgit v1.2.3 From 8ddd4c4c52eef9f382a321fa880adba4a1e35ee2 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 30 Jun 2014 13:09:04 +0200 Subject: wip --- ethchain/state_transition.go | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index f84c3486b..4b4cbeb51 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -1,7 +1,9 @@ package ethchain import ( + "bytes" "fmt" + "github.com/ethereum/eth-go/ethutil" "math/big" ) @@ -236,6 +238,8 @@ func (self *StateTransition) transferValue(sender, receiver *StateObject) error return nil } +var testAddr = ethutil.FromHex("ec4f34c97e43fbb2816cfd95e388353c7181dab1") + func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []byte, err error, deepErr bool) { var ( block = self.block @@ -258,5 +262,46 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by ret, _, err = closure.Call(vm, self.data, nil) deepErr = vm.err != nil + /* + if bytes.Compare(testAddr, context.Address()) == 0 { + trie := context.state.trie + trie.NewIterator().Each(func(key string, v *ethutil.Value) { + v.Decode() + fmt.Printf("%x : %x\n", key, v.Str()) + }) + fmt.Println("\n\n") + } + */ + + Paranoia := true + if Paranoia { + var ( + trie = context.state.trie + trie2 = ethutil.NewTrie(ethutil.Config.Db, "") + ) + + trie.NewIterator().Each(func(key string, v *ethutil.Value) { + trie2.Update(key, v.Str()) + }) + + a := ethutil.NewValue(trie2.Root).Bytes() + b := ethutil.NewValue(context.state.trie.Root).Bytes() + if bytes.Compare(a, b) != 0 { + fmt.Printf("original: %x\n", trie.Root) + trie.NewIterator().Each(func(key string, v *ethutil.Value) { + v.Decode() + fmt.Printf("%x : %x\n", key, v.Str()) + }) + + fmt.Printf("new: %x\n", trie2.Root) + trie2.NewIterator().Each(func(key string, v *ethutil.Value) { + v.Decode() + fmt.Printf("%x : %x\n", key, v.Str()) + }) + + return nil, fmt.Errorf("PARANOIA: Different state object roots during copy"), false + } + } + return } -- cgit v1.2.3 From ed276cd7c241749a9cf8add4e2fae3d3608a7ea4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 30 Jun 2014 20:03:31 +0200 Subject: Added Paranoia check for VM execution --- ethchain/state_transition.go | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 4b4cbeb51..b18091691 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -226,20 +226,14 @@ func (self *StateTransition) transferValue(sender, receiver *StateObject) error return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount) } - //if self.value.Cmp(ethutil.Big0) > 0 { // Subtract the amount from the senders account sender.SubAmount(self.value) // Add the amount to receivers account which should conclude this transaction receiver.AddAmount(self.value) - //statelogger.Debugf("%x => %x (%v)\n", sender.Address()[:4], receiver.Address()[:4], self.value) - //} - return nil } -var testAddr = ethutil.FromHex("ec4f34c97e43fbb2816cfd95e388353c7181dab1") - func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []byte, err error, deepErr bool) { var ( block = self.block @@ -263,6 +257,7 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by deepErr = vm.err != nil /* + var testAddr = ethutil.FromHex("ec4f34c97e43fbb2816cfd95e388353c7181dab1") if bytes.Compare(testAddr, context.Address()) == 0 { trie := context.state.trie trie.NewIterator().Each(func(key string, v *ethutil.Value) { @@ -273,7 +268,7 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by } */ - Paranoia := true + Paranoia := true // TODO Create a flag for this if Paranoia { var ( trie = context.state.trie @@ -287,17 +282,19 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by a := ethutil.NewValue(trie2.Root).Bytes() b := ethutil.NewValue(context.state.trie.Root).Bytes() if bytes.Compare(a, b) != 0 { - fmt.Printf("original: %x\n", trie.Root) - trie.NewIterator().Each(func(key string, v *ethutil.Value) { - v.Decode() - fmt.Printf("%x : %x\n", key, v.Str()) - }) - - fmt.Printf("new: %x\n", trie2.Root) - trie2.NewIterator().Each(func(key string, v *ethutil.Value) { - v.Decode() - fmt.Printf("%x : %x\n", key, v.Str()) - }) + /* + statelogger.Debugf("(o): %x\n", trie.Root) + trie.NewIterator().Each(func(key string, v *ethutil.Value) { + v.Decode() + statelogger.Debugf("%x : %x\n", key, v.Str()) + }) + + statelogger.Debugf("(c): %x\n", trie2.Root) + trie2.NewIterator().Each(func(key string, v *ethutil.Value) { + v.Decode() + statelogger.Debugf("%x : %x\n", key, v.Str()) + }) + */ return nil, fmt.Errorf("PARANOIA: Different state object roots during copy"), false } -- cgit v1.2.3 From 39263b674c1a8a13a1c29349a48b3cdc4c5948db Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 1 Jul 2014 09:56:10 +0200 Subject: Paranoia --- ethchain/state_transition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index b18091691..6837f92f7 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -268,7 +268,7 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by } */ - Paranoia := true // TODO Create a flag for this + Paranoia := ethutil.Config.Paranoia if Paranoia { var ( trie = context.state.trie -- cgit v1.2.3 From 92693e44599c44e606813d2c3259cc9f6f81a644 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 1 Jul 2014 11:26:45 +0200 Subject: The dragon has been slain. Consensus reached! --- ethchain/state_transition.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 6837f92f7..94c3de3d9 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -253,26 +253,22 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by Value: self.value, }) vm.Verbose = true - ret, _, err = closure.Call(vm, self.data, nil) - deepErr = vm.err != nil - /* - var testAddr = ethutil.FromHex("ec4f34c97e43fbb2816cfd95e388353c7181dab1") - if bytes.Compare(testAddr, context.Address()) == 0 { - trie := context.state.trie - trie.NewIterator().Each(func(key string, v *ethutil.Value) { - v.Decode() - fmt.Printf("%x : %x\n", key, v.Str()) - }) - fmt.Println("\n\n") - } - */ + ret, err, deepErr = Call(vm, closure, self.data) + + return +} + +func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error, deepErr bool) { + ret, _, err = closure.Call(vm, data, nil) + deepErr = vm.err != nil Paranoia := ethutil.Config.Paranoia if Paranoia { var ( - trie = context.state.trie - trie2 = ethutil.NewTrie(ethutil.Config.Db, "") + context = closure.object + trie = context.state.trie + trie2 = ethutil.NewTrie(ethutil.Config.Db, "") ) trie.NewIterator().Each(func(key string, v *ethutil.Value) { @@ -282,6 +278,8 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by a := ethutil.NewValue(trie2.Root).Bytes() b := ethutil.NewValue(context.state.trie.Root).Bytes() if bytes.Compare(a, b) != 0 { + // TODO FIXME ASAP + context.state.trie = trie2 /* statelogger.Debugf("(o): %x\n", trie.Root) trie.NewIterator().Each(func(key string, v *ethutil.Value) { @@ -296,7 +294,7 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by }) */ - return nil, fmt.Errorf("PARANOIA: Different state object roots during copy"), false + //return nil, fmt.Errorf("PARANOIA: Different state object roots during copy"), false } } -- cgit v1.2.3 From ff5703fd9b089de67811af61de05637c62dc7a2c Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 1 Jul 2014 15:09:43 +0100 Subject: ethutil -> ethtrie.NewTrie --- ethchain/state_transition.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 94c3de3d9..c382bcd60 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -3,6 +3,7 @@ package ethchain import ( "bytes" "fmt" + "github.com/ethereum/eth-go/ethtrie" "github.com/ethereum/eth-go/ethutil" "math/big" ) @@ -268,7 +269,7 @@ func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error, deepErr var ( context = closure.object trie = context.state.trie - trie2 = ethutil.NewTrie(ethutil.Config.Db, "") + trie2 = ethtrie.NewTrie(ethutil.Config.Db, "") ) trie.NewIterator().Each(func(key string, v *ethutil.Value) { -- cgit v1.2.3 From d15952c867f5c31fa68600754bd17c76a992a70e Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 2 Jul 2014 01:04:21 +0200 Subject: Moved debug hook to Vm directly --- ethchain/state_transition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index c382bcd60..9e7ef3efd 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -261,7 +261,7 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by } func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error, deepErr bool) { - ret, _, err = closure.Call(vm, data, nil) + ret, _, err = closure.Call(vm, data) deepErr = vm.err != nil Paranoia := ethutil.Config.Paranoia -- cgit v1.2.3 From 35ae9e3aa89dc0e3be1cabed313996a7d49f6628 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 2 Jul 2014 17:48:10 +0200 Subject: Paranoia check --- ethchain/state_transition.go | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 9e7ef3efd..898344c2e 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -1,7 +1,6 @@ package ethchain import ( - "bytes" "fmt" "github.com/ethereum/eth-go/ethtrie" "github.com/ethereum/eth-go/ethutil" @@ -264,23 +263,16 @@ func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error, deepErr ret, _, err = closure.Call(vm, data) deepErr = vm.err != nil - Paranoia := ethutil.Config.Paranoia - if Paranoia { + if ethutil.Config.Paranoia { var ( context = closure.object trie = context.state.trie - trie2 = ethtrie.NewTrie(ethutil.Config.Db, "") ) - trie.NewIterator().Each(func(key string, v *ethutil.Value) { - trie2.Update(key, v.Str()) - }) - - a := ethutil.NewValue(trie2.Root).Bytes() - b := ethutil.NewValue(context.state.trie.Root).Bytes() - if bytes.Compare(a, b) != 0 { + valid, t2 := ethtrie.ParanoiaCheck(trie) + if !valid { // TODO FIXME ASAP - context.state.trie = trie2 + context.state.trie = t2 /* statelogger.Debugf("(o): %x\n", trie.Root) trie.NewIterator().Each(func(key string, v *ethutil.Value) { -- cgit v1.2.3 From 5d6713920625b82df2b55728b2cbb9f7f3df2025 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 3 Jul 2014 10:05:02 +0200 Subject: Fix --- ethchain/state_transition.go | 1 + 1 file changed, 1 insertion(+) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 898344c2e..31196d2d7 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -53,6 +53,7 @@ func (self *StateTransition) Sender() *StateObject { } self.sen = self.state.GetAccount(self.tx.Sender()) + return self.sen } func (self *StateTransition) Receiver() *StateObject { -- cgit v1.2.3 From 8baa0f84e70aafa3882ec477d3b3d401d462958b Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 3 Jul 2014 16:07:21 +0200 Subject: Fixed reverting error --- ethchain/state_transition.go | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 31196d2d7..16e1f124b 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -192,6 +192,8 @@ func (self *StateTransition) TransitionState() (err error) { return } + //snapshot := self.state.Copy() + // Process the init code and create 'valid' contract if IsContractAddr(self.receiver) { // Evaluate the initialization script @@ -199,22 +201,25 @@ func (self *StateTransition) TransitionState() (err error) { // script section for the state object. self.data = nil - code, err, deepErr := self.Eval(receiver.Init(), receiver) - if err != nil || deepErr { + statelogger.Debugln("~> init") + code, err := self.Eval(receiver.Init(), receiver) + if err != nil { + //self.state.Set(snapshot) self.state.ResetStateObject(receiver) - return fmt.Errorf("Error during init script run %v (deepErr = %v)", err, deepErr) + return fmt.Errorf("Error during init execution %v", err) } receiver.script = code } else { if len(receiver.Script()) > 0 { - var deepErr bool - _, err, deepErr = self.Eval(receiver.Script(), receiver) + statelogger.Debugln("~> code") + _, err = self.Eval(receiver.Script(), receiver) if err != nil { + //self.state.Set(snapshot) self.state.ResetStateObject(receiver) - return fmt.Errorf("Error during code execution %v (deepErr = %v)", err, deepErr) + return fmt.Errorf("Error during code execution %v", err) } } } @@ -235,7 +240,7 @@ func (self *StateTransition) transferValue(sender, receiver *StateObject) error return nil } -func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []byte, err error, deepErr bool) { +func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []byte, err error) { var ( block = self.block initiator = self.Sender() @@ -255,14 +260,13 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by }) vm.Verbose = true - ret, err, deepErr = Call(vm, closure, self.data) + ret, err = Call(vm, closure, self.data) return } -func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error, deepErr bool) { +func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error) { ret, _, err = closure.Call(vm, data) - deepErr = vm.err != nil if ethutil.Config.Paranoia { var ( @@ -274,21 +278,8 @@ func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error, deepErr if !valid { // TODO FIXME ASAP context.state.trie = t2 - /* - statelogger.Debugf("(o): %x\n", trie.Root) - trie.NewIterator().Each(func(key string, v *ethutil.Value) { - v.Decode() - statelogger.Debugf("%x : %x\n", key, v.Str()) - }) - - statelogger.Debugf("(c): %x\n", trie2.Root) - trie2.NewIterator().Each(func(key string, v *ethutil.Value) { - v.Decode() - statelogger.Debugf("%x : %x\n", key, v.Str()) - }) - */ - - //return nil, fmt.Errorf("PARANOIA: Different state object roots during copy"), false + + statelogger.Debugln("Warn: PARANOIA: Different state object roots during copy") } } -- cgit v1.2.3 From 90eb4f1939f7b0389d5784b889cc0e5d2b3451f7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 4 Jul 2014 15:32:10 +0200 Subject: Debug output, minor fixes and tweaks * Script compile length fix * Transition fix --- ethchain/state_transition.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 16e1f124b..6ea9a837d 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -201,8 +201,7 @@ func (self *StateTransition) TransitionState() (err error) { // script section for the state object. self.data = nil - statelogger.Debugln("~> init") - code, err := self.Eval(receiver.Init(), receiver) + code, err := self.Eval(receiver.Init(), receiver, "init") if err != nil { //self.state.Set(snapshot) self.state.ResetStateObject(receiver) @@ -213,8 +212,7 @@ func (self *StateTransition) TransitionState() (err error) { receiver.script = code } else { if len(receiver.Script()) > 0 { - statelogger.Debugln("~> code") - _, err = self.Eval(receiver.Script(), receiver) + _, err = self.Eval(receiver.Script(), receiver, "code") if err != nil { //self.state.Set(snapshot) self.state.ResetStateObject(receiver) @@ -240,7 +238,7 @@ func (self *StateTransition) transferValue(sender, receiver *StateObject) error return nil } -func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []byte, err error) { +func (self *StateTransition) Eval(script []byte, context *StateObject, typ string) (ret []byte, err error) { var ( block = self.block initiator = self.Sender() @@ -259,6 +257,7 @@ func (self *StateTransition) Eval(script []byte, context *StateObject) (ret []by Value: self.value, }) vm.Verbose = true + vm.Fn = typ ret, err = Call(vm, closure, self.data) @@ -279,7 +278,7 @@ func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error) { // TODO FIXME ASAP context.state.trie = t2 - statelogger.Debugln("Warn: PARANOIA: Different state object roots during copy") + statelogger.Infoln("Warn: PARANOIA: Different state object roots during copy") } } -- cgit v1.2.3 From d40cba3042564f3471aa20a5cf477cafcacc2189 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 7 Jul 2014 10:53:20 +0200 Subject: changed state reset --- ethchain/state_transition.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 6ea9a837d..a92aa4a33 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -164,8 +164,6 @@ func (self *StateTransition) TransitionState() (err error) { // Increment the nonce for the next transaction sender.Nonce += 1 - receiver = self.Receiver() - // Transaction gas if err = self.UseGas(GasTx); err != nil { return @@ -178,6 +176,10 @@ func (self *StateTransition) TransitionState() (err error) { return } + snapshot := self.state.Copy() + + receiver = self.Receiver() + // If the receiver is nil it's a contract (\0*32). if receiver == nil { // Create a new state object for the contract @@ -192,8 +194,6 @@ func (self *StateTransition) TransitionState() (err error) { return } - //snapshot := self.state.Copy() - // Process the init code and create 'valid' contract if IsContractAddr(self.receiver) { // Evaluate the initialization script @@ -203,8 +203,7 @@ func (self *StateTransition) TransitionState() (err error) { code, err := self.Eval(receiver.Init(), receiver, "init") if err != nil { - //self.state.Set(snapshot) - self.state.ResetStateObject(receiver) + self.state.Set(snapshot) return fmt.Errorf("Error during init execution %v", err) } @@ -214,8 +213,7 @@ func (self *StateTransition) TransitionState() (err error) { if len(receiver.Script()) > 0 { _, err = self.Eval(receiver.Script(), receiver, "code") if err != nil { - //self.state.Set(snapshot) - self.state.ResetStateObject(receiver) + self.state.Set(snapshot) return fmt.Errorf("Error during code execution %v", err) } -- cgit v1.2.3 From 68fba4b781652c0181ca58cf176e96a303acffe4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 7 Jul 2014 11:17:48 +0200 Subject: Fixed state reset on err --- ethchain/state_transition.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index a92aa4a33..10a795cb8 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -176,8 +176,6 @@ func (self *StateTransition) TransitionState() (err error) { return } - snapshot := self.state.Copy() - receiver = self.Receiver() // If the receiver is nil it's a contract (\0*32). @@ -194,6 +192,8 @@ func (self *StateTransition) TransitionState() (err error) { return } + snapshot := self.state.Copy() + // Process the init code and create 'valid' contract if IsContractAddr(self.receiver) { // Evaluate the initialization script -- cgit v1.2.3 From b01cb2406f94745277fe05dfa74c6e5d42af1c6a Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 7 Jul 2014 13:59:09 +0200 Subject: Fixed state reset case --- ethchain/state_transition.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 10a795cb8..314d858f2 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -176,15 +176,23 @@ func (self *StateTransition) TransitionState() (err error) { return } - receiver = self.Receiver() + /* FIXME + * If tx goes TO "0", goes OOG during init, reverse changes, but initial endowment should happen. The ether is lost forever + */ + var snapshot *State // If the receiver is nil it's a contract (\0*32). - if receiver == nil { + if tx.CreatesContract() { + snapshot = self.state.Copy() + // Create a new state object for the contract receiver = self.MakeStateObject(self.state, tx) + self.rec = receiver if receiver == nil { return fmt.Errorf("Unable to create contract") } + } else { + receiver = self.Receiver() } // Transfer value from sender to receiver @@ -192,7 +200,9 @@ func (self *StateTransition) TransitionState() (err error) { return } - snapshot := self.state.Copy() + if snapshot == nil { + snapshot = self.state.Copy() + } // Process the init code and create 'valid' contract if IsContractAddr(self.receiver) { -- cgit v1.2.3 From 69acda2c255b098a015e17432b9bffd9010d841d Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 15 Jul 2014 00:25:27 +0200 Subject: Paranoia check moved --- ethchain/state_transition.go | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 314d858f2..8cface9e8 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -2,8 +2,6 @@ package ethchain import ( "fmt" - "github.com/ethereum/eth-go/ethtrie" - "github.com/ethereum/eth-go/ethutil" "math/big" ) @@ -275,20 +273,5 @@ func (self *StateTransition) Eval(script []byte, context *StateObject, typ strin func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error) { ret, _, err = closure.Call(vm, data) - if ethutil.Config.Paranoia { - var ( - context = closure.object - trie = context.state.trie - ) - - valid, t2 := ethtrie.ParanoiaCheck(trie) - if !valid { - // TODO FIXME ASAP - context.state.trie = t2 - - statelogger.Infoln("Warn: PARANOIA: Different state object roots during copy") - } - } - return } -- cgit v1.2.3 From 0415e4a637296539e7a5c09282b7aee19268e599 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 17 Jul 2014 14:53:27 +0200 Subject: Fixed coinbase copy in state --- ethchain/state_transition.go | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 8cface9e8..8ed528c9f 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -42,7 +42,7 @@ func (self *StateTransition) Coinbase() *StateObject { return self.cb } - self.cb = self.state.GetAccount(self.coinbase) + self.cb = self.state.GetOrNewStateObject(self.coinbase) return self.cb } func (self *StateTransition) Sender() *StateObject { @@ -50,7 +50,7 @@ func (self *StateTransition) Sender() *StateObject { return self.sen } - self.sen = self.state.GetAccount(self.tx.Sender()) + self.sen = self.state.GetOrNewStateObject(self.tx.Sender()) return self.sen } @@ -63,7 +63,7 @@ func (self *StateTransition) Receiver() *StateObject { return self.rec } - self.rec = self.state.GetAccount(self.tx.Recipient) + self.rec = self.state.GetOrNewStateObject(self.tx.Recipient) return self.rec } @@ -174,13 +174,16 @@ func (self *StateTransition) TransitionState() (err error) { return } - /* FIXME - * If tx goes TO "0", goes OOG during init, reverse changes, but initial endowment should happen. The ether is lost forever - */ - var snapshot *State + if sender.Amount.Cmp(self.value) < 0 { + return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount) + } + var snapshot *State // If the receiver is nil it's a contract (\0*32). if tx.CreatesContract() { + // Subtract the (irreversible) amount from the senders account + sender.SubAmount(self.value) + snapshot = self.state.Copy() // Create a new state object for the contract @@ -189,16 +192,17 @@ func (self *StateTransition) TransitionState() (err error) { if receiver == nil { return fmt.Errorf("Unable to create contract") } + + // Add the amount to receivers account which should conclude this transaction + receiver.AddAmount(self.value) } else { receiver = self.Receiver() - } - // Transfer value from sender to receiver - if err = self.transferValue(sender, receiver); err != nil { - return - } + // Subtract the amount from the senders account + sender.SubAmount(self.value) + // Add the amount to receivers account which should conclude this transaction + receiver.AddAmount(self.value) - if snapshot == nil { snapshot = self.state.Copy() } -- cgit v1.2.3 From 32d125131f602d63f66ee7eb09439074f0b94a91 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 24 Jul 2014 12:04:15 +0200 Subject: Refactored to new state and vm --- ethchain/state_transition.go | 95 +++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 32 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 8ed528c9f..a03a3a94a 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -2,6 +2,10 @@ package ethchain import ( "fmt" + "github.com/ethereum/eth-go/ethstate" + "github.com/ethereum/eth-go/ethtrie" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethvm" "math/big" ) @@ -27,17 +31,17 @@ type StateTransition struct { gas, gasPrice *big.Int value *big.Int data []byte - state *State + state *ethstate.State block *Block - cb, rec, sen *StateObject + cb, rec, sen *ethstate.StateObject } -func NewStateTransition(coinbase *StateObject, tx *Transaction, state *State, block *Block) *StateTransition { +func NewStateTransition(coinbase *ethstate.StateObject, tx *Transaction, state *ethstate.State, block *Block) *StateTransition { return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil} } -func (self *StateTransition) Coinbase() *StateObject { +func (self *StateTransition) Coinbase() *ethstate.StateObject { if self.cb != nil { return self.cb } @@ -45,7 +49,7 @@ func (self *StateTransition) Coinbase() *StateObject { self.cb = self.state.GetOrNewStateObject(self.coinbase) return self.cb } -func (self *StateTransition) Sender() *StateObject { +func (self *StateTransition) Sender() *ethstate.StateObject { if self.sen != nil { return self.sen } @@ -54,7 +58,7 @@ func (self *StateTransition) Sender() *StateObject { return self.sen } -func (self *StateTransition) Receiver() *StateObject { +func (self *StateTransition) Receiver() *ethstate.StateObject { if self.tx != nil && self.tx.CreatesContract() { return nil } @@ -67,7 +71,7 @@ func (self *StateTransition) Receiver() *StateObject { return self.rec } -func (self *StateTransition) MakeStateObject(state *State, tx *Transaction) *StateObject { +func (self *StateTransition) MakeStateObject(state *ethstate.State, tx *Transaction) *ethstate.StateObject { contract := MakeContract(tx, state) return contract @@ -154,7 +158,7 @@ func (self *StateTransition) TransitionState() (err error) { var ( tx = self.tx sender = self.Sender() - receiver *StateObject + receiver *ethstate.StateObject ) defer self.RefundGas() @@ -163,13 +167,13 @@ func (self *StateTransition) TransitionState() (err error) { sender.Nonce += 1 // Transaction gas - if err = self.UseGas(GasTx); err != nil { + if err = self.UseGas(ethvm.GasTx); err != nil { return } // Pay data gas dataPrice := big.NewInt(int64(len(self.data))) - dataPrice.Mul(dataPrice, GasData) + dataPrice.Mul(dataPrice, ethvm.GasData) if err = self.UseGas(dataPrice); err != nil { return } @@ -178,7 +182,7 @@ func (self *StateTransition) TransitionState() (err error) { return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount) } - var snapshot *State + var snapshot *ethstate.State // If the receiver is nil it's a contract (\0*32). if tx.CreatesContract() { // Subtract the (irreversible) amount from the senders account @@ -220,10 +224,10 @@ func (self *StateTransition) TransitionState() (err error) { return fmt.Errorf("Error during init execution %v", err) } - receiver.script = code + receiver.Code = code } else { - if len(receiver.Script()) > 0 { - _, err = self.Eval(receiver.Script(), receiver, "code") + if len(receiver.Code) > 0 { + _, err = self.Eval(receiver.Code, receiver, "code") if err != nil { self.state.Set(snapshot) @@ -235,7 +239,7 @@ func (self *StateTransition) TransitionState() (err error) { return } -func (self *StateTransition) transferValue(sender, receiver *StateObject) error { +func (self *StateTransition) transferValue(sender, receiver *ethstate.StateObject) error { if sender.Amount.Cmp(self.value) < 0 { return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount) } @@ -248,34 +252,61 @@ func (self *StateTransition) transferValue(sender, receiver *StateObject) error return nil } -func (self *StateTransition) Eval(script []byte, context *StateObject, typ string) (ret []byte, err error) { +func (self *StateTransition) Eval(script []byte, context *ethstate.StateObject, typ string) (ret []byte, err error) { var ( - block = self.block - initiator = self.Sender() - state = self.state + transactor = self.Sender() + state = self.state + env = NewEnv(state, self.tx, self.block) + callerClosure = ethvm.NewClosure(transactor, context, script, self.gas, self.gasPrice) ) - closure := NewClosure(initiator, context, script, state, self.gas, self.gasPrice) - vm := NewVm(state, nil, RuntimeVars{ - Origin: initiator.Address(), - Block: block, - BlockNumber: block.Number, - PrevHash: block.PrevHash, - Coinbase: block.Coinbase, - Time: block.Time, - Diff: block.Difficulty, - Value: self.value, - }) + vm := ethvm.New(env) vm.Verbose = true vm.Fn = typ - ret, err = Call(vm, closure, self.data) + ret, _, err = callerClosure.Call(vm, self.tx.Data) + + /* + closure := NewClosure(initiator, context, script, state, self.gas, self.gasPrice) + vm := NewVm(state, nil, RuntimeVars{ + Origin: initiator.Address(), + Block: block, + BlockNumber: block.Number, + PrevHash: block.PrevHash, + Coinbase: block.Coinbase, + Time: block.Time, + Diff: block.Difficulty, + Value: self.value, + }) + vm.Verbose = true + vm.Fn = typ + + ret, err = Call(vm, closure, self.data) + */ return } -func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error) { +/* +func Call(vm *eth.Vm, closure *Closure, data []byte) (ret []byte, err error) { ret, _, err = closure.Call(vm, data) return } +*/ + +// Converts an transaction in to a state object +func MakeContract(tx *Transaction, state *ethstate.State) *ethstate.StateObject { + // Create contract if there's no recipient + if tx.IsContract() { + addr := tx.CreationAddress() + + contract := state.NewStateObject(addr) + contract.InitCode = tx.Data + contract.State = ethstate.NewState(ethtrie.NewTrie(ethutil.Config.Db, "")) + + return contract + } + + return nil +} -- cgit v1.2.3 From a45c08f9fe320d79d2abc7c29e5f3b986130c5bb Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 24 Jul 2014 12:19:55 +0200 Subject: Removed old code --- ethchain/state_transition.go | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index a03a3a94a..266328ce8 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -266,34 +266,8 @@ func (self *StateTransition) Eval(script []byte, context *ethstate.StateObject, ret, _, err = callerClosure.Call(vm, self.tx.Data) - /* - closure := NewClosure(initiator, context, script, state, self.gas, self.gasPrice) - vm := NewVm(state, nil, RuntimeVars{ - Origin: initiator.Address(), - Block: block, - BlockNumber: block.Number, - PrevHash: block.PrevHash, - Coinbase: block.Coinbase, - Time: block.Time, - Diff: block.Difficulty, - Value: self.value, - }) - vm.Verbose = true - vm.Fn = typ - - ret, err = Call(vm, closure, self.data) - */ - - return -} - -/* -func Call(vm *eth.Vm, closure *Closure, data []byte) (ret []byte, err error) { - ret, _, err = closure.Call(vm, data) - return } -*/ // Converts an transaction in to a state object func MakeContract(tx *Transaction, state *ethstate.State) *ethstate.StateObject { -- cgit v1.2.3 From 1f9894c0845a5259adbfd30fe3a86631e6403b8d Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 30 Jul 2014 00:31:15 +0200 Subject: Old code removed and renamed amount to balance --- ethchain/state_transition.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 266328ce8..02a8e0e82 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -2,11 +2,12 @@ package ethchain import ( "fmt" + "math/big" + "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethtrie" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethvm" - "math/big" ) /* @@ -94,8 +95,8 @@ func (self *StateTransition) BuyGas() error { var err error sender := self.Sender() - if sender.Amount.Cmp(self.tx.GasValue()) < 0 { - return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Amount) + if sender.Balance.Cmp(self.tx.GasValue()) < 0 { + return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Balance) } coinbase := self.Coinbase() @@ -178,8 +179,8 @@ func (self *StateTransition) TransitionState() (err error) { return } - if sender.Amount.Cmp(self.value) < 0 { - return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount) + if sender.Balance.Cmp(self.value) < 0 { + return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance) } var snapshot *ethstate.State @@ -240,8 +241,8 @@ func (self *StateTransition) TransitionState() (err error) { } func (self *StateTransition) transferValue(sender, receiver *ethstate.StateObject) error { - if sender.Amount.Cmp(self.value) < 0 { - return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount) + if sender.Balance.Cmp(self.value) < 0 { + return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance) } // Subtract the amount from the senders account -- cgit v1.2.3 From 3debeb7236d2c8474fa9049cc91dc26bf1040b3f Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 4 Aug 2014 10:38:18 +0200 Subject: ethtrie.NewTrie => ethtrie.New --- ethchain/state_transition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 02a8e0e82..8f1561c00 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -278,7 +278,7 @@ func MakeContract(tx *Transaction, state *ethstate.State) *ethstate.StateObject contract := state.NewStateObject(addr) contract.InitCode = tx.Data - contract.State = ethstate.NewState(ethtrie.NewTrie(ethutil.Config.Db, "")) + contract.State = ethstate.NewState(ethtrie.New(ethutil.Config.Db, "")) return contract } -- cgit v1.2.3 From 03ce15df4c7ef51d4373233ab5c3766282b31771 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 4 Aug 2014 10:42:40 +0200 Subject: ethstate.NewState => ethstate.New --- ethchain/state_transition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 8f1561c00..dfcbfcc04 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -278,7 +278,7 @@ func MakeContract(tx *Transaction, state *ethstate.State) *ethstate.StateObject contract := state.NewStateObject(addr) contract.InitCode = tx.Data - contract.State = ethstate.NewState(ethtrie.New(ethutil.Config.Db, "")) + contract.State = ethstate.New(ethtrie.New(ethutil.Config.Db, "")) return contract } -- cgit v1.2.3 From a760ce05b948e89bc564af20599dcf95698ac0eb Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 11 Aug 2014 16:23:38 +0200 Subject: Updated chain for filtering --- ethchain/state_transition.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index dfcbfcc04..489ff2b6a 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -211,6 +211,13 @@ func (self *StateTransition) TransitionState() (err error) { snapshot = self.state.Copy() } + msg := self.state.Manifest().AddMessage(ðstate.Message{ + To: receiver.Address(), From: sender.Address(), + Input: self.tx.Data, + Origin: sender.Address(), + Block: self.block.Hash(), Timestamp: self.block.Time, Coinbase: self.block.Coinbase, Number: self.block.Number, + }) + // Process the init code and create 'valid' contract if IsContractAddr(self.receiver) { // Evaluate the initialization script @@ -226,14 +233,17 @@ func (self *StateTransition) TransitionState() (err error) { } receiver.Code = code + msg.Output = code } else { if len(receiver.Code) > 0 { - _, err = self.Eval(receiver.Code, receiver, "code") + ret, err := self.Eval(receiver.Code, receiver, "code") if err != nil { self.state.Set(snapshot) return fmt.Errorf("Error during code execution %v", err) } + + msg.Output = ret } } -- cgit v1.2.3 From 7d95e8624a3bdca4a68b2a7ff6ed133264088cc1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 15 Aug 2014 16:19:10 +0200 Subject: Added message to closure && added change addresses --- ethchain/state_transition.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 489ff2b6a..f8452cdb3 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -225,7 +225,7 @@ func (self *StateTransition) TransitionState() (err error) { // script section for the state object. self.data = nil - code, err := self.Eval(receiver.Init(), receiver, "init") + code, err := self.Eval(msg, receiver.Init(), receiver, "init") if err != nil { self.state.Set(snapshot) @@ -236,7 +236,7 @@ func (self *StateTransition) TransitionState() (err error) { msg.Output = code } else { if len(receiver.Code) > 0 { - ret, err := self.Eval(receiver.Code, receiver, "code") + ret, err := self.Eval(msg, receiver.Code, receiver, "code") if err != nil { self.state.Set(snapshot) @@ -263,12 +263,12 @@ func (self *StateTransition) transferValue(sender, receiver *ethstate.StateObjec return nil } -func (self *StateTransition) Eval(script []byte, context *ethstate.StateObject, typ string) (ret []byte, err error) { +func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context *ethstate.StateObject, typ string) (ret []byte, err error) { var ( transactor = self.Sender() state = self.state env = NewEnv(state, self.tx, self.block) - callerClosure = ethvm.NewClosure(transactor, context, script, self.gas, self.gasPrice) + callerClosure = ethvm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice) ) vm := ethvm.New(env) -- cgit v1.2.3 From b0ae61c6521003d7861d89944e1d426e939535bb Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 18 Aug 2014 10:17:45 +0200 Subject: Removed the "Get" part --- ethchain/state_transition.go | 1 + 1 file changed, 1 insertion(+) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index f8452cdb3..9fbc160a5 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -216,6 +216,7 @@ func (self *StateTransition) TransitionState() (err error) { Input: self.tx.Data, Origin: sender.Address(), Block: self.block.Hash(), Timestamp: self.block.Time, Coinbase: self.block.Coinbase, Number: self.block.Number, + Value: self.value, }) // Process the init code and create 'valid' contract -- cgit v1.2.3 From 93008e279d947e872099c8029b54f7431178bb29 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 22 Aug 2014 10:58:14 +0200 Subject: Removed old chain code --- ethchain/state_transition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 9fbc160a5..80f9fda5e 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -140,7 +140,7 @@ func (self *StateTransition) preCheck() (err error) { } func (self *StateTransition) TransitionState() (err error) { - statelogger.Infof("(~) %x\n", self.tx.Hash()) + statelogger.Debugf("(~) %x\n", self.tx.Hash()) /* defer func() { -- cgit v1.2.3 From 3f904bf3acb5779f68834ebca95825ea1990f85b Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 25 Aug 2014 11:29:42 +0200 Subject: Implemented POST --- ethchain/state_transition.go | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 80f9fda5e..1c7eae675 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -278,6 +278,15 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context ret, _, err = callerClosure.Call(vm, self.tx.Data) + if err == nil { + // Execute POSTs + for e := vm.Queue().Front(); e != nil; e = e.Next() { + msg := e.Value.(*ethvm.Message) + + msg.Exec(transactor) + } + } + return } -- cgit v1.2.3 From 29499900160cc2ee88968b74035f0a5c2d4c5af6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 10 Sep 2014 00:19:20 +0200 Subject: Added CALLSTATELESS --- ethchain/state_transition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 1c7eae675..c1180a641 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -283,7 +283,7 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context for e := vm.Queue().Front(); e != nil; e = e.Next() { msg := e.Value.(*ethvm.Message) - msg.Exec(transactor) + msg.Exec(msg.Addr(), transactor) } } -- cgit v1.2.3 From 3af211dd65d6690afce9976a9f47ab1cdddb8d58 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 30 Sep 2014 23:26:52 +0200 Subject: Implemented WebSocket package --- ethchain/state_transition.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index c1180a641..096464963 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -142,14 +142,12 @@ func (self *StateTransition) preCheck() (err error) { func (self *StateTransition) TransitionState() (err error) { statelogger.Debugf("(~) %x\n", self.tx.Hash()) - /* - defer func() { - if r := recover(); r != nil { - logger.Infoln(r) - err = fmt.Errorf("state transition err %v", r) - } - }() - */ + defer func() { + if r := recover(); r != nil { + statelogger.Infoln(r) + err = fmt.Errorf("state transition err %v", r) + } + }() // XXX Transactions after this point are considered valid. if err = self.preCheck(); err != nil { -- cgit v1.2.3 From 82be3054961864dfd5bbeaec2ab961f593203dbf Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 2 Oct 2014 17:03:15 +0200 Subject: Fixed inconsistencies --- ethchain/state_transition.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 096464963..fbb729950 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -292,9 +292,9 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context func MakeContract(tx *Transaction, state *ethstate.State) *ethstate.StateObject { // Create contract if there's no recipient if tx.IsContract() { - addr := tx.CreationAddress() + addr := tx.CreationAddress(state) - contract := state.NewStateObject(addr) + contract := state.GetOrNewStateObject(addr) contract.InitCode = tx.Data contract.State = ethstate.New(ethtrie.New(ethutil.Config.Db, "")) -- cgit v1.2.3 From b417766b36f46316cbae6fa42815f1a519e5f733 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 8 Oct 2014 11:59:44 +0200 Subject: Minor tweaks for poc7 --- ethchain/state_transition.go | 9 --------- 1 file changed, 9 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index fbb729950..28cb66105 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -276,15 +276,6 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context ret, _, err = callerClosure.Call(vm, self.tx.Data) - if err == nil { - // Execute POSTs - for e := vm.Queue().Front(); e != nil; e = e.Next() { - msg := e.Value.(*ethvm.Message) - - msg.Exec(msg.Addr(), transactor) - } - } - return } -- cgit v1.2.3 From c5bd32b0ad1a3d0fd20a3d1014cc8a97d889dc28 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 14 Oct 2014 11:48:52 +0200 Subject: Refactored VM to two separate VMs; std & debug Standard VM should be about 10x faster than the debug VM. Some error checking has been removed, all of the log statements and therefor quite some unnecessary if-statements. --- ethchain/state_transition.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 28cb66105..10159929b 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -224,7 +224,7 @@ func (self *StateTransition) TransitionState() (err error) { // script section for the state object. self.data = nil - code, err := self.Eval(msg, receiver.Init(), receiver, "init") + code, err := self.Eval(msg, receiver.Init(), receiver) if err != nil { self.state.Set(snapshot) @@ -235,7 +235,7 @@ func (self *StateTransition) TransitionState() (err error) { msg.Output = code } else { if len(receiver.Code) > 0 { - ret, err := self.Eval(msg, receiver.Code, receiver, "code") + ret, err := self.Eval(msg, receiver.Code, receiver) if err != nil { self.state.Set(snapshot) @@ -262,7 +262,7 @@ func (self *StateTransition) transferValue(sender, receiver *ethstate.StateObjec return nil } -func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context *ethstate.StateObject, typ string) (ret []byte, err error) { +func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context *ethstate.StateObject) (ret []byte, err error) { var ( transactor = self.Sender() state = self.state @@ -270,9 +270,7 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context callerClosure = ethvm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice) ) - vm := ethvm.New(env) - vm.Verbose = true - vm.Fn = typ + vm := ethvm.New(env, ethvm.Type(ethutil.Config.VmType)) ret, _, err = callerClosure.Call(vm, self.tx.Data) -- cgit v1.2.3 From 311c6f8a3fed5ac03ee4b442fd0f420072bc41b4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 15 Oct 2014 17:12:26 +0200 Subject: Fixed remote Arithmetic tests --- ethchain/state_transition.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 10159929b..719e5fd66 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -270,7 +270,8 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context callerClosure = ethvm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice) ) - vm := ethvm.New(env, ethvm.Type(ethutil.Config.VmType)) + //vm := ethvm.New(env, ethvm.Type(ethutil.Config.VmType)) + vm := ethutil.New(env, ethvm.DebugVmTy) ret, _, err = callerClosure.Call(vm, self.tx.Data) -- cgit v1.2.3 From bb5038699ef7e08054ef154107e359dce2e3b106 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Oct 2014 13:41:44 +0200 Subject: Corrected package .... --- ethchain/state_transition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 719e5fd66..93b991c45 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -271,7 +271,7 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context ) //vm := ethvm.New(env, ethvm.Type(ethutil.Config.VmType)) - vm := ethutil.New(env, ethvm.DebugVmTy) + vm := ethvm.New(env, ethvm.DebugVmTy) ret, _, err = callerClosure.Call(vm, self.tx.Data) -- cgit v1.2.3 From 93fcabd25189b447cc5c52523134cca2fa1d794e Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Oct 2014 18:27:05 +0200 Subject: Fixed most of the tests --- ethchain/state_transition.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 93b991c45..5bb084ae4 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -72,12 +72,6 @@ func (self *StateTransition) Receiver() *ethstate.StateObject { return self.rec } -func (self *StateTransition) MakeStateObject(state *ethstate.State, tx *Transaction) *ethstate.StateObject { - contract := MakeContract(tx, state) - - return contract -} - func (self *StateTransition) UseGas(amount *big.Int) error { if self.gas.Cmp(amount) < 0 { return OutOfGasError() @@ -190,7 +184,7 @@ func (self *StateTransition) TransitionState() (err error) { snapshot = self.state.Copy() // Create a new state object for the contract - receiver = self.MakeStateObject(self.state, tx) + receiver := MakeContract(tx, self.state) self.rec = receiver if receiver == nil { return fmt.Errorf("Unable to create contract") -- cgit v1.2.3 From 20c742e47406c13ebc6427951f6fcf1b0056ea26 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 18 Oct 2014 13:31:20 +0200 Subject: Moved ethvm => vm --- ethchain/state_transition.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 5bb084ae4..79321eaac 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethtrie" "github.com/ethereum/eth-go/ethutil" - "github.com/ethereum/eth-go/ethvm" + "github.com/ethereum/eth-go/vm" ) /* @@ -160,13 +160,13 @@ func (self *StateTransition) TransitionState() (err error) { sender.Nonce += 1 // Transaction gas - if err = self.UseGas(ethvm.GasTx); err != nil { + if err = self.UseGas(vm.GasTx); err != nil { return } // Pay data gas dataPrice := big.NewInt(int64(len(self.data))) - dataPrice.Mul(dataPrice, ethvm.GasData) + dataPrice.Mul(dataPrice, vm.GasData) if err = self.UseGas(dataPrice); err != nil { return } @@ -261,11 +261,11 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context transactor = self.Sender() state = self.state env = NewEnv(state, self.tx, self.block) - callerClosure = ethvm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice) + callerClosure = vm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice) ) - //vm := ethvm.New(env, ethvm.Type(ethutil.Config.VmType)) - vm := ethvm.New(env, ethvm.DebugVmTy) + //vm := vm.New(env, vm.Type(ethutil.Config.VmType)) + vm := vm.New(env, vm.DebugVmTy) ret, _, err = callerClosure.Call(vm, self.tx.Data) -- cgit v1.2.3 From 29b8a0bc5ffa7a674a06a211e1c8bdd1b6ed07b1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 23 Oct 2014 01:01:26 +0200 Subject: Updated the VM & VM tests * Stack Error shouldn't revert to previous state * Updated VM Test tool * Added Transfer method to VM Env --- ethchain/state_transition.go | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'ethchain/state_transition.go') diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 79321eaac..1e6834729 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -89,8 +89,8 @@ func (self *StateTransition) BuyGas() error { var err error sender := self.Sender() - if sender.Balance.Cmp(self.tx.GasValue()) < 0 { - return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Balance) + if sender.Balance().Cmp(self.tx.GasValue()) < 0 { + return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Balance()) } coinbase := self.Coinbase() @@ -171,7 +171,7 @@ func (self *StateTransition) TransitionState() (err error) { return } - if sender.Balance.Cmp(self.value) < 0 { + if sender.Balance().Cmp(self.value) < 0 { return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance) } @@ -243,19 +243,6 @@ func (self *StateTransition) TransitionState() (err error) { return } -func (self *StateTransition) transferValue(sender, receiver *ethstate.StateObject) error { - if sender.Balance.Cmp(self.value) < 0 { - return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance) - } - - // Subtract the amount from the senders account - sender.SubAmount(self.value) - // Add the amount to receivers account which should conclude this transaction - receiver.AddAmount(self.value) - - return nil -} - func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context *ethstate.StateObject) (ret []byte, err error) { var ( transactor = self.Sender() @@ -265,9 +252,9 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context ) //vm := vm.New(env, vm.Type(ethutil.Config.VmType)) - vm := vm.New(env, vm.DebugVmTy) + evm := vm.New(env, vm.DebugVmTy) - ret, _, err = callerClosure.Call(vm, self.tx.Data) + ret, _, err = callerClosure.Call(evm, self.tx.Data) return } -- cgit v1.2.3