diff --git a/db_query_interface.go b/db_query_interface.go new file mode 100644 index 000000000..1bcf1e72d --- /dev/null +++ b/db_query_interface.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "bufio" + "strings" + "os" + "errors" + "encoding/hex" +) + +type DbInterface struct { + db *MemDatabase + trie *Trie +} + +func NewDBInterface() *DbInterface { + db, _ := NewMemDatabase() + trie := NewTrie(db, "") + + return &DbInterface{db: db, trie: trie} +} + +func (i *DbInterface) 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 == "quit" || action == "exit") && argumentLength != 0: + err = true + expArgCount = 0 + } + + if err { + return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength)) + } else { + return nil + } +} + +func (i *DbInterface) 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 "exit", "quit", "q": + return false + default: + fmt.Println("Unknown command:", tokens[0]) + } + } + + return true +} + +func (i *DbInterface) Start() { + reader := bufio.NewReader(os.Stdin) + for { + fmt.Printf("db >>> ") + str, _, err := reader.ReadLine() + if err != nil { + fmt.Println("Error reading input", err) + } else { + if !i.ParseInput(string(str)) { + return + } + } + } +} diff --git a/memory_database.go b/memory_database.go new file mode 100644 index 000000000..fc40f76f3 --- /dev/null +++ b/memory_database.go @@ -0,0 +1,25 @@ +package main + +import ( +) + +/* + * This is a test memory database. Do not use for any production it does not get persisted + */ +type MemDatabase struct { + db map[string][]byte +} + +func NewMemDatabase() (*MemDatabase, error) { + db := &MemDatabase{db: make(map[string][]byte)} + + return db, nil +} + +func (db *MemDatabase) Put(key []byte, value []byte) { + db.db[string(key)] = value +} + +func (db *MemDatabase) Get(key []byte) ([]byte, error) { + return db.db[string(key)], nil +} diff --git a/testing.go b/testing.go new file mode 100644 index 000000000..5d0b818a9 --- /dev/null +++ b/testing.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" +) + +func Testing() { + bm := NewBlockManager() + + tx := NewTransaction("\x00", 20, []string{ + "SET 10 6", + "LD 10 10", + "LT 10 1 20", + "SET 255 7", + "JMPI 20 255", + "STOP", + "SET 30 200", + "LD 30 31", + "SET 255 22", + "JMPI 31 255", + "SET 255 15", + "JMP 255", + }) + txData := tx.MarshalRlp() + + copyTx := &Transaction{} + copyTx.UnmarshalRlp(txData) + + tx2 := NewTransaction("\x00", 20, []string{"SET 10 6", "LD 10 10"}) + + blck := CreateBlock([]*Transaction{tx2, tx}) + + bm.ProcessBlock( blck ) + + fmt.Println("GenesisBlock:", GenisisBlock, "hashed", GenisisBlock.Hash()) +}