Trie fixes

This commit is contained in:
obscuren
2014-07-17 11:21:18 +02:00
parent 14c4f06100
commit ed3424ff75
8 changed files with 129 additions and 38 deletions
+20 -10
View File
@@ -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 {
+61 -8
View File
@@ -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"))))
}