aboutsummaryrefslogtreecommitdiffstats
path: root/dev_console.go
blob: 923c483c2feadb9a94935b080f1bf47b79c90c6d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package main

import (
    "bufio"
    "encoding/hex"
    "errors"
    "fmt"
    "github.com/ethereum/ethdb-go"
    "github.com/ethereum/ethutil-go"
    "os"
    "strings"
)

type Console struct {
    db   *ethdb.MemDatabase
    trie *ethutil.Trie
}

func NewConsole() *Console {
    db, _ := ethdb.NewMemDatabase()
    trie := ethutil.NewTrie(db, "")

    return &Console{db: db, trie: trie}
}

func (i *Console) ValidateInput(action string, argumentLength int) error {
    err := false
    var expArgCount int

    switch {
    case action == "update" && argumentLength != 2:
        err = true
        expArgCount = 2
    case action == "get" && argumentLength != 1:
        err = true
        expArgCount = 1
    case action == "dag" && argumentLength != 2:
        err = true
        expArgCount = 2
    }

    if err {
        return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength))
    } else {
        return nil
    }
}

func (i *Console) ParseInput(input string) bool {
    scanner := bufio.NewScanner(strings.NewReader(input))
    scanner.Split(bufio.ScanWords)

    count := 0
    var tokens []string
    for scanner.Scan() {
        count++
        tokens = append(tokens, scanner.Text())
    }
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "reading input:", err)
    }

    if len(tokens) == 0 {
        return true
    }

    err := i.ValidateInput(tokens[0], count-1)
    if err != nil {
        fmt.Println(err)
    } else {
        switch tokens[0] {
        case "update":
            i.trie.Update(tokens[1], tokens[2])

            fmt.Println(hex.EncodeToString([]byte(i.trie.Root)))
        case "get":
            fmt.Println(i.trie.Get(tokens[1]))
        case "root":
            fmt.Println(hex.EncodeToString([]byte(i.trie.Root)))
        case "rawroot":
            fmt.Println(i.trie.Root)
        case "print":
            i.db.Print()
        case "dag":
            fmt.Println(DaggerVerify(ethutil.Big(tokens[1]), // hash
                ethutil.BigPow(2, 36),   // diff
                ethutil.Big(tokens[2]))) // nonce
        case "exit", "quit", "q":
            return false
        case "help":
            fmt.Printf("COMMANDS:\n" +
                "\033[1m= DB =\033[0m\n" +
                "update KEY VALUE - Updates/Creates a new value for the given key\n" +
                "get KEY - Retrieves the given key\n" +
                "root - Prints the hex encoded merkle root\n" +
                "rawroot - Prints the raw merkle root\n" +
                "\033[1m= Dagger =\033[0m\n" +
                "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n")
        default:
            fmt.Println("Unknown command:", tokens[0])
        }
    }

    return true
}

func (i *Console) Start() {
    fmt.Printf("Eth Console. Type (help) for help\n")
    reader := bufio.NewReader(os.Stdin)
    for {
        fmt.Printf("eth >>> ")
        str, _, err := reader.ReadLine()
        if err != nil {
            fmt.Println("Error reading input", err)
        } else {
            if !i.ParseInput(string(str)) {
                return
            }
        }
    }
}