Commit 9571a512 authored by obscuren's avatar obscuren

gofmt no coding standards

parent 8bbf879c
......@@ -21,3 +21,8 @@ Command line options
-c launch the developer console
-m start mining fake blocks and broadcast fake messages to the net
Contribution
============
See CONTRIB.md
package main
import (
"fmt"
"github.com/ethereum/ethutil-go"
"fmt"
"github.com/ethereum/ethutil-go"
)
type BlockChain struct {
lastBlock *ethutil.Block
lastBlock *ethutil.Block
genesisBlock *ethutil.Block
genesisBlock *ethutil.Block
}
func NewBlockChain() *BlockChain {
bc := &BlockChain{}
bc.genesisBlock = ethutil.NewBlock( ethutil.Encode(ethutil.Genesis) )
bc := &BlockChain{}
bc.genesisBlock = ethutil.NewBlock(ethutil.Encode(ethutil.Genesis))
return bc
return bc
}
type BlockManager struct {
vm *Vm
vm *Vm
blockChain *BlockChain
blockChain *BlockChain
}
func NewBlockManager() *BlockManager {
bm := &BlockManager{vm: NewVm()}
bm := &BlockManager{vm: NewVm()}
return bm
return bm
}
// Process a block.
func (bm *BlockManager) ProcessBlock(block *ethutil.Block) error {
// TODO Validation (Or move to other part of the application)
if err := bm.ValidateBlock(block); err != nil {
return err
}
// Get the tx count. Used to create enough channels to 'join' the go routines
txCount := len(block.Transactions())
// Locking channel. When it has been fully buffered this method will return
lockChan := make(chan bool, txCount)
// Process each transaction/contract
for _, tx := range block.Transactions() {
// If there's no recipient, it's a contract
if tx.IsContract() {
go bm.ProcessContract(tx, block, lockChan)
} else {
// "finish" tx which isn't a contract
lockChan <- true
}
}
// Wait for all Tx to finish processing
for i := 0; i < txCount; i++ {
<- lockChan
}
return nil
// TODO Validation (Or move to other part of the application)
if err := bm.ValidateBlock(block); err != nil {
return err
}
// Get the tx count. Used to create enough channels to 'join' the go routines
txCount := len(block.Transactions())
// Locking channel. When it has been fully buffered this method will return
lockChan := make(chan bool, txCount)
// Process each transaction/contract
for _, tx := range block.Transactions() {
// If there's no recipient, it's a contract
if tx.IsContract() {
go bm.ProcessContract(tx, block, lockChan)
} else {
// "finish" tx which isn't a contract
lockChan <- true
}
}
// Wait for all Tx to finish processing
for i := 0; i < txCount; i++ {
<-lockChan
}
return nil
}
func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error {
return nil
return nil
}
func (bm *BlockManager) ProcessContract(tx *ethutil.Transaction, block *ethutil.Block, lockChan chan bool) {
// Recovering function in case the VM had any errors
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from VM execution with err =", r)
// Let the channel know where done even though it failed (so the execution may resume normally)
lockChan <- true
}
}()
// Process contract
bm.vm.ProcContract(tx, block, func(opType OpType) bool {
// TODO turn on once big ints are in place
//if !block.PayFee(tx.Hash(), StepFee.Uint64()) {
// return false
//}
return true // Continue
})
// Broadcast we're done
lockChan <- true
// Recovering function in case the VM had any errors
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from VM execution with err =", r)
// Let the channel know where done even though it failed (so the execution may resume normally)
lockChan <- true
}
}()
// Process contract
bm.vm.ProcContract(tx, block, func(opType OpType) bool {
// TODO turn on once big ints are in place
//if !block.PayFee(tx.Hash(), StepFee.Uint64()) {
// return false
//}
return true // Continue
})
// Broadcast we're done
lockChan <- true
}
package main
import (
"math/big"
"math/rand"
"time"
"github.com/obscuren/sha3"
"hash"
"github.com/ethereum/ethutil-go"
"github.com/ethereum/ethutil-go"
"github.com/obscuren/sha3"
"hash"
"math/big"
"math/rand"
"time"
)
type Dagger struct {
hash *big.Int
xn *big.Int
hash *big.Int
xn *big.Int
}
var Found bool
func (dag *Dagger) Find(obj *big.Int, resChan chan int64) {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < 1000; i++ {
rnd := r.Int63()
for i := 0; i < 1000; i++ {
rnd := r.Int63()
if dag.Eval(big.NewInt(rnd)).Cmp(obj) < 0 {
// Post back result on the channel
resChan <- rnd
// Notify other threads we've found a valid nonce
Found = true
}
if dag.Eval(big.NewInt(rnd)).Cmp(obj) < 0 {
// Post back result on the channel
resChan <- rnd
// Notify other threads we've found a valid nonce
Found = true
}
// Break out if found
if Found { break }
}
// Break out if found
if Found {
break
}
}
resChan <- 0
resChan <- 0
}
func (dag *Dagger) Search(hash, diff *big.Int) *big.Int {
// TODO fix multi threading. Somehow it results in the wrong nonce
amountOfRoutines := 1
// TODO fix multi threading. Somehow it results in the wrong nonce
amountOfRoutines := 1
dag.hash = hash
dag.hash = hash
obj := ethutil.BigPow(2, 256)
obj = obj.Div(obj, diff)
obj := ethutil.BigPow(2, 256)
obj = obj.Div(obj, diff)
Found = false
resChan := make(chan int64, 3)
var res int64
Found = false
resChan := make(chan int64, 3)
var res int64
for k := 0; k < amountOfRoutines; k++ {
go dag.Find(obj, resChan)
}
for k := 0; k < amountOfRoutines; k++ {
go dag.Find(obj, resChan)
}
// Wait for each go routine to finish
for k := 0; k < amountOfRoutines; k++ {
// Get the result from the channel. 0 = quit
if r := <- resChan; r != 0 {
res = r
}
}
// Wait for each go routine to finish
for k := 0; k < amountOfRoutines; k++ {
// Get the result from the channel. 0 = quit
if r := <-resChan; r != 0 {
res = r
}
}
return big.NewInt(res)
return big.NewInt(res)
}
func DaggerVerify(hash, diff, nonce *big.Int) bool {
dagger := &Dagger{}
dagger.hash = hash
dagger := &Dagger{}
dagger.hash = hash
obj := ethutil.BigPow(2, 256)
obj = obj.Div(obj, diff)
obj := ethutil.BigPow(2, 256)
obj = obj.Div(obj, diff)
return dagger.Eval(nonce).Cmp(obj) < 0
return dagger.Eval(nonce).Cmp(obj) < 0
}
func (dag *Dagger) Node(L uint64, i uint64) *big.Int {
if L == i {
return dag.hash
}
var m *big.Int
if L == 9 {
m = big.NewInt(16)
} else {
m = big.NewInt(3)
}
sha := sha3.NewKeccak256()
sha.Reset()
d := sha3.NewKeccak256()
b := new(big.Int)
ret := new(big.Int)
for k := 0; k < int(m.Uint64()); k++ {
d.Reset()
d.Write(dag.hash.Bytes())
d.Write(dag.xn.Bytes())
d.Write(big.NewInt(int64(L)).Bytes())
d.Write(big.NewInt(int64(i)).Bytes())
d.Write(big.NewInt(int64(k)).Bytes())
b.SetBytes(Sum(d))
pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1)
sha.Write(dag.Node(L - 1, pk).Bytes())
}
ret.SetBytes(Sum(sha))
return ret
if L == i {
return dag.hash
}
var m *big.Int
if L == 9 {
m = big.NewInt(16)
} else {
m = big.NewInt(3)
}
sha := sha3.NewKeccak256()
sha.Reset()
d := sha3.NewKeccak256()
b := new(big.Int)
ret := new(big.Int)
for k := 0; k < int(m.Uint64()); k++ {
d.Reset()
d.Write(dag.hash.Bytes())
d.Write(dag.xn.Bytes())
d.Write(big.NewInt(int64(L)).Bytes())
d.Write(big.NewInt(int64(i)).Bytes())
d.Write(big.NewInt(int64(k)).Bytes())
b.SetBytes(Sum(d))
pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1)
sha.Write(dag.Node(L-1, pk).Bytes())
}
ret.SetBytes(Sum(sha))
return ret
}
func Sum(sha hash.Hash) []byte {
in := make([]byte, 32)
return sha.Sum(in)
in := make([]byte, 32)
return sha.Sum(in)
}
func (dag *Dagger) Eval(N *big.Int) *big.Int {
pow := ethutil.BigPow(2, 26)
dag.xn = N.Div(N, pow)
pow := ethutil.BigPow(2, 26)
dag.xn = N.Div(N, pow)
sha := sha3.NewKeccak256()
sha.Reset()
ret := new(big.Int)
sha := sha3.NewKeccak256()
sha.Reset()
ret := new(big.Int)
for k := 0; k < 4; k++ {
d := sha3.NewKeccak256()
b := new(big.Int)
for k := 0; k < 4; k++ {
d := sha3.NewKeccak256()
b := new(big.Int)
d.Reset()
d.Write(dag.hash.Bytes())
d.Write(dag.xn.Bytes())
d.Write(N.Bytes())
d.Write(big.NewInt(int64(k)).Bytes())
d.Reset()
d.Write(dag.hash.Bytes())
d.Write(dag.xn.Bytes())
d.Write(N.Bytes())
d.Write(big.NewInt(int64(k)).Bytes())
b.SetBytes(Sum(d))
pk := (b.Uint64() & 0x1ffffff)
b.SetBytes(Sum(d))
pk := (b.Uint64() & 0x1ffffff)
sha.Write(dag.Node(9, pk).Bytes())
}
sha.Write(dag.Node(9, pk).Bytes())
}
return ret.SetBytes(Sum(sha))
return ret.SetBytes(Sum(sha))
}
package main
import (
"testing"
"math/big"
"math/big"
"testing"
)
func BenchmarkDaggerSearch(b *testing.B) {
hash := big.NewInt(0)
diff := BigPow(2, 36)
o := big.NewInt(0) // nonce doesn't matter. We're only testing against speed, not validity
hash := big.NewInt(0)
diff := BigPow(2, 36)
o := big.NewInt(0) // nonce doesn't matter. We're only testing against speed, not validity
// Reset timer so the big generation isn't included in the benchmark
b.ResetTimer()
// Validate
DaggerVerify(hash, diff, o)
// Reset timer so the big generation isn't included in the benchmark
b.ResetTimer()
// Validate
DaggerVerify(hash, diff, o)
}
package main
import (
"fmt"
"bufio"
"strings"
"os"
"errors"
"encoding/hex"
"github.com/ethereum/ethdb-go"
"github.com/ethereum/ethutil-go"
"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
db *ethdb.MemDatabase
trie *ethutil.Trie
}
func NewConsole() *Console {
db, _ := ethdb.NewMemDatabase()
trie := ethutil.NewTrie(db, "")
db, _ := ethdb.NewMemDatabase()
trie := ethutil.NewTrie(db, "")
return &Console{db: db, trie: trie}
return &Console{db: db, trie: trie}
}
func (i *Console) ValidateInput(action string, argumentLength int) error {
err := false
var expArgCount int
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
}
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
}
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)
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)
}
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 }
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])
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])
}
}
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
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
}
}
}
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
}
}
}
}
package main
import (
"fmt"
"os"
"os/signal"
"flag"
"runtime"
"log"
"github.com/ethereum/ethutil-go"
"flag"
"fmt"
"github.com/ethereum/ethutil-go"
"log"
"os"
"os/signal"
"runtime"
)
const Debug = true
var StartConsole bool
var StartMining bool
func Init() {
flag.BoolVar(&StartConsole, "c", false, "debug and testing console")
flag.BoolVar(&StartMining, "m", false, "start dagger mining")
flag.BoolVar(&StartConsole, "c", false, "debug and testing console")
flag.BoolVar(&StartMining, "m", false, "start dagger mining")
flag.Parse()
flag.Parse()
}
// Register interrupt handlers so we can stop the server
func RegisterInterupts(s *Server) {
// Buffered chan of one is enough
c := make(chan os.Signal, 1)
// Notify about interrupts for now
signal.Notify(c, os.Interrupt)
go func() {
for sig := range c {
fmt.Printf("Shutting down (%v) ... \n", sig)
s.Stop()
}
}()
// Buffered chan of one is enough
c := make(chan os.Signal, 1)
// Notify about interrupts for now
signal.Notify(c, os.Interrupt)
go func() {
for sig := range c {
fmt.Printf("Shutting down (%v) ... \n", sig)
s.Stop()
}
}()
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
ethutil.InitFees()
Init()
if StartConsole {
console := NewConsole()
console.Start()
} else{
log.Println("Starting Ethereum")
server, err := NewServer()
if err != nil {
log.Println(err)
return
}
RegisterInterupts(server)
if StartMining {
log.Println("Mining started")
dagger := &Dagger{}
go func() {
for {
res := dagger.Search(ethutil.Big("0"), ethutil.BigPow(2, 36))
server.Broadcast("block", Encode(res.String()))
}
}()
}
server.Start()
err = server.ConnectToPeer("localhost:12345")
if err != nil {
log.Println(err)
server.Stop()
return
}
// Wait for shutdown
server.WaitForShutdown()
}
runtime.GOMAXPROCS(runtime.NumCPU())
ethutil.InitFees()
Init()
if StartConsole {
console := NewConsole()
console.Start()
} else {
log.Println("Starting Ethereum")
server, err := NewServer()
if err != nil {
log.Println(err)
return
}
RegisterInterupts(server)
if StartMining {
log.Println("Mining started")
dagger := &Dagger{}
go func() {
for {
res := dagger.Search(ethutil.Big("0"), ethutil.BigPow(2, 36))
server.Broadcast("block", Encode(res.String()))
}
}()
}
server.Start()
err = server.ConnectToPeer("localhost:12345")
if err != nil {
log.Println(err)
server.Stop()
return
}
// Wait for shutdown
server.WaitForShutdown()
}
}
package main
import (
"net"
"log"
"github.com/ethereum/ethwire-go"
"github.com/ethereum/ethwire-go"
"log"
"net"
)
type Peer struct {
// Server interface
server *Server
// Net connection
conn net.Conn
// Output queue which is used to communicate and handle messages
outputQueue chan ethwire.InOutMsg
// Quit channel
quit chan bool
// Server interface
server *Server
// Net connection
conn net.Conn
// Output queue which is used to communicate and handle messages
outputQueue chan ethwire.InOutMsg
// Quit channel
quit chan bool
}
func NewPeer(conn net.Conn, server *Server) *Peer {
return &Peer{
outputQueue: make(chan ethwire.InOutMsg, 1), // Buffered chan of 1 is enough
quit: make(chan bool),
return &Peer{
outputQueue: make(chan ethwire.InOutMsg, 1), // Buffered chan of 1 is enough
quit: make(chan bool),
server: server,
conn: conn,
}
server: server,
conn: conn,
}
}
// Outputs any RLP encoded data to the peer
func (p *Peer) QueueMessage(msgType string, data []byte) {
p.outputQueue <- ethwire.InOutMsg{MsgType: msgType, Data: data}
p.outputQueue <- ethwire.InOutMsg{MsgType: msgType, Data: data}
}
// Outbound message handler. Outbound messages are handled here
func (p *Peer) HandleOutbound() {
out:
for {
select {
// Main message queue. All outbound messages are processed through here
case msg := <-p.outputQueue:
// TODO Message checking and handle accordingly
err := ethwire.WriteMessage(p.conn, msg)
if err != nil {
log.Println(err)
// Stop the client if there was an error writing to it
p.Stop()
}
// Break out of the for loop if a quit message is posted
case <- p.quit:
break out
}
}
for {
select {
// Main message queue. All outbound messages are processed through here
case msg := <-p.outputQueue:
// TODO Message checking and handle accordingly
err := ethwire.WriteMessage(p.conn, msg)
if err != nil {
log.Println(err)
// Stop the client if there was an error writing to it
p.Stop()
}
// Break out of the for loop if a quit message is posted
case <-p.quit:
break out
}
}
}
// Inbound handler. Inbound messages are received here and passed to the appropriate methods
func (p *Peer) HandleInbound() {
defer p.Stop()
defer p.Stop()
out:
for {
// Wait for a message from the peer
msg, err := ethwire.ReadMessage(p.conn)
if err != nil {
log.Println(err)
break out
}
// TODO
data, _ := Decode(msg.Data, 0)
log.Printf("%s, %s\n", msg.MsgType, data)
}
// Notify the out handler we're quiting
p.quit <- true
for {
// Wait for a message from the peer
msg, err := ethwire.ReadMessage(p.conn)
if err != nil {
log.Println(err)
break out
}
// TODO
data, _ := Decode(msg.Data, 0)
log.Printf("%s, %s\n", msg.MsgType, data)
}
// Notify the out handler we're quiting
p.quit <- true
}
func (p *Peer) Start() {
// Run the outbound handler in a new goroutine
go p.HandleOutbound()
// Run the inbound handler in a new goroutine
go p.HandleInbound()
// Run the outbound handler in a new goroutine
go p.HandleOutbound()
// Run the inbound handler in a new goroutine
go p.HandleInbound()
}
func (p *Peer) Stop() {
p.conn.Close()
p.conn.Close()
p.quit <- true
p.quit <- true
}
This diff is collapsed.
package main
import (
"testing"
"fmt"
"fmt"
"testing"
)
func TestEncode(t *testing.T) {
strRes := "Cdog"
strRes := "Cdog"
bytes := Encode("dog")
bytes := Encode("dog")
str := string(bytes)
if str != strRes {
t.Error(fmt.Sprintf("Expected %q, got %q", strRes, str))
}
//dec,_ := Decode(bytes, 0)
str := string(bytes)
if str != strRes {
t.Error(fmt.Sprintf("Expected %q, got %q", strRes, str))
}
//dec,_ := Decode(bytes, 0)
sliceRes := "\x83CdogCgodCcat"
strs := []string{"dog", "god", "cat"}
bytes = Encode(strs)
slice := string(bytes)
if slice != sliceRes {
t.Error(fmt.Sprintf("Expected %q, got %q", sliceRes, slice))
}
sliceRes := "\x83CdogCgodCcat"
strs := []string{"dog", "god", "cat"}
bytes = Encode(strs)
slice := string(bytes)
if slice != sliceRes {
t.Error(fmt.Sprintf("Expected %q, got %q", sliceRes, slice))
}
//dec,_ = Decode(bytes, 0)
//dec,_ = Decode(bytes, 0)
}
func TestMultiEncode(t *testing.T) {
inter := []interface{}{
[]interface{}{
"1","2","3",
},
[]string{
"string",
"string2",
"\x86A0J1234567890A\x00B20A0\x82F395843F657986",
"\x86A0J1234567890A\x00B20A0\x8cF395843F657986I335612448F524099H16716881A0H13114947G2039362G1507139H16719697G1048387E65360",
},
"test",
}
bytes := Encode(inter)
Decode(bytes, 0)
inter := []interface{}{
[]interface{}{
"1", "2", "3",
},
[]string{
"string",
"string2",
"\x86A0J1234567890A\x00B20A0\x82F395843F657986",
"\x86A0J1234567890A\x00B20A0\x8cF395843F657986I335612448F524099H16716881A0H13114947G2039362G1507139H16719697G1048387E65360",
},
"test",
}
bytes := Encode(inter)
Decode(bytes, 0)
}
func BenchmarkEncodeDecode(b *testing.B) {
for i := 0; i < b.N; i++ {
bytes := Encode([]string{"dog", "god", "cat"})
Decode(bytes, 0)
}
for i := 0; i < b.N; i++ {
bytes := Encode([]string{"dog", "god", "cat"})
Decode(bytes, 0)
}
}
package main
import (
"container/list"
"net"
"log"
_"time"
"github.com/ethereum/ethdb-go"
"github.com/ethereum/ethutil-go"
"container/list"
"github.com/ethereum/ethdb-go"
"github.com/ethereum/ethutil-go"
"log"
"net"
_ "time"
)
type Server struct {
// Channel for shutting down the server
shutdownChan chan bool
// DB interface
db *ethdb.LDBDatabase
// Block manager for processing new blocks and managing the block chain
blockManager *BlockManager
// Peers (NYI)
peers *list.List
// Channel for shutting down the server
shutdownChan chan bool
// DB interface
db *ethdb.LDBDatabase
// Block manager for processing new blocks and managing the block chain
blockManager *BlockManager
// Peers (NYI)
peers *list.List
}
func NewServer() (*Server, error) {
db, err := ethdb.NewLDBDatabase()
if err != nil {
return nil, err
}
db, err := ethdb.NewLDBDatabase()
if err != nil {
return nil, err
}
ethutil.SetConfig(db)
ethutil.SetConfig(db)
server := &Server{
shutdownChan: make(chan bool),
blockManager: NewBlockManager(),
db: db,
peers: list.New(),
}
server := &Server{
shutdownChan: make(chan bool),
blockManager: NewBlockManager(),
db: db,
peers: list.New(),
}
return server, nil
return server, nil
}
func (s *Server) AddPeer(conn net.Conn) {
peer := NewPeer(conn, s)
s.peers.PushBack(peer)
peer.Start()
peer := NewPeer(conn, s)
s.peers.PushBack(peer)
peer.Start()
log.Println("Peer connected ::", conn.RemoteAddr())
log.Println("Peer connected ::", conn.RemoteAddr())
}
func (s *Server) ConnectToPeer(addr string) error {
conn, err := net.Dial("tcp", addr)
conn, err := net.Dial("tcp", addr)
if err != nil {
return err
}
if err != nil {
return err
}
peer := NewPeer(conn, s)
s.peers.PushBack(peer)
peer.Start()
peer := NewPeer(conn, s)
s.peers.PushBack(peer)
peer.Start()
log.Println("Connected to peer ::", conn.RemoteAddr())
log.Println("Connected to peer ::", conn.RemoteAddr())
return nil
return nil
}
func (s *Server) Broadcast(msgType string, data []byte) {
for e := s.peers.Front(); e != nil; e = e.Next() {
if peer, ok := e.Value.(*Peer); ok {
peer.QueueMessage(msgType, data)
}
}
for e := s.peers.Front(); e != nil; e = e.Next() {
if peer, ok := e.Value.(*Peer); ok {
peer.QueueMessage(msgType, data)
}
}
}
// Start the server
func (s *Server) Start() {
// For now this function just blocks the main thread
ln, err := net.Listen("tcp", ":12345")
if err != nil {
log.Fatal(err)
}
go func() {
for {
conn, err := ln.Accept()
if err != nil {
log.Println(err)
continue
}
go s.AddPeer(conn)
}
}()
// TMP
//go func() {
// for {
// s.Broadcast("block", Encode("blockdata"))
//
// time.Sleep(100 * time.Millisecond)
// }
// }()
// For now this function just blocks the main thread
ln, err := net.Listen("tcp", ":12345")
if err != nil {
log.Fatal(err)
}
go func() {
for {
conn, err := ln.Accept()
if err != nil {
log.Println(err)
continue
}
go s.AddPeer(conn)
}
}()
// TMP
//go func() {
// for {
// s.Broadcast("block", Encode("blockdata"))
//
// time.Sleep(100 * time.Millisecond)
// }
// }()
}
func (s *Server) Stop() {
// Close the database
defer s.db.Close()
// 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() {
if peer, ok := e.Value.(*Peer); ok {
peer.Stop()
}
}
// Loop thru the peers and close them (if we had them)
for e := s.peers.Front(); e != nil; e = e.Next() {
if peer, ok := e.Value.(*Peer); ok {
peer.Stop()
}
}
s.shutdownChan <- true
s.shutdownChan <- true
}
// This function will wait for a shutdown and resumes main thread execution
func (s *Server) WaitForShutdown() {
<- s.shutdownChan
<-s.shutdownChan
}
package main
import (
"fmt"
"testing"
"encoding/json"
"encoding/json"
"fmt"
"testing"
)
type TestSource struct {
Inputs map[string]string
Expectation string
Inputs map[string]string
Expectation string
}
func NewTestSource(source string) *TestSource {
s := &TestSource{}
err := json.Unmarshal([]byte(source), s)
if err != nil {
fmt.Println(err)
}
s := &TestSource{}
err := json.Unmarshal([]byte(source), s)
if err != nil {
fmt.Println(err)
}
return s
return s
}
type TestRunner struct {
source *TestSource
source *TestSource
}
func NewTestRunner(t *testing.T) *TestRunner {
return &TestRunner{}
return &TestRunner{}
}
func (runner *TestRunner) RunFromString(input string, Cb func(*TestSource)) {
source := NewTestSource(input)
Cb(source)
source := NewTestSource(input)
Cb(source)
}
package main
import (
_"fmt"
"testing"
"encoding/hex"
"encoding/hex"
_ "fmt"
"testing"
)
var testsource = `{"Inputs":{
......@@ -15,17 +15,17 @@ var testsource = `{"Inputs":{
}`
func TestTestRunner(t *testing.T) {
db, _ := NewMemDatabase()
trie := NewTrie(db, "")
db, _ := NewMemDatabase()
trie := NewTrie(db, "")
runner := NewTestRunner(t)
runner.RunFromString(testsource, func(source *TestSource) {
for key, value := range source.Inputs {
trie.Update(key, value)
}
runner := NewTestRunner(t)
runner.RunFromString(testsource, func(source *TestSource) {
for key, value := range source.Inputs {
trie.Update(key, value)
}
if hex.EncodeToString([]byte(trie.root)) != source.Expectation {
t.Error("trie root did not match")
}
})
if hex.EncodeToString([]byte(trie.root)) != source.Expectation {
t.Error("trie root did not match")
}
})
}
package main
/*
import (
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment