aboutsummaryrefslogtreecommitdiffstats
path: root/ethutil
diff options
context:
space:
mode:
Diffstat (limited to 'ethutil')
-rw-r--r--ethutil/db.go1
-rw-r--r--ethutil/parsing.go102
-rw-r--r--ethutil/parsing_test.go4
-rw-r--r--ethutil/trie.go85
-rw-r--r--ethutil/trie_test.go24
5 files changed, 163 insertions, 53 deletions
diff --git a/ethutil/db.go b/ethutil/db.go
index 3681c4b05..b11d5d726 100644
--- a/ethutil/db.go
+++ b/ethutil/db.go
@@ -4,6 +4,7 @@ package ethutil
type Database interface {
Put(key []byte, value []byte)
Get(key []byte) ([]byte, error)
+ Delete(key []byte) error
LastKnownTD() []byte
Close()
Print()
diff --git a/ethutil/parsing.go b/ethutil/parsing.go
index b43dac064..553bb9717 100644
--- a/ethutil/parsing.go
+++ b/ethutil/parsing.go
@@ -7,57 +7,57 @@ import (
// Op codes
var OpCodes = map[string]byte{
- "STOP": 0,
- "ADD": 1,
- "MUL": 2,
- "SUB": 3,
- "DIV": 4,
- "SDIV": 5,
- "MOD": 6,
- "SMOD": 7,
- "EXP": 8,
- "NEG": 9,
- "LT": 10,
- "LE": 11,
- "GT": 12,
- "GE": 13,
- "EQ": 14,
- "NOT": 15,
- "MYADDRESS": 16,
- "TXSENDER": 17,
- "TXVALUE": 18,
- "TXFEE": 19,
- "TXDATAN": 20,
- "TXDATA": 21,
- "BLK_PREVHASH": 22,
- "BLK_COINBASE": 23,
- "BLK_TIMESTAMP": 24,
- "BLK_NUMBER": 25,
- "BLK_DIFFICULTY": 26,
- "BASEFEE": 27,
- "SHA256": 32,
- "RIPEMD160": 33,
- "ECMUL": 34,
- "ECADD": 35,
- "ECSIGN": 36,
- "ECRECOVER": 37,
- "ECVALID": 38,
- "SHA3": 39,
- "PUSH": 48,
- "POP": 49,
- "DUP": 50,
- "SWAP": 51,
- "MLOAD": 52,
- "MSTORE": 53,
- "SLOAD": 54,
- "SSTORE": 55,
- "JMP": 56,
- "JMPI": 57,
- "IND": 58,
- "EXTRO": 59,
- "BALANCE": 60,
- "MKTX": 61,
- "SUICIDE": 62,
+ "STOP": 0x00,
+ "ADD": 0x01,
+ "MUL": 0x02,
+ "SUB": 0x03,
+ "DIV": 0x04,
+ "SDIV": 0x05,
+ "MOD": 0x06,
+ "SMOD": 0x07,
+ "EXP": 0x08,
+ "NEG": 0x09,
+ "LT": 0x0a,
+ "LE": 0x0b,
+ "GT": 0x0c,
+ "GE": 0x0d,
+ "EQ": 0x0e,
+ "NOT": 0x0f,
+ "MYADDRESS": 0x10,
+ "TXSENDER": 0x11,
+ "TXVALUE": 0x12,
+ "TXDATAN": 0x13,
+ "TXDATA": 0x14,
+ "BLK_PREVHASH": 0x15,
+ "BLK_COINBASE": 0x16,
+ "BLK_TIMESTAMP": 0x17,
+ "BLK_NUMBER": 0x18,
+ "BLK_DIFFICULTY": 0x19,
+ "BLK_NONCE": 0x1a,
+ "BASEFEE": 0x1b,
+ "SHA256": 0x20,
+ "RIPEMD160": 0x21,
+ "ECMUL": 0x22,
+ "ECADD": 0x23,
+ "ECSIGN": 0x24,
+ "ECRECOVER": 0x25,
+ "ECVALID": 0x26,
+ "SHA3": 0x27,
+ "PUSH": 0x30,
+ "POP": 0x31,
+ "DUP": 0x32,
+ "SWAP": 0x33,
+ "MLOAD": 0x34,
+ "MSTORE": 0x35,
+ "SLOAD": 0x36,
+ "SSTORE": 0x37,
+ "JMP": 0x38,
+ "JMPI": 0x39,
+ "IND": 0x3a,
+ "EXTRO": 0x3b,
+ "BALANCE": 0x3c,
+ "MKTX": 0x3d,
+ "SUICIDE": 0x3f,
}
func IsOpCode(s string) bool {
diff --git a/ethutil/parsing_test.go b/ethutil/parsing_test.go
index 69a5e9016..6b59777e6 100644
--- a/ethutil/parsing_test.go
+++ b/ethutil/parsing_test.go
@@ -1,5 +1,6 @@
package ethutil
+/*
import (
"math"
"testing"
@@ -19,14 +20,13 @@ func TestCompile(t *testing.T) {
}
func TestValidInstr(t *testing.T) {
- /*
op, args, err := Instr("68163")
if err != nil {
t.Error("Error decoding instruction")
}
- */
}
func TestInvalidInstr(t *testing.T) {
}
+*/
diff --git a/ethutil/trie.go b/ethutil/trie.go
index 322f77647..83527d364 100644
--- a/ethutil/trie.go
+++ b/ethutil/trie.go
@@ -70,6 +70,12 @@ func (cache *Cache) Get(key []byte) *Value {
return value
}
+func (cache *Cache) Delete(key []byte) {
+ delete(cache.nodes, string(key))
+
+ cache.db.Delete(key)
+}
+
func (cache *Cache) Commit() {
// Don't try to commit if it isn't dirty
if !cache.IsDirty {
@@ -413,3 +419,82 @@ func (t *Trie) Copy() *Trie {
return trie
}
+
+type TrieIterator struct {
+ trie *Trie
+ key string
+ value string
+
+ shas [][]byte
+ values []string
+}
+
+func (t *Trie) NewIterator() *TrieIterator {
+ return &TrieIterator{trie: t}
+}
+
+// Some time in the near future this will need refactoring :-)
+// XXX Note to self, IsSlice == inline node. Str == sha3 to node
+func (it *TrieIterator) workNode(currentNode *Value) {
+ if currentNode.Len() == 2 {
+ k := CompactDecode(currentNode.Get(0).Str())
+
+ if currentNode.Get(1).IsSlice() {
+ it.workNode(currentNode.Get(1))
+ } else {
+ if k[len(k)-1] == 16 {
+ it.values = append(it.values, currentNode.Get(1).Str())
+ } else {
+ it.shas = append(it.shas, currentNode.Get(1).Bytes())
+ it.getNode(currentNode.Get(1).Bytes())
+ }
+ }
+ } else {
+ for i := 0; i < currentNode.Len(); i++ {
+ if i == 16 && currentNode.Get(i).Len() != 0 {
+ it.values = append(it.values, currentNode.Get(i).Str())
+ } else {
+ if currentNode.Get(i).IsSlice() {
+ it.workNode(currentNode.Get(i))
+ } else {
+ val := currentNode.Get(i).Str()
+ if val != "" {
+ it.shas = append(it.shas, currentNode.Get(1).Bytes())
+ it.getNode([]byte(val))
+ }
+ }
+ }
+ }
+ }
+}
+
+func (it *TrieIterator) getNode(node []byte) {
+ currentNode := it.trie.cache.Get(node)
+ it.workNode(currentNode)
+}
+
+func (it *TrieIterator) Collect() [][]byte {
+ if it.trie.Root == "" {
+ return nil
+ }
+
+ it.getNode(NewValue(it.trie.Root).Bytes())
+
+ return it.shas
+}
+
+func (it *TrieIterator) Purge() int {
+ shas := it.Collect()
+ for _, sha := range shas {
+ it.trie.cache.Delete(sha)
+ }
+ return len(it.values)
+}
+
+func (it *TrieIterator) Key() string {
+ return ""
+}
+
+func (it *TrieIterator) Value() string {
+ return ""
+}
diff --git a/ethutil/trie_test.go b/ethutil/trie_test.go
index 9d2c8e19f..c3a8f224d 100644
--- a/ethutil/trie_test.go
+++ b/ethutil/trie_test.go
@@ -1,6 +1,7 @@
package ethutil
import (
+ "fmt"
"reflect"
"testing"
)
@@ -21,6 +22,10 @@ func (db *MemDatabase) Put(key []byte, value []byte) {
func (db *MemDatabase) Get(key []byte) ([]byte, error) {
return db.db[string(key)], nil
}
+func (db *MemDatabase) Delete(key []byte) error {
+ delete(db.db, string(key))
+ return nil
+}
func (db *MemDatabase) Print() {}
func (db *MemDatabase) Close() {}
func (db *MemDatabase) LastKnownTD() []byte { return nil }
@@ -148,3 +153,22 @@ func TestTrieDeleteWithValue(t *testing.T) {
}
}
+
+func TestTrieIterator(t *testing.T) {
+ _, trie := New()
+ trie.Update("c", LONG_WORD)
+ trie.Update("ca", LONG_WORD)
+ trie.Update("cat", LONG_WORD)
+
+ it := trie.NewIterator()
+ fmt.Println("purging")
+ fmt.Println("len =", it.Purge())
+ /*
+ for it.Next() {
+ k := it.Key()
+ v := it.Value()
+
+ fmt.Println(k, v)
+ }
+ */
+}