diff options
author | obscuren <geffobscura@gmail.com> | 2015-02-03 11:58:34 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2015-02-03 11:58:34 +0800 |
commit | 3c7181d28f1f24aaea2da5cce664ffac52f369df (patch) | |
tree | 36e229ec95e89287e6d1add6ab587a90f8960041 /trie/trie.go | |
parent | 6fecb150d6f2bb36d3f1b7b9095cac428df2ce5a (diff) | |
download | dexon-3c7181d28f1f24aaea2da5cce664ffac52f369df.tar.gz dexon-3c7181d28f1f24aaea2da5cce664ffac52f369df.tar.zst dexon-3c7181d28f1f24aaea2da5cce664ffac52f369df.zip |
Fixed a copy issue in the trie which could cause a consensus failure
Diffstat (limited to 'trie/trie.go')
-rw-r--r-- | trie/trie.go | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/trie/trie.go b/trie/trie.go index 36f2af5d2..9087f7bda 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -34,7 +34,9 @@ func New(root []byte, backend Backend) *Trie { trie := &Trie{} trie.revisions = list.New() trie.roothash = root - trie.cache = NewCache(backend) + if backend != nil { + trie.cache = NewCache(backend) + } if root != nil { value := ethutil.NewValueFromBytes(trie.cache.Get(root)) @@ -49,7 +51,15 @@ func (self *Trie) Iterator() *Iterator { } func (self *Trie) Copy() *Trie { - return New(self.roothash, self.cache.backend) + cpy := make([]byte, 32) + copy(cpy, self.roothash) + trie := New(nil, nil) + trie.cache = self.cache.Copy() + if self.root != nil { + trie.root = self.root.Copy(trie) + } + + return trie } // Legacy support @@ -177,7 +187,7 @@ func (self *Trie) insert(node Node, key []byte, value Node) Node { return NewShortNode(self, key[:matchlength], n) case *FullNode: - cpy := node.Copy().(*FullNode) + cpy := node.Copy(self).(*FullNode) cpy.set(key[0], self.insert(node.branch(key[0]), key[1:], value)) return cpy @@ -244,7 +254,7 @@ func (self *Trie) delete(node Node, key []byte) Node { } case *FullNode: - n := node.Copy().(*FullNode) + n := node.Copy(self).(*FullNode) n.set(key[0], self.delete(n.branch(key[0]), key[1:])) pos := -1 @@ -301,7 +311,7 @@ func (self *Trie) mknode(value *ethutil.Value) Node { } return fnode case 32: - return &HashNode{value.Bytes()} + return &HashNode{value.Bytes(), self} } return &ValueNode{self, value.Bytes()} @@ -331,4 +341,5 @@ func (self *Trie) store(node Node) interface{} { func (self *Trie) PrintRoot() { fmt.Println(self.root) + fmt.Printf("root=%x\n", self.Root()) } |