aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ethchain/state.go4
-rw-r--r--ethchain/state_manager.go1
-rw-r--r--ethchain/state_object.go41
-rw-r--r--ethchain/vm.go2
-rw-r--r--ethtrie/trie.go30
-rw-r--r--ethtrie/trie_test.go69
-rw-r--r--ethutil/bytes.go12
-rw-r--r--ethutil/value.go8
8 files changed, 129 insertions, 38 deletions
diff --git a/ethchain/state.go b/ethchain/state.go
index 66c298b3c..6b849296a 100644
--- a/ethchain/state.go
+++ b/ethchain/state.go
@@ -76,6 +76,8 @@ func (self *State) DeleteStateObject(stateObject *StateObject) {
// Retrieve a state object given my the address. Nil if not found
func (self *State) GetStateObject(addr []byte) *StateObject {
+ addr = ethutil.Address(addr)
+
stateObject := self.stateObjects[string(addr)]
if stateObject != nil {
return stateObject
@@ -204,6 +206,8 @@ func (self *State) Update() {
// FIXME trie delete is broken
valid, t2 := ethtrie.ParanoiaCheck(self.trie)
if !valid {
+ statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.trie.Root, t2.Root)
+
self.trie = t2
}
}
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index 80362fa77..a0568c4cd 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -121,6 +121,7 @@ done:
for i, tx := range txs {
txGas := new(big.Int).Set(tx.Gas)
st := NewStateTransition(coinbase, tx, state, block)
+ //fmt.Printf("#%d\n", i+1)
err = st.TransitionState()
if err != nil {
switch {
diff --git a/ethchain/state_object.go b/ethchain/state_object.go
index 889496e91..cf37586fc 100644
--- a/ethchain/state_object.go
+++ b/ethchain/state_object.go
@@ -75,7 +75,7 @@ func MakeContract(tx *Transaction, state *State) *StateObject {
func NewStateObject(addr []byte) *StateObject {
// This to ensure that it has 20 bytes (and not 0 bytes), thus left or right pad doesn't matter.
- address := ethutil.LeftPadBytes(addr, 20)
+ address := ethutil.Address(addr)
object := &StateObject{address: address, Amount: new(big.Int), gasPool: new(big.Int)}
object.state = NewState(ethtrie.NewTrie(ethutil.Config.Db, ""))
@@ -92,13 +92,6 @@ func NewContract(address []byte, Amount *big.Int, root []byte) *StateObject {
return contract
}
-// Returns a newly created account
-func NewAccount(address []byte, amount *big.Int) *StateObject {
- account := &StateObject{address: address, Amount: amount, Nonce: 0}
-
- return account
-}
-
func NewStateObjectFromBytes(address, data []byte) *StateObject {
object := &StateObject{address: address}
object.RlpDecode(data)
@@ -139,17 +132,37 @@ func (self *StateObject) getStorage(k []byte) *ethutil.Value {
}
return value
+
+ //return self.GetAddr(key)
}
func (self *StateObject) setStorage(k []byte, value *ethutil.Value) {
key := ethutil.LeftPadBytes(k, 32)
- //fmt.Printf("%x %v\n", key, value)
self.storage[string(key)] = value.Copy()
+
+ /*
+ if value.BigInt().Cmp(ethutil.Big0) == 0 {
+ self.state.trie.Delete(string(key))
+ return
+ }
+
+ self.SetAddr(key, value)
+ */
}
func (self *StateObject) Sync() {
+ /*
+ fmt.Println("############# BEFORE ################")
+ self.state.EachStorage(func(key string, value *ethutil.Value) {
+ fmt.Printf("%x %x %x\n", self.Address(), []byte(key), value.Bytes())
+ })
+ fmt.Printf("%x @:%x\n", self.Address(), self.state.Root())
+ fmt.Println("#####################################")
+ */
for key, value := range self.storage {
- if value.BigInt().Cmp(ethutil.Big0) == 0 {
+ if value.Len() == 0 { // value.BigInt().Cmp(ethutil.Big0) == 0 {
+ //data := self.getStorage([]byte(key))
+ //fmt.Printf("deleting %x %x 0x%x\n", self.Address(), []byte(key), data)
self.state.trie.Delete(string(key))
continue
}
@@ -163,6 +176,14 @@ func (self *StateObject) Sync() {
self.state.trie = t2
}
+
+ /*
+ fmt.Println("############# AFTER ################")
+ self.state.EachStorage(func(key string, value *ethutil.Value) {
+ fmt.Printf("%x %x %x\n", self.Address(), []byte(key), value.Bytes())
+ })
+ */
+ //fmt.Printf("%x @:%x\n", self.Address(), self.state.Root())
}
func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value {
diff --git a/ethchain/vm.go b/ethchain/vm.go
index 3a956ee83..58d1bee89 100644
--- a/ethchain/vm.go
+++ b/ethchain/vm.go
@@ -195,7 +195,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
val := closure.GetStorage(x)
if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 {
mult = ethutil.Big2
- } else if !val.IsEmpty() && len(y.Bytes()) == 0 {
+ } else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 {
mult = ethutil.Big0
} else {
mult = ethutil.Big1
diff --git a/ethtrie/trie.go b/ethtrie/trie.go
index 07720be54..f0f3fe5a8 100644
--- a/ethtrie/trie.go
+++ b/ethtrie/trie.go
@@ -5,7 +5,7 @@ import (
"fmt"
"github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethutil"
- "reflect"
+ _ "reflect"
"sync"
)
@@ -326,7 +326,8 @@ func (t *Trie) InsertState(node interface{}, key []int, value interface{}) inter
// New node
n := ethutil.NewValue(node)
- if node == nil || (n.Type() == reflect.String && (n.Str() == "" || n.Get(0).IsNil())) || n.Len() == 0 {
+ if node == nil || n.Len() == 0 {
+ //if node == nil || (n.Type() == reflect.String && (n.Str() == "" || n.Get(0).IsNil())) || n.Len() == 0 {
newNode := []interface{}{CompactEncode(key), value}
return t.Put(newNode)
@@ -393,13 +394,17 @@ func (t *Trie) InsertState(node interface{}, key []int, value interface{}) inter
func (t *Trie) deleteState(node interface{}, key []int) interface{} {
if len(key) == 0 {
+ println("<empty ret>")
return ""
}
// New node
n := ethutil.NewValue(node)
- if node == nil || (n.Type() == reflect.String && (n.Str() == "" || n.Get(0).IsNil())) || n.Len() == 0 {
+ //if node == nil || (n.Type() == reflect.String && (n.Str() == "" || n.Get(0).IsNil())) || n.Len() == 0 {
+ if node == nil || n.Len() == 0 {
//return nil
+ //fmt.Printf("<empty ret> %x %d\n", n, len(n.Bytes()))
+
return ""
}
@@ -410,17 +415,19 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
k := CompactDecode(currentNode.Get(0).Str())
v := currentNode.Get(1).Raw()
- matchingLength := MatchingNibbleLength(key, k)
-
// Matching key pair (ie. there's already an object with this key)
if CompareIntSlice(k, key) {
+ //fmt.Printf("<delete ret> %x\n", v)
+
return ""
- } else if CompareIntSlice(key[:matchingLength], k) {
+ } else if CompareIntSlice(key[:len(k)], k) {
hash := t.deleteState(v, key[len(k):])
child := t.getNode(hash)
- if child.IsNil() {
- return node
- }
+ /*
+ if child.IsNil() {
+ return node
+ }
+ */
var newNode []interface{}
if child.Len() == 2 {
@@ -430,6 +437,8 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
newNode = []interface{}{currentNode.Get(0).Str(), hash}
}
+ //fmt.Printf("%x\n", newNode)
+
return t.Put(newNode)
} else {
return node
@@ -472,10 +481,11 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
newNode = n
}
+ //fmt.Printf("%x\n", newNode)
return t.Put(newNode)
}
- return ""
+ panic("unexpected return")
}
type TrieIterator struct {
diff --git a/ethtrie/trie_test.go b/ethtrie/trie_test.go
index f39477ff9..3989a8f45 100644
--- a/ethtrie/trie_test.go
+++ b/ethtrie/trie_test.go
@@ -1,17 +1,17 @@
package ethtrie
import (
- "bytes"
- "encoding/hex"
- "encoding/json"
+ _ "bytes"
+ _ "encoding/hex"
+ _ "encoding/json"
"fmt"
"github.com/ethereum/eth-go/ethutil"
- "io/ioutil"
- "math/rand"
- "net/http"
- "reflect"
+ _ "io/ioutil"
+ _ "math/rand"
+ _ "net/http"
+ _ "reflect"
"testing"
- "time"
+ _ "time"
)
const LONG_WORD = "1234567890abcdefghijklmnopqrstuvwxxzABCEFGHIJKLMNOPQRSTUVWXYZ"
@@ -43,6 +43,7 @@ func New() (*MemDatabase, *Trie) {
return db, NewTrie(db, "")
}
+/*
func TestTrieSync(t *testing.T) {
db, trie := New()
@@ -365,3 +366,55 @@ func TestDelete(t *testing.T) {
fmt.Printf("o: %x\nc: %x\n", a, b)
}
+*/
+
+func TestRndCase(t *testing.T) {
+ _, trie := New()
+
+ data := []struct{ k, v string }{
+ {"0000000000000000000000000000000000000000000000000000000000000001", "a07573657264617461000000000000000000000000000000000000000000000000"},
+ {"0000000000000000000000000000000000000000000000000000000000000003", "8453bb5b31"},
+ {"0000000000000000000000000000000000000000000000000000000000000004", "850218711a00"},
+ {"0000000000000000000000000000000000000000000000000000000000000005", "9462d7705bd0b3ecbc51a8026a25597cb28a650c79"},
+ {"0000000000000000000000000000000000000000000000000000000000000010", "947e70f9460402290a3e487dae01f610a1a8218fda"},
+ {"0000000000000000000000000000000000000000000000000000000000000111", "01"},
+ {"0000000000000000000000000000000000000000000000000000000000000112", "a053656e6174650000000000000000000000000000000000000000000000000000"},
+ {"0000000000000000000000000000000000000000000000000000000000000113", "a053656e6174650000000000000000000000000000000000000000000000000000"},
+ {"53656e6174650000000000000000000000000000000000000000000000000000", "94977e3f62f5e1ed7953697430303a3cfa2b5b736e"},
+ }
+ for _, e := range data {
+ trie.Update(string(ethutil.Hex2Bytes(e.k)), string(ethutil.Hex2Bytes(e.v)))
+ }
+
+ fmt.Printf("root after update %x\n", trie.Root)
+ trie.NewIterator().Each(func(k string, v *ethutil.Value) {
+ fmt.Printf("%x %x\n", k, v.Bytes())
+ })
+
+ data = []struct{ k, v string }{
+ {"0000000000000000000000000000000000000000000000000000000000000112", ""},
+ {"436974697a656e73000000000000000000000000000000000000000000000001", ""},
+ {"436f757274000000000000000000000000000000000000000000000000000002", ""},
+ {"53656e6174650000000000000000000000000000000000000000000000000000", ""},
+ {"436f757274000000000000000000000000000000000000000000000000000000", ""},
+ {"53656e6174650000000000000000000000000000000000000000000000000001", ""},
+ {"0000000000000000000000000000000000000000000000000000000000000113", ""},
+ {"436974697a656e73000000000000000000000000000000000000000000000000", ""},
+ {"436974697a656e73000000000000000000000000000000000000000000000002", ""},
+ {"436f757274000000000000000000000000000000000000000000000000000001", ""},
+ {"0000000000000000000000000000000000000000000000000000000000000111", ""},
+ {"53656e6174650000000000000000000000000000000000000000000000000002", ""},
+ }
+
+ for _, e := range data {
+ trie.Delete(string(ethutil.Hex2Bytes(e.k)))
+ }
+
+ fmt.Printf("root after delete %x\n", trie.Root)
+
+ trie.NewIterator().Each(func(k string, v *ethutil.Value) {
+ fmt.Printf("%x %x\n", k, v.Bytes())
+ })
+
+ fmt.Printf("%x\n", trie.Get(string(ethutil.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"))))
+}
diff --git a/ethutil/bytes.go b/ethutil/bytes.go
index 07584d0bf..d16bd6780 100644
--- a/ethutil/bytes.go
+++ b/ethutil/bytes.go
@@ -150,12 +150,16 @@ func LeftPadBytes(slice []byte, l int) []byte {
return padded
}
-func Address(slice []byte) []byte {
+func Address(slice []byte) (addr []byte) {
if len(slice) < 20 {
- slice = LeftPadBytes(slice, 20)
+ addr = LeftPadBytes(slice, 20)
} else if len(slice) > 20 {
- slice = slice[len(slice)-20:]
+ addr = slice[len(slice)-20:]
+ } else {
+ addr = slice
}
- return slice
+ addr = CopyBytes(addr)
+
+ return
}
diff --git a/ethutil/value.go b/ethutil/value.go
index ecb9d1511..fba7426d1 100644
--- a/ethutil/value.go
+++ b/ethutil/value.go
@@ -40,13 +40,9 @@ func (val *Value) Len() int {
//return val.kind.Len()
if data, ok := val.Val.([]interface{}); ok {
return len(data)
- } else if data, ok := val.Val.([]byte); ok {
- return len(data)
- } else if data, ok := val.Val.(string); ok {
- return len(data)
}
- return 0
+ return len(val.Bytes())
}
func (val *Value) Raw() interface{} {
@@ -118,6 +114,8 @@ func (val *Value) Bytes() []byte {
return []byte{s}
} else if s, ok := val.Val.(string); ok {
return []byte(s)
+ } else if s, ok := val.Val.(*big.Int); ok {
+ return s.Bytes()
}
return []byte{}