Merge branch 'develop' of github.com:ethereum/eth-go into feature/clientid

This commit is contained in:
zelig 2014-07-03 15:08:13 +01:00
commit de2da4fd19
6 changed files with 66 additions and 46 deletions

View File

@ -93,10 +93,6 @@ func (self *State) ResetStateObject(stateObject *StateObject) {
func (self *State) UpdateStateObject(stateObject *StateObject) { func (self *State) UpdateStateObject(stateObject *StateObject) {
addr := stateObject.Address() addr := stateObject.Address()
if self.stateObjects[string(addr)] == nil {
self.stateObjects[string(addr)] = stateObject
}
ethutil.Config.Db.Put(ethcrypto.Sha3Bin(stateObject.Script()), stateObject.Script()) ethutil.Config.Db.Put(ethcrypto.Sha3Bin(stateObject.Script()), stateObject.Script())
self.trie.Update(string(addr), string(stateObject.RlpEncode())) self.trie.Update(string(addr), string(stateObject.RlpEncode()))
@ -131,7 +127,7 @@ func (self *State) GetOrNewStateObject(addr []byte) *StateObject {
} }
func (self *State) NewStateObject(addr []byte) *StateObject { func (self *State) NewStateObject(addr []byte) *StateObject {
//statelogger.Infof("(+) %x\n", addr) statelogger.Infof("(+) %x\n", addr)
stateObject := NewStateObject(addr) stateObject := NewStateObject(addr)
self.stateObjects[string(addr)] = stateObject self.stateObjects[string(addr)] = stateObject

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethtrie"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethwire" "github.com/ethereum/eth-go/ethwire"
"math/big" "math/big"
@ -205,7 +206,15 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
return err return err
} }
if ethutil.Config.Paranoia {
valid, _ := ethtrie.ParanoiaCheck(state.trie)
if !valid {
err = fmt.Errorf("PARANOIA: World state trie corruption")
}
}
if !block.State().Cmp(state) { if !block.State().Cmp(state) {
err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().trie.Root, state.trie.Root) err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().trie.Root, state.trie.Root)
return return
} }

View File

