Merge branch 'develop' of github.com:ethereum/eth-go into feature/clientid
This commit is contained in:
commit
de2da4fd19
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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:]
|
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user