mirror of https://github.com/ethereum/go-ethereum
parent
ad048e9f44
commit
a926686445
@ -0,0 +1,94 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"path" |
||||
"os/user" |
||||
"github.com/syndtr/goleveldb/leveldb" |
||||
"fmt" |
||||
) |
||||
|
||||
type Database struct { |
||||
db *leveldb.DB |
||||
trie *Trie |
||||
} |
||||
|
||||
func NewDatabase() (*Database, error) { |
||||
// This will eventually have to be something like a resource folder.
|
||||
// it works on my system for now. Probably won't work on Windows
|
||||
usr, _ := user.Current() |
||||
dbPath := path.Join(usr.HomeDir, ".ethereum", "database") |
||||
|
||||
// Open the db
|
||||
db, err := leveldb.OpenFile(dbPath, nil) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
database := &Database{db: db} |
||||
|
||||
// Bootstrap database. Sets a few defaults; such as the last block
|
||||
database.Bootstrap() |
||||
|
||||
return database, nil |
||||
} |
||||
|
||||
func (db *Database) Bootstrap() error { |
||||
db.trie = NewTrie(db) |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func (db *Database) Put(key []byte, value []byte) { |
||||
err := db.db.Put(key, value, nil) |
||||
if err != nil { |
||||
fmt.Println("Error put", err) |
||||
} |
||||
} |
||||
|
||||
func (db *Database) Close() { |
||||
// Close the leveldb database
|
||||
db.db.Close() |
||||
} |
||||
|
||||
type Trie struct { |
||||
root string |
||||
db *Database |
||||
} |
||||
|
||||
func NewTrie(db *Database) *Trie { |
||||
return &Trie{db: db, root: ""} |
||||
} |
||||
|
||||
func (t *Trie) Update(key string, value string) { |
||||
k := CompactHexDecode(key) |
||||
|
||||
t.root = t.UpdateState(t.root, k, value) |
||||
} |
||||
|
||||
func (t *Trie) Get(key []byte) ([]byte, error) { |
||||
return nil, nil |
||||
} |
||||
|
||||
// Inserts a new sate or delete a state based on the value
|
||||
func (t *Trie) UpdateState(node, key, value string) string { |
||||
if value != "" { |
||||
return t.InsertState(node, key, value) |
||||
} else { |
||||
// delete it
|
||||
} |
||||
|
||||
return "" |
||||
} |
||||
|
||||
func (t *Trie) InsertState(node, key, value string) string { |
||||
return "" |
||||
} |
||||
|
||||
func (t *Trie) Put(node []byte) []byte { |
||||
enc := Encode(node) |
||||
sha := Sha256Bin(enc) |
||||
|
||||
t.db.Put([]byte(sha), enc) |
||||
|
||||
return sha |
||||
} |
@ -0,0 +1,43 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"testing" |
||||
_"fmt" |
||||
) |
||||
|
||||
func TestTriePut(t *testing.T) { |
||||
db, err := NewDatabase() |
||||
defer db.Close() |
||||
|
||||
if err != nil { |
||||
t.Error("Error starting db") |
||||
} |
||||
|
||||
key := db.trie.Put([]byte("testing node")) |
||||
|
||||
data, err := db.db.Get(key, nil) |
||||
if err != nil { |
||||
t.Error("Nothing at node") |
||||
} |
||||
|
||||
s, _ := Decode(data, 0) |
||||
if str, ok := s.([]byte); ok { |
||||
if string(str) != "testing node" { |
||||
t.Error("Wrong value node", str) |
||||
} |
||||
} else { |
||||
t.Error("Invalid return type") |
||||
} |
||||
} |
||||
|
||||
func TestTrieUpdate(t *testing.T) { |
||||
db, err := NewDatabase() |
||||
defer db.Close() |
||||
|
||||
if err != nil { |
||||
t.Error("Error starting db") |
||||
} |
||||
|
||||
db.trie.Update("test", "test") |
||||
} |
||||
|
@ -0,0 +1,36 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"math" |
||||
) |
||||
|
||||
/* |
||||
* This is the special genesis block. |
||||
*/ |
||||
|
||||
var GenisisHeader = []interface{}{ |
||||
// Block number
|
||||
uint32(0), |
||||
// Previous hash (none)
|
||||
"", |
||||
// Sha of uncles
|
||||
string(Sha256Bin(Encode([]interface{}{}))), |
||||
// Coinbase
|
||||
"", |
||||
// Root state
|
||||
"", |
||||
// Sha of transactions
|
||||
string(Sha256Bin(Encode([]interface{}{}))), |
||||
// Difficulty
|
||||
uint32(math.Pow(2, 36)), |
||||
// Time
|
||||
uint64(1), |
||||
// Nonce
|
||||
uint32(0), |
||||
// Extra
|
||||
"", |
||||
} |
||||
|
||||
var Genesis = []interface{}{ GenisisHeader, []interface{}{}, []interface{}{} } |
||||
|
||||
var GenisisBlock = NewBlock( Encode(Genesis) ) |
@ -0,0 +1,55 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"container/list" |
||||
"time" |
||||
) |
||||
|
||||
type Server struct { |
||||
// Channel for shutting down the server
|
||||
shutdownChan chan bool |
||||
// DB interface
|
||||
db *Database |
||||
// Peers (NYI)
|
||||
peers *list.List |
||||
} |
||||
|
||||
func NewServer() (*Server, error) { |
||||
db, err := NewDatabase() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
server := &Server{ |
||||
shutdownChan: make(chan bool), |
||||
db: db, |
||||
peers: list.New(), |
||||
} |
||||
|
||||
return server, nil |
||||
} |
||||
|
||||
// Start the server
|
||||
func (s *Server) Start() { |
||||
// For now this function just blocks the main thread
|
||||
for { |
||||
time.Sleep( time.Second ) |
||||
} |
||||
} |
||||
|
||||
func (s *Server) Stop() { |
||||
// Close the database
|
||||
defer s.db.Close() |
||||
|
||||
// Loop thru the peers and close them (if we had them)
|
||||
for e := s.peers.Front(); e != nil; e = e.Next() { |
||||
// peer close etc
|
||||
} |
||||
|
||||
s.shutdownChan <- true |
||||
} |
||||
|
||||
// This function will wait for a shutdown and resumes main thread execution
|
||||
func (s *Server) WaitForShutdown() { |
||||
<- s.shutdownChan |
||||
} |
Loading…
Reference in new issue