@ -1,7 +1,6 @@
package ethchain package ethchain
import ( import (
"bytes"
"fmt" "fmt"
"github.com/ethereum/eth-go/ethtrie" "github.com/ethereum/eth-go/ethtrie"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
@ -54,6 +53,7 @@ func (self *StateTransition) Sender() *StateObject {
} }
self.sen = self.state.GetAccount(self.tx.Sender()) self.sen = self.state.GetAccount(self.tx.Sender())
return self.sen return self.sen
} }
func (self *StateTransition) Receiver() *StateObject { func (self *StateTransition) Receiver() *StateObject {
@ -264,23 +264,16 @@ func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error, deepErr
ret, _, err = closure.Call(vm, data) ret, _, err = closure.Call(vm, data)
deepErr = vm.err != nil deepErr = vm.err != nil
Paranoia := ethutil.Config.Paranoia if ethutil.Config.Paranoia {
if Paranoia {
var ( var (
context = closure.object context = closure.object
trie = context.state.trie trie = context.state.trie
trie2 = ethtrie.NewTrie(ethutil.Config.Db, "")
) )
trie.NewIterator().Each(func(key string, v *ethutil.Value) { valid, t2 := ethtrie.ParanoiaCheck(trie)
trie2.Update(key, v.Str()) if !valid {
})
a := ethutil.NewValue(trie2.Root).Bytes()
b := ethutil.NewValue(context.state.trie.Root).Bytes()
if bytes.Compare(a, b) != 0 {
// TODO FIXME ASAP // TODO FIXME ASAP
context.state.trie = trie2 context.state.trie = t2
/* /*
statelogger.Debugf("(o): %x\n", trie.Root) statelogger.Debugf("(o): %x\n", trie.Root)
trie.NewIterator().Each(func(key string, v *ethutil.Value) { trie.NewIterator().Each(func(key string, v *ethutil.Value) {

View File

@ -35,7 +35,6 @@ func CalculateTxGas(initSize *big.Int) *big.Int {
} }
type Vm struct { type Vm struct {
txPool *TxPool
// Stack for processing contracts // Stack for processing contracts
stack *Stack stack *Stack
// non-persistent key/value memory storage // non-persistent key/value memory storage
@ -617,48 +616,59 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
case CREATE: case CREATE:
require(3) require(3)
value := stack.Pop() var (
size, offset := stack.Popn() err error
value = stack.Pop()
size, offset = stack.Popn()
// Snapshot the current stack so we are able to // Snapshot the current stack so we are able to
// revert back to it later. // revert back to it later.
snapshot := vm.state.Copy() snapshot = vm.state.Copy()
)
// Generate a new address // Generate a new address
addr := ethcrypto.CreateAddress(closure.caller.Address(), closure.caller.N()) addr := ethcrypto.CreateAddress(closure.object.Address(), closure.object.Nonce)
for i := uint64(0); vm.state.GetStateObject(addr) != nil; i++ {
ethcrypto.CreateAddress(closure.object.Address(), closure.object.Nonce+i)
}
closure.object.Nonce++
vm.Printf(" (*) %x", addr).Endl() vm.Printf(" (*) %x", addr).Endl()
// Create a new contract // Create a new contract
contract := vm.state.NewStateObject(addr) contract := vm.state.NewStateObject(addr)
contract.Amount = value if contract.Amount.Cmp(value) >= 0 {
closure.object.SubAmount(value)
contract.AddAmount(value)
// Set the init script // Set the init script
contract.initScript = ethutil.BigD(mem.Get(offset.Int64(), size.Int64())).Bytes() contract.initScript = mem.Get(offset.Int64(), size.Int64())
// Transfer all remaining gas to the new // Transfer all remaining gas to the new
// contract so it may run the init script // contract so it may run the init script
gas := new(big.Int).Set(closure.Gas) gas := new(big.Int).Set(closure.Gas)
closure.UseGas(closure.Gas)
// Create the closure // Create the closure
c := NewClosure(closure.caller, c := NewClosure(closure, contract, contract.initScript, vm.state, gas, closure.Price)
closure.Object(), // Call the closure and set the return value as
contract.initScript, // main script.
vm.state, contract.script, err, _ = Call(vm, c, nil)
gas, } else {
closure.Price) err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount)
// Call the closure and set the return value as }
// main script.
var err error
c.Script, gas, err = c.Call(vm, nil)
if err != nil { if err != nil {
stack.Push(ethutil.BigFalse) stack.Push(ethutil.BigFalse)
// Revert the state as it was before. // Revert the state as it was before.
vm.state.Set(snapshot) vm.state.Set(snapshot)
vm.Printf("CREATE err %v", err)
} else { } else {
stack.Push(ethutil.BigD(addr)) stack.Push(ethutil.BigD(addr))
vm.Printf("CREATE success")
} }
vm.Endl()
case CALL: case CALL:
require(7) require(7)

View File

@ -3,8 +3,8 @@ package ethcrypto
import ( import (
"code.google.com/p/go.crypto/ripemd160" "code.google.com/p/go.crypto/ripemd160"
"crypto/sha256" "crypto/sha256"
"github.com/ethereum/eth-go/ethutil"
"github.com/obscuren/sha3" "github.com/obscuren/sha3"
"math/big"
) )
func Sha256Bin(data []byte) []byte { func Sha256Bin(data []byte) []byte {
@ -28,8 +28,6 @@ func Sha3Bin(data []byte) []byte {
} }
// Creates an ethereum address given the bytes and the nonce // Creates an ethereum address given the bytes and the nonce
func CreateAddress(b []byte, nonce *big.Int) []byte { func CreateAddress(b []byte, nonce uint64) []byte {
addrBytes := append(b, nonce.Bytes()...) return Sha3Bin(ethutil.NewValue([]interface{}{b, nonce}).Encode())[12:]
return Sha3Bin(addrBytes)[12:]
} }

View File

@ -1,6 +1,7 @@
package ethtrie package ethtrie
import ( import (
"bytes"
"fmt" "fmt"
"github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
@ -8,6 +9,19 @@ import (
"sync" "sync"
) )
func ParanoiaCheck(t1 *Trie) (bool, *Trie) {
t2 := NewTrie(ethutil.Config.Db, "")
t1.NewIterator().Each(func(key string, v *ethutil.Value) {
t2.Update(key, v.Str())
})
a := ethutil.NewValue(t2.Root).Bytes()
b := ethutil.NewValue(t1.Root).Bytes()
return bytes.Compare(a, b) == 0, t2
}
func (s *Cache) Len() int { func (s *Cache) Len() int {
return len(s.nodes) return len(s.nodes)
} }