This commit is contained in:
Jae Kwon
2014-07-01 14:50:24 -07:00
parent fa07748d23
commit c40fc65e6b
41 changed files with 3176 additions and 2938 deletions

View File

@ -7,8 +7,10 @@ type Binary interface {
} }
func WriteOnto(b Binary, w io.Writer, n int64, err error) (int64, error) { func WriteOnto(b Binary, w io.Writer, n int64, err error) (int64, error) {
if err != nil { return n, err } if err != nil {
return n, err
}
var n_ int64 var n_ int64
n_, err = b.WriteTo(w) n_, err = b.WriteTo(w)
return n+n_, err return n + n_, err
} }

View File

@ -22,28 +22,36 @@ func (self ByteSlice) Less(other Binary) bool {
} }
func (self ByteSlice) ByteSize() int { func (self ByteSlice) ByteSize() int {
return len(self)+4 return len(self) + 4
} }
func (self ByteSlice) WriteTo(w io.Writer) (n int64, err error) { func (self ByteSlice) WriteTo(w io.Writer) (n int64, err error) {
var n_ int var n_ int
_, err = UInt32(len(self)).WriteTo(w) _, err = UInt32(len(self)).WriteTo(w)
if err != nil { return n, err } if err != nil {
return n, err
}
n_, err = w.Write([]byte(self)) n_, err = w.Write([]byte(self))
return int64(n_+4), err return int64(n_ + 4), err
} }
func ReadByteSliceSafe(r io.Reader) (ByteSlice, error) { func ReadByteSliceSafe(r io.Reader) (ByteSlice, error) {
length, err := ReadUInt32Safe(r) length, err := ReadUInt32Safe(r)
if err != nil { return nil, err } if err != nil {
return nil, err
}
bytes := make([]byte, int(length)) bytes := make([]byte, int(length))
_, err = io.ReadFull(r, bytes) _, err = io.ReadFull(r, bytes)
if err != nil { return nil, err } if err != nil {
return nil, err
}
return bytes, nil return bytes, nil
} }
func ReadByteSlice(r io.Reader) ByteSlice { func ReadByteSlice(r io.Reader) ByteSlice {
bytes, err := ReadByteSliceSafe(r) bytes, err := ReadByteSliceSafe(r)
if r != nil { panic(err) } if r != nil {
panic(err)
}
return bytes return bytes
} }

View File

@ -24,47 +24,77 @@ const (
func GetBinaryType(o Binary) Byte { func GetBinaryType(o Binary) Byte {
switch o.(type) { switch o.(type) {
case nil: return TYPE_NIL case nil:
case Byte: return TYPE_BYTE return TYPE_NIL
case Int8: return TYPE_INT8 case Byte:
case UInt8: return TYPE_UINT8 return TYPE_BYTE
case Int16: return TYPE_INT16 case Int8:
case UInt16: return TYPE_UINT16 return TYPE_INT8
case Int32: return TYPE_INT32 case UInt8:
case UInt32: return TYPE_UINT32 return TYPE_UINT8
case Int64: return TYPE_INT64 case Int16:
case UInt64: return TYPE_UINT64 return TYPE_INT16
case Int: panic("Int not supported") case UInt16:
case UInt: panic("UInt not supported") return TYPE_UINT16
case Int32:
return TYPE_INT32
case UInt32:
return TYPE_UINT32
case Int64:
return TYPE_INT64
case UInt64:
return TYPE_UINT64
case Int:
panic("Int not supported")
case UInt:
panic("UInt not supported")
case String: return TYPE_STRING case String:
case ByteSlice: return TYPE_BYTESLICE return TYPE_STRING
case ByteSlice:
return TYPE_BYTESLICE
case Time: return TYPE_TIME case Time:
return TYPE_TIME
default: panic("Unsupported type") default:
panic("Unsupported type")
} }
} }
func ReadBinary(r io.Reader) Binary { func ReadBinary(r io.Reader) Binary {
type_ := ReadByte(r) type_ := ReadByte(r)
switch type_ { switch type_ {
case TYPE_NIL: return nil case TYPE_NIL:
case TYPE_BYTE: return ReadByte(r) return nil
case TYPE_INT8: return ReadInt8(r) case TYPE_BYTE:
case TYPE_UINT8: return ReadUInt8(r) return ReadByte(r)
case TYPE_INT16: return ReadInt16(r) case TYPE_INT8:
case TYPE_UINT16: return ReadUInt16(r) return ReadInt8(r)
case TYPE_INT32: return ReadInt32(r) case TYPE_UINT8:
case TYPE_UINT32: return ReadUInt32(r) return ReadUInt8(r)
case TYPE_INT64: return ReadInt64(r) case TYPE_INT16:
case TYPE_UINT64: return ReadUInt64(r) return ReadInt16(r)
case TYPE_UINT16:
return ReadUInt16(r)
case TYPE_INT32:
return ReadInt32(r)
case TYPE_UINT32:
return ReadUInt32(r)
case TYPE_INT64:
return ReadInt64(r)
case TYPE_UINT64:
return ReadUInt64(r)
case TYPE_STRING: return ReadString(r) case TYPE_STRING:
case TYPE_BYTESLICE:return ReadByteSlice(r) return ReadString(r)
case TYPE_BYTESLICE:
return ReadByteSlice(r)
case TYPE_TIME: return ReadTime(r) case TYPE_TIME:
return ReadTime(r)
default: panic("Unsupported type") default:
panic("Unsupported type")
} }
} }

View File

@ -1,8 +1,8 @@
package binary package binary
import ( import (
"io"
"encoding/binary" "encoding/binary"
"io"
) )
type Byte byte type Byte byte
@ -17,7 +17,6 @@ type UInt64 uint64
type Int int type Int int
type UInt uint type UInt uint
// Byte // Byte
func (self Byte) Equals(other Binary) bool { func (self Byte) Equals(other Binary) bool {
@ -44,17 +43,20 @@ func (self Byte) WriteTo(w io.Writer) (int64, error) {
func ReadByteSafe(r io.Reader) (Byte, error) { func ReadByteSafe(r io.Reader) (Byte, error) {
buf := [1]byte{0} buf := [1]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { return 0, err } if err != nil {
return 0, err
}
return Byte(buf[0]), nil return Byte(buf[0]), nil
} }
func ReadByte(r io.Reader) (Byte) { func ReadByte(r io.Reader) Byte {
b, err := ReadByteSafe(r) b, err := ReadByteSafe(r)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return b return b
} }
// Int8 // Int8
func (self Int8) Equals(other Binary) bool { func (self Int8) Equals(other Binary) bool {
@ -81,17 +83,20 @@ func (self Int8) WriteTo(w io.Writer) (int64, error) {
func ReadInt8Safe(r io.Reader) (Int8, error) { func ReadInt8Safe(r io.Reader) (Int8, error) {
buf := [1]byte{0} buf := [1]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { return Int8(0), err } if err != nil {
return Int8(0), err
}
return Int8(buf[0]), nil return Int8(buf[0]), nil
} }
func ReadInt8(r io.Reader) (Int8) { func ReadInt8(r io.Reader) Int8 {
b, err := ReadInt8Safe(r) b, err := ReadInt8Safe(r)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return b return b
} }
// UInt8 // UInt8
func (self UInt8) Equals(other Binary) bool { func (self UInt8) Equals(other Binary) bool {
@ -118,17 +123,20 @@ func (self UInt8) WriteTo(w io.Writer) (int64, error) {
func ReadUInt8Safe(r io.Reader) (UInt8, error) { func ReadUInt8Safe(r io.Reader) (UInt8, error) {
buf := [1]byte{0} buf := [1]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { return UInt8(0), err } if err != nil {
return UInt8(0), err
}
return UInt8(buf[0]), nil return UInt8(buf[0]), nil
} }
func ReadUInt8(r io.Reader) (UInt8) { func ReadUInt8(r io.Reader) UInt8 {
b, err := ReadUInt8Safe(r) b, err := ReadUInt8Safe(r)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return b return b
} }
// Int16 // Int16
func (self Int16) Equals(other Binary) bool { func (self Int16) Equals(other Binary) bool {
@ -155,17 +163,20 @@ func (self Int16) WriteTo(w io.Writer) (int64, error) {
func ReadInt16Safe(r io.Reader) (Int16, error) { func ReadInt16Safe(r io.Reader) (Int16, error) {
buf := [2]byte{0} buf := [2]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { return Int16(0), err } if err != nil {
return Int16(0), err
}
return Int16(binary.LittleEndian.Uint16(buf[:])), nil return Int16(binary.LittleEndian.Uint16(buf[:])), nil
} }
func ReadInt16(r io.Reader) (Int16) { func ReadInt16(r io.Reader) Int16 {
b, err := ReadInt16Safe(r) b, err := ReadInt16Safe(r)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return b return b
} }
// UInt16 // UInt16
func (self UInt16) Equals(other Binary) bool { func (self UInt16) Equals(other Binary) bool {
@ -192,17 +203,20 @@ func (self UInt16) WriteTo(w io.Writer) (int64, error) {
func ReadUInt16Safe(r io.Reader) (UInt16, error) { func ReadUInt16Safe(r io.Reader) (UInt16, error) {
buf := [2]byte{0} buf := [2]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { return UInt16(0), err } if err != nil {
return UInt16(0), err
}
return UInt16(binary.LittleEndian.Uint16(buf[:])), nil return UInt16(binary.LittleEndian.Uint16(buf[:])), nil
} }
func ReadUInt16(r io.Reader) (UInt16) { func ReadUInt16(r io.Reader) UInt16 {
b, err := ReadUInt16Safe(r) b, err := ReadUInt16Safe(r)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return b return b
} }
// Int32 // Int32
func (self Int32) Equals(other Binary) bool { func (self Int32) Equals(other Binary) bool {
@ -229,17 +243,20 @@ func (self Int32) WriteTo(w io.Writer) (int64, error) {
func ReadInt32Safe(r io.Reader) (Int32, error) { func ReadInt32Safe(r io.Reader) (Int32, error) {
buf := [4]byte{0} buf := [4]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { return Int32(0), err } if err != nil {
return Int32(0), err
}
return Int32(binary.LittleEndian.Uint32(buf[:])), nil return Int32(binary.LittleEndian.Uint32(buf[:])), nil
} }
func ReadInt32(r io.Reader) (Int32) { func ReadInt32(r io.Reader) Int32 {
b, err := ReadInt32Safe(r) b, err := ReadInt32Safe(r)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return b return b
} }
// UInt32 // UInt32
func (self UInt32) Equals(other Binary) bool { func (self UInt32) Equals(other Binary) bool {
@ -266,17 +283,20 @@ func (self UInt32) WriteTo(w io.Writer) (int64, error) {
func ReadUInt32Safe(r io.Reader) (UInt32, error) { func ReadUInt32Safe(r io.Reader) (UInt32, error) {
buf := [4]byte{0} buf := [4]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { return UInt32(0), err } if err != nil {
return UInt32(0), err
}
return UInt32(binary.LittleEndian.Uint32(buf[:])), nil return UInt32(binary.LittleEndian.Uint32(buf[:])), nil
} }
func ReadUInt32(r io.Reader) (UInt32) { func ReadUInt32(r io.Reader) UInt32 {
b, err := ReadUInt32Safe(r) b, err := ReadUInt32Safe(r)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return b return b
} }
// Int64 // Int64
func (self Int64) Equals(other Binary) bool { func (self Int64) Equals(other Binary) bool {
@ -303,17 +323,20 @@ func (self Int64) WriteTo(w io.Writer) (int64, error) {
func ReadInt64Safe(r io.Reader) (Int64, error) { func ReadInt64Safe(r io.Reader) (Int64, error) {
buf := [8]byte{0} buf := [8]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { return Int64(0), err } if err != nil {
return Int64(0), err
}
return Int64(binary.LittleEndian.Uint64(buf[:])), nil return Int64(binary.LittleEndian.Uint64(buf[:])), nil
} }
func ReadInt64(r io.Reader) (Int64) { func ReadInt64(r io.Reader) Int64 {
b, err := ReadInt64Safe(r) b, err := ReadInt64Safe(r)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return b return b
} }
// UInt64 // UInt64
func (self UInt64) Equals(other Binary) bool { func (self UInt64) Equals(other Binary) bool {
@ -340,17 +363,20 @@ func (self UInt64) WriteTo(w io.Writer) (int64, error) {
func ReadUInt64Safe(r io.Reader) (UInt64, error) { func ReadUInt64Safe(r io.Reader) (UInt64, error) {
buf := [8]byte{0} buf := [8]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { return UInt64(0), err } if err != nil {
return UInt64(0), err
}
return UInt64(binary.LittleEndian.Uint64(buf[:])), nil return UInt64(binary.LittleEndian.Uint64(buf[:])), nil
} }
func ReadUInt64(r io.Reader) (UInt64) { func ReadUInt64(r io.Reader) UInt64 {
b, err := ReadUInt64Safe(r) b, err := ReadUInt64Safe(r)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return b return b
} }
// Int // Int
func (self Int) Equals(other Binary) bool { func (self Int) Equals(other Binary) bool {
@ -377,11 +403,12 @@ func (self Int) WriteTo(w io.Writer) (int64, error) {
func ReadInt(r io.Reader) Int { func ReadInt(r io.Reader) Int {
buf := [8]byte{0} buf := [8]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { panic(err) } if err != nil {
panic(err)
}
return Int(binary.LittleEndian.Uint64(buf[:])) return Int(binary.LittleEndian.Uint64(buf[:]))
} }
// UInt // UInt
func (self UInt) Equals(other Binary) bool { func (self UInt) Equals(other Binary) bool {
@ -408,6 +435,8 @@ func (self UInt) WriteTo(w io.Writer) (int64, error) {
func ReadUInt(r io.Reader) UInt { func ReadUInt(r io.Reader) UInt {
buf := [8]byte{0} buf := [8]byte{0}
_, err := io.ReadFull(r, buf[:]) _, err := io.ReadFull(r, buf[:])
if err != nil { panic(err) } if err != nil {
panic(err)
}
return UInt(binary.LittleEndian.Uint64(buf[:])) return UInt(binary.LittleEndian.Uint64(buf[:]))
} }

View File

@ -19,28 +19,36 @@ func (self String) Less(other Binary) bool {
} }
func (self String) ByteSize() int { func (self String) ByteSize() int {
return len(self)+4 return len(self) + 4
} }
func (self String) WriteTo(w io.Writer) (n int64, err error) { func (self String) WriteTo(w io.Writer) (n int64, err error) {
var n_ int var n_ int
_, err = UInt32(len(self)).WriteTo(w) _, err = UInt32(len(self)).WriteTo(w)
if err != nil { return n, err } if err != nil {
return n, err
}
n_, err = w.Write([]byte(self)) n_, err = w.Write([]byte(self))
return int64(n_+4), err return int64(n_ + 4), err
} }
func ReadStringSafe(r io.Reader) (String, error) { func ReadStringSafe(r io.Reader) (String, error) {
length, err := ReadUInt32Safe(r) length, err := ReadUInt32Safe(r)
if err != nil { return "", err } if err != nil {
return "", err
}
bytes := make([]byte, int(length)) bytes := make([]byte, int(length))
_, err = io.ReadFull(r, bytes) _, err = io.ReadFull(r, bytes)
if err != nil { return "", err } if err != nil {
return "", err
}
return String(bytes), nil return String(bytes), nil
} }
func ReadString(r io.Reader) String { func ReadString(r io.Reader) String {
str, err := ReadStringSafe(r) str, err := ReadStringSafe(r)
if r != nil { panic(err) } if r != nil {
panic(err)
}
return str return str
} }

View File

@ -1,8 +1,8 @@
package binary package binary
import ( import (
"crypto/sha256"
"bytes" "bytes"
"crypto/sha256"
) )
func BinaryBytes(b Binary) ByteSlice { func BinaryBytes(b Binary) ByteSlice {
@ -28,6 +28,8 @@ func BinaryCompare(a, b Binary) int {
func BinaryHash(b Binary) ByteSlice { func BinaryHash(b Binary) ByteSlice {
hasher := sha256.New() hasher := sha256.New()
_, err := b.WriteTo(hasher) _, err := b.WriteTo(hasher)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return ByteSlice(hasher.Sum(nil)) return ByteSlice(hasher.Sum(nil))
} }

View File

@ -1,8 +1,8 @@
package blocks package blocks
import ( import (
. "github.com/tendermint/tendermint/common"
. "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
"io" "io"
) )

View File

@ -1,8 +1,8 @@
package blocks package blocks
import ( import (
. "github.com/tendermint/tendermint/common"
. "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
"io" "io"
) )
@ -59,7 +59,6 @@ func ReadAdjustment(r io.Reader) Adjustment {
} }
} }
/* Bond < Adjustment */ /* Bond < Adjustment */
type Bond struct { type Bond struct {
@ -82,7 +81,6 @@ func (self *Bond) WriteTo(w io.Writer) (n int64, err error) {
return return
} }
/* Unbond < Adjustment */ /* Unbond < Adjustment */
type Unbond struct { type Unbond struct {
@ -103,7 +101,6 @@ func (self *Unbond) WriteTo(w io.Writer) (n int64, err error) {
return return
} }
/* Timeout < Adjustment */ /* Timeout < Adjustment */
type Timeout struct { type Timeout struct {
@ -122,7 +119,6 @@ func (self *Timeout) WriteTo(w io.Writer) (n int64, err error) {
return return
} }
/* Dupeout < Adjustment */ /* Dupeout < Adjustment */
type Dupeout struct { type Dupeout struct {

View File

@ -6,7 +6,6 @@ import (
"io" "io"
) )
/* Block */ /* Block */
type Block struct { type Block struct {
@ -35,7 +34,6 @@ func (self *Block) WriteTo(w io.Writer) (n int64, err error) {
return return
} }
/* Block > Header */ /* Block > Header */
type Header struct { type Header struct {
@ -71,7 +69,6 @@ func (self *Header) WriteTo(w io.Writer) (n int64, err error) {
return return
} }
/* Block > Validation */ /* Block > Validation */
type Validation struct { type Validation struct {
@ -83,11 +80,11 @@ func ReadValidation(r io.Reader) Validation {
numSigs := int(ReadUInt64(r)) numSigs := int(ReadUInt64(r))
numAdjs := int(ReadUInt64(r)) numAdjs := int(ReadUInt64(r))
sigs := make([]Signature, 0, numSigs) sigs := make([]Signature, 0, numSigs)
for i:=0; i<numSigs; i++ { for i := 0; i < numSigs; i++ {
sigs = append(sigs, ReadSignature(r)) sigs = append(sigs, ReadSignature(r))
} }
adjs := make([]Adjustment, 0, numAdjs) adjs := make([]Adjustment, 0, numAdjs)
for i:=0; i<numAdjs; i++ { for i := 0; i < numAdjs; i++ {
adjs = append(adjs, ReadAdjustment(r)) adjs = append(adjs, ReadAdjustment(r))
} }
return Validation{ return Validation{
@ -117,7 +114,7 @@ type Data struct {
func ReadData(r io.Reader) Data { func ReadData(r io.Reader) Data {
numTxs := int(ReadUInt64(r)) numTxs := int(ReadUInt64(r))
txs := make([]Tx, 0, numTxs) txs := make([]Tx, 0, numTxs)
for i:=0; i<numTxs; i++ { for i := 0; i < numTxs; i++ {
txs = append(txs, ReadTx(r)) txs = append(txs, ReadTx(r))
} }
return Data{txs} return Data{txs}

View File

@ -1,24 +1,26 @@
package blocks package blocks
import ( import (
. "github.com/tendermint/tendermint/binary"
"testing"
"math/rand"
"bytes" "bytes"
. "github.com/tendermint/tendermint/binary"
"math/rand"
"testing"
) )
// Distributed pseudo-exponentially to test for various cases // Distributed pseudo-exponentially to test for various cases
func randVar() UInt64 { func randVar() UInt64 {
bits := rand.Uint32() % 64 bits := rand.Uint32() % 64
if bits == 0 { return 0 } if bits == 0 {
n := uint64(1 << (bits-1)) return 0
n += uint64(rand.Int63()) & ((1 << (bits-1)) - 1) }
n := uint64(1 << (bits - 1))
n += uint64(rand.Int63()) & ((1 << (bits - 1)) - 1)
return UInt64(n) return UInt64(n)
} }
func randBytes(n int) ByteSlice { func randBytes(n int) ByteSlice {
bs := make([]byte, n) bs := make([]byte, n)
for i:=0; i<n; i++ { for i := 0; i < n; i++ {
bs[i] = byte(rand.Intn(256)) bs[i] = byte(rand.Intn(256))
} }
return bs return bs
@ -92,8 +94,8 @@ func TestBlock(t *testing.T) {
DataHash: randBytes(32), DataHash: randBytes(32),
}, },
Validation{ Validation{
Signatures: []Signature{randSig(),randSig()}, Signatures: []Signature{randSig(), randSig()},
Adjustments:[]Adjustment{bond,unbond,timeout,dupeout}, Adjustments: []Adjustment{bond, unbond, timeout, dupeout},
}, },
Data{ Data{
Txs: []Tx{sendTx, nameTx}, Txs: []Tx{sendTx, nameTx},

View File

@ -1,8 +1,8 @@
package blocks package blocks
import ( import (
. "github.com/tendermint/tendermint/common"
. "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
"io" "io"
) )
@ -52,7 +52,6 @@ func ReadTx(r io.Reader) Tx {
} }
} }
/* SendTx < Tx */ /* SendTx < Tx */
type SendTx struct { type SendTx struct {
@ -75,7 +74,6 @@ func (self *SendTx) WriteTo(w io.Writer) (n int64, err error) {
return return
} }
/* NameTx < Tx */ /* NameTx < Tx */
type NameTx struct { type NameTx struct {

View File

@ -1,8 +1,8 @@
package common package common
import ( import (
"time"
"sync" "sync"
"time"
) )
/* Debouncer */ /* Debouncer */
@ -26,20 +26,23 @@ func NewDebouncer(dur time.Duration) *Debouncer {
case <-quit: case <-quit:
} }
}() }()
mtx.Lock(); defer mtx.Unlock() mtx.Lock()
defer mtx.Unlock()
timer.Reset(dur) timer.Reset(dur)
} }
timer = time.AfterFunc(dur, fire) timer = time.AfterFunc(dur, fire)
return &Debouncer{Ch:ch, dur:dur, quit:quit, mtx:mtx, timer:timer} return &Debouncer{Ch: ch, dur: dur, quit: quit, mtx: mtx, timer: timer}
} }
func (d *Debouncer) Reset() { func (d *Debouncer) Reset() {
d.mtx.Lock(); defer d.mtx.Unlock() d.mtx.Lock()
defer d.mtx.Unlock()
d.timer.Reset(d.dur) d.timer.Reset(d.dur)
} }
func (d *Debouncer) Stop() bool { func (d *Debouncer) Stop() bool {
d.mtx.Lock(); defer d.mtx.Unlock() d.mtx.Lock()
defer d.mtx.Unlock()
close(d.quit) close(d.quit)
return d.timer.Stop() return d.timer.Stop()
} }

View File

@ -9,7 +9,7 @@ type Heap struct {
} }
func NewHeap() *Heap { func NewHeap() *Heap {
return &Heap{pq:make([]*pqItem, 0)} return &Heap{pq: make([]*pqItem, 0)}
} }
func (h *Heap) Len() int { func (h *Heap) Len() int {
@ -17,7 +17,7 @@ func (h *Heap) Len() int {
} }
func (h *Heap) Push(value interface{}, priority int) { func (h *Heap) Push(value interface{}, priority int) {
heap.Push(&h.pq, &pqItem{value:value, priority:priority}) heap.Push(&h.pq, &pqItem{value: value, priority: priority})
} }
func (h *Heap) Pop() interface{} { func (h *Heap) Pop() interface{} {
@ -84,4 +84,3 @@ func (pq *priorityQueue) Update(item *pqItem, value interface{}, priority int) {
item.priority = priority item.priority = priority
heap.Push(pq, item) heap.Push(pq, item)
} }

View File

@ -2,27 +2,26 @@ package config
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"errors"
//"crypto/rand" //"crypto/rand"
//"encoding/hex" //"encoding/hex"
) )
var APP_DIR = os.Getenv("HOME") + "/.tendermint" var APP_DIR = os.Getenv("HOME") + "/.tendermint"
/* Global & initialization */ /* Global & initialization */
var Config Config_ var Config Config_
func init() { func init() {
configFile := APP_DIR+"/config.json" configFile := APP_DIR + "/config.json"
// try to read configuration. if missing, write default // try to read configuration. if missing, write default
configBytes, err := ioutil.ReadFile(configFile) configBytes, err := ioutil.ReadFile(configFile)
@ -45,7 +44,6 @@ func init() {
} }
} }
/* Default configuration */ /* Default configuration */
var defaultConfig = Config_{ var defaultConfig = Config_{
@ -53,13 +51,11 @@ var defaultConfig = Config_{
Port: 8770, Port: 8770,
Db: DbConfig{ Db: DbConfig{
Type: "level", Type: "level",
Dir: APP_DIR+"/data", Dir: APP_DIR + "/data",
},
Twilio: TwilioConfig{
}, },
Twilio: TwilioConfig{},
} }
/* Configuration types */ /* Configuration types */
type Config_ struct { type Config_ struct {
@ -83,22 +79,32 @@ type DbConfig struct {
} }
func (cfg *Config_) validate() error { func (cfg *Config_) validate() error {
if cfg.Host == "" { return errors.New("Host must be set") } if cfg.Host == "" {
if cfg.Port == 0 { return errors.New("Port must be set") } return errors.New("Host must be set")
if cfg.Db.Type == "" { return errors.New("Db.Type must be set") } }
if cfg.Port == 0 {
return errors.New("Port must be set")
}
if cfg.Db.Type == "" {
return errors.New("Db.Type must be set")
}
return nil return nil
} }
func (cfg *Config_) bytes() []byte { func (cfg *Config_) bytes() []byte {
configBytes, err := json.Marshal(cfg) configBytes, err := json.Marshal(cfg)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return configBytes return configBytes
} }
func (cfg *Config_) write(configFile string) { func (cfg *Config_) write(configFile string) {
if strings.Index(configFile, "/") != -1 { if strings.Index(configFile, "/") != -1 {
err := os.MkdirAll(filepath.Dir(configFile), 0700) err := os.MkdirAll(filepath.Dir(configFile), 0700)
if err != nil { panic(err) } if err != nil {
panic(err)
}
} }
err := ioutil.WriteFile(configFile, cfg.bytes(), 0600) err := ioutil.WriteFile(configFile, cfg.bytes(), 0600)
if err != nil { if err != nil {
@ -113,4 +119,3 @@ func generateKeys() string {
return hex.EncodeToString(bytes[:]) return hex.EncodeToString(bytes[:])
} }
*/ */

View File

@ -1,14 +1,16 @@
package crypto package crypto
import ( import (
"testing"
"crypto/rand" "crypto/rand"
"testing"
) )
func TestSign(t *testing.T) { func TestSign(t *testing.T) {
privKey := make([]byte, 32) privKey := make([]byte, 32)
_, err := rand.Read(privKey) _, err := rand.Read(privKey)
if err != nil { t.Fatal(err) } if err != nil {
t.Fatal(err)
}
pubKey := MakePubKey(privKey) pubKey := MakePubKey(privKey)
signature := SignMessage([]byte("hello"), privKey, pubKey) signature := SignMessage([]byte("hello"), privKey, pubKey)
@ -19,8 +21,12 @@ func TestSign(t *testing.T) {
} }
ok := VerifyBatch([]*Verify{v1, v1, v1, v1}) ok := VerifyBatch([]*Verify{v1, v1, v1, v1})
if ok != true { t.Fatal("Expected ok == true") } if ok != true {
if v1.Valid != true { t.Fatal("Expected v1.Valid to be true") } t.Fatal("Expected ok == true")
}
if v1.Valid != true {
t.Fatal("Expected v1.Valid to be true")
}
v2 := &Verify{ v2 := &Verify{
Message: []byte{0x73}, Message: []byte{0x73},
@ -29,7 +35,13 @@ func TestSign(t *testing.T) {
} }
ok = VerifyBatch([]*Verify{v1, v1, v1, v2}) ok = VerifyBatch([]*Verify{v1, v1, v1, v2})
if ok != false { t.Fatal("Expected ok == false") } if ok != false {
if v1.Valid != true { t.Fatal("Expected v1.Valid to be true") } t.Fatal("Expected ok == false")
if v2.Valid != false { t.Fatal("Expected v2.Valid to be true") } }
if v1.Valid != true {
t.Fatal("Expected v1.Valid to be true")
}
if v2.Valid != false {
t.Fatal("Expected v2.Valid to be true")
}
} }

View File

@ -22,18 +22,24 @@ func NewLevelDB(name string) (*LevelDB, error) {
func (db *LevelDB) Put(key []byte, value []byte) { func (db *LevelDB) Put(key []byte, value []byte) {
err := db.db.Put(key, value, nil) err := db.db.Put(key, value, nil)
if err != nil { panic(err) } if err != nil {
panic(err)
}
} }
func (db *LevelDB) Get(key []byte) ([]byte) { func (db *LevelDB) Get(key []byte) []byte {
res, err := db.db.Get(key, nil) res, err := db.db.Get(key, nil)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return res return res
} }
func (db *LevelDB) Delete(key []byte) { func (db *LevelDB) Delete(key []byte) {
err := db.db.Delete(key, nil) err := db.db.Delete(key, nil)
if err != nil { panic(err) } if err != nil {
panic(err)
}
} }
func (db *LevelDB) Db() *leveldb.DB { func (db *LevelDB) Db() *leveldb.DB {

View File

@ -8,8 +8,8 @@ type MemDB struct {
db map[string][]byte db map[string][]byte
} }
func NewMemDB() (*MemDB) { func NewMemDB() *MemDB {
database := &MemDB{db:make(map[string][]byte)} database := &MemDB{db: make(map[string][]byte)}
return database return database
} }
@ -17,7 +17,7 @@ func (db *MemDB) Put(key []byte, value []byte) {
db.db[string(key)] = value db.db[string(key)] = value
} }
func (db *MemDB) Get(key []byte) ([]byte) { func (db *MemDB) Get(key []byte) []byte {
return db.db[string(key)] return db.db[string(key)]
} }

View File

@ -1,10 +1,10 @@
package merkle package merkle
import ( import (
. "github.com/tendermint/tendermint/binary"
"bytes" "bytes"
"io"
"crypto/sha256" "crypto/sha256"
. "github.com/tendermint/tendermint/binary"
"io"
) )
// Node // Node
@ -104,18 +104,20 @@ func (self *IAVLNode) Hash() (ByteSlice, uint64) {
hasher := sha256.New() hasher := sha256.New()
_, hashCount, err := self.saveToCountHashes(hasher, false) _, hashCount, err := self.saveToCountHashes(hasher, false)
if err != nil { panic(err) } if err != nil {
panic(err)
}
self.hash = hasher.Sum(nil) self.hash = hasher.Sum(nil)
return self.hash, hashCount+1 return self.hash, hashCount + 1
} }
func (self *IAVLNode) Save(db Db) { func (self *IAVLNode) Save(db Db) {
if self.hash == nil { if self.hash == nil {
panic("savee.hash can't be nil") panic("savee.hash can't be nil")
} }
if self.flags & IAVLNODE_FLAG_PERSISTED > 0 || if self.flags&IAVLNODE_FLAG_PERSISTED > 0 ||
self.flags & IAVLNODE_FLAG_PLACEHOLDER > 0 { self.flags&IAVLNODE_FLAG_PLACEHOLDER > 0 {
return return
} }
@ -128,7 +130,9 @@ func (self *IAVLNode) Save(db Db) {
// save self // save self
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
_, err := self.WriteTo(buf) _, err := self.WriteTo(buf)
if err != nil { panic(err) } if err != nil {
panic(err)
}
db.Put([]byte(self.hash), buf.Bytes()) db.Put([]byte(self.hash), buf.Bytes())
self.flags |= IAVLNODE_FLAG_PERSISTED self.flags |= IAVLNODE_FLAG_PERSISTED
@ -221,36 +225,68 @@ func (self *IAVLNode) saveToCountHashes(w io.Writer, meta bool) (n int64, hashCo
if meta { if meta {
// height & size // height & size
_n, err = UInt8(self.height).WriteTo(w) _n, err = UInt8(self.height).WriteTo(w)
if err != nil { return } else { n += _n } if err != nil {
return
} else {
n += _n
}
_n, err = UInt64(self.size).WriteTo(w) _n, err = UInt64(self.size).WriteTo(w)
if err != nil { return } else { n += _n } if err != nil {
return
} else {
n += _n
}
// key // key
_n, err = Byte(GetBinaryType(self.key)).WriteTo(w) _n, err = Byte(GetBinaryType(self.key)).WriteTo(w)
if err != nil { return } else { n += _n } if err != nil {
return
} else {
n += _n
}
_n, err = self.key.WriteTo(w) _n, err = self.key.WriteTo(w)
if err != nil { return } else { n += _n } if err != nil {
return
} else {
n += _n
}
} }
if self.height == 0 { if self.height == 0 {
// value // value
_n, err = Byte(GetBinaryType(self.value)).WriteTo(w) _n, err = Byte(GetBinaryType(self.value)).WriteTo(w)
if err != nil { return } else { n += _n } if err != nil {
return
} else {
n += _n
}
if self.value != nil { if self.value != nil {
_n, err = self.value.WriteTo(w) _n, err = self.value.WriteTo(w)
if err != nil { return } else { n += _n } if err != nil {
return
} else {
n += _n
}
} }
} else { } else {
// left // left
leftHash, leftCount := self.left.Hash() leftHash, leftCount := self.left.Hash()
hashCount += leftCount hashCount += leftCount
_n, err = leftHash.WriteTo(w) _n, err = leftHash.WriteTo(w)
if err != nil { return } else { n += _n } if err != nil {
return
} else {
n += _n
}
// right // right
rightHash, rightCount := self.right.Hash() rightHash, rightCount := self.right.Hash()
hashCount += rightCount hashCount += rightCount
_n, err = rightHash.WriteTo(w) _n, err = rightHash.WriteTo(w)
if err != nil { return } else { n += _n } if err != nil {
return
} else {
n += _n
}
} }
return return
@ -298,14 +334,14 @@ func (self *IAVLNode) fill(db Db) {
} }
func (self *IAVLNode) leftFilled(db Db) *IAVLNode { func (self *IAVLNode) leftFilled(db Db) *IAVLNode {
if self.left.flags & IAVLNODE_FLAG_PLACEHOLDER > 0 { if self.left.flags&IAVLNODE_FLAG_PLACEHOLDER > 0 {
self.left.fill(db) self.left.fill(db)
} }
return self.left return self.left
} }
func (self *IAVLNode) rightFilled(db Db) *IAVLNode { func (self *IAVLNode) rightFilled(db Db) *IAVLNode {
if self.right.flags & IAVLNODE_FLAG_PLACEHOLDER > 0 { if self.right.flags&IAVLNODE_FLAG_PLACEHOLDER > 0 {
self.right.fill(db) self.right.fill(db)
} }
return self.right return self.right
@ -350,8 +386,8 @@ func (self *IAVLNode) calcBalance(db Db) int {
func (self *IAVLNode) balance(db Db) (newSelf *IAVLNode) { func (self *IAVLNode) balance(db Db) (newSelf *IAVLNode) {
balance := self.calcBalance(db) balance := self.calcBalance(db)
if (balance > 1) { if balance > 1 {
if (self.leftFilled(db).calcBalance(db) >= 0) { if self.leftFilled(db).calcBalance(db) >= 0 {
// Left Left Case // Left Left Case
return self.rotateRight(db) return self.rotateRight(db)
} else { } else {
@ -362,8 +398,8 @@ func (self *IAVLNode) balance(db Db) (newSelf *IAVLNode) {
return self.rotateRight(db) return self.rotateRight(db)
} }
} }
if (balance < -1) { if balance < -1 {
if (self.rightFilled(db).calcBalance(db) <= 0) { if self.rightFilled(db).calcBalance(db) <= 0 {
// Right Right Case // Right Right Case
return self.rotateLeft(db) return self.rotateLeft(db)
} else { } else {
@ -378,28 +414,34 @@ func (self *IAVLNode) balance(db Db) (newSelf *IAVLNode) {
return self return self
} }
func (self *IAVLNode) lmd(db Db) (*IAVLNode) { func (self *IAVLNode) lmd(db Db) *IAVLNode {
if self.height == 0 { if self.height == 0 {
return self return self
} }
return self.leftFilled(db).lmd(db) return self.leftFilled(db).lmd(db)
} }
func (self *IAVLNode) rmd(db Db) (*IAVLNode) { func (self *IAVLNode) rmd(db Db) *IAVLNode {
if self.height == 0 { if self.height == 0 {
return self return self
} }
return self.rightFilled(db).rmd(db) return self.rightFilled(db).rmd(db)
} }
func (self *IAVLNode) traverse(db Db, cb func(Node)bool) bool { func (self *IAVLNode) traverse(db Db, cb func(Node) bool) bool {
stop := cb(self) stop := cb(self)
if stop { return stop } if stop {
return stop
}
if self.height > 0 { if self.height > 0 {
stop = self.leftFilled(db).traverse(db, cb) stop = self.leftFilled(db).traverse(db, cb)
if stop { return stop } if stop {
return stop
}
stop = self.rightFilled(db).traverse(db, cb) stop = self.rightFilled(db).traverse(db, cb)
if stop { return stop } if stop {
return stop
}
} }
return false return false
} }

View File

@ -1,16 +1,16 @@
package merkle package merkle
import ( import (
. "github.com/tendermint/tendermint/binary"
"testing"
"fmt"
"os"
"bytes" "bytes"
"math/rand"
"encoding/binary"
"github.com/tendermint/tendermint/db"
"crypto/sha256" "crypto/sha256"
"encoding/binary"
"fmt"
. "github.com/tendermint/tendermint/binary"
"github.com/tendermint/tendermint/db"
"math/rand"
"os"
"runtime" "runtime"
"testing"
) )
func init() { func init() {
@ -71,7 +71,7 @@ func TestUnit(t *testing.T) {
t.Fatalf("Expected %v new hashes, got %v", hashCount, count) t.Fatalf("Expected %v new hashes, got %v", hashCount, count)
} }
// nuke hashes and reconstruct hash, ensure it's the same. // nuke hashes and reconstruct hash, ensure it's the same.
(&IAVLTree{root:n2}).Traverse(func(node Node) bool { (&IAVLTree{root: n2}).Traverse(func(node Node) bool {
node.(*IAVLNode).hash = nil node.(*IAVLNode).hash = nil
return false return false
}) })
@ -155,7 +155,7 @@ func TestIntegration(t *testing.T) {
var updated bool var updated bool
randomRecord := func() *record { randomRecord := func() *record {
return &record{ randstr(20), randstr(20) } return &record{randstr(20), randstr(20)}
} }
for i := range records { for i := range records {
@ -205,8 +205,8 @@ func TestIntegration(t *testing.T) {
t.Error("wrong value") t.Error("wrong value")
} }
} }
if tree.Size() != uint64(len(records) - (i+1)) { if tree.Size() != uint64(len(records)-(i+1)) {
t.Error("size was wrong", tree.Size(), (len(records) - (i+1))) t.Error("size was wrong", tree.Size(), (len(records) - (i + 1)))
} }
} }
} }
@ -216,7 +216,7 @@ func TestPersistence(t *testing.T) {
// Create some random key value pairs // Create some random key value pairs
records := make(map[String]String) records := make(map[String]String)
for i:=0; i<10000; i++ { for i := 0; i < 10000; i++ {
records[String(randstr(20))] = String(randstr(20)) records[String(randstr(20))] = String(randstr(20))
} }
@ -261,11 +261,11 @@ func BenchmarkImmutableAvlTree(b *testing.B) {
} }
randomRecord := func() *record { randomRecord := func() *record {
return &record{ randstr(32), randstr(32) } return &record{randstr(32), randstr(32)}
} }
t := NewIAVLTree(nil) t := NewIAVLTree(nil)
for i:=0; i<1000000; i++ { for i := 0; i < 1000000; i++ {
r := randomRecord() r := randomRecord()
t.Put(r.key, r.value) t.Put(r.key, r.value)
} }

View File

@ -4,7 +4,7 @@ import (
. "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/binary"
) )
const HASH_BYTE_SIZE int = 4+32 const HASH_BYTE_SIZE int = 4 + 32
/* /*
Immutable AVL Tree (wraps the Node root) Immutable AVL Tree (wraps the Node root)
@ -18,7 +18,7 @@ type IAVLTree struct {
} }
func NewIAVLTree(db Db) *IAVLTree { func NewIAVLTree(db Db) *IAVLTree {
return &IAVLTree{db:db, root:nil} return &IAVLTree{db: db, root: nil}
} }
func NewIAVLTreeFromHash(db Db, hash ByteSlice) *IAVLTree { func NewIAVLTreeFromHash(db Db, hash ByteSlice) *IAVLTree {
@ -27,7 +27,7 @@ func NewIAVLTreeFromHash(db Db, hash ByteSlice) *IAVLTree {
flags: IAVLNODE_FLAG_PERSISTED | IAVLNODE_FLAG_PLACEHOLDER, flags: IAVLNODE_FLAG_PERSISTED | IAVLNODE_FLAG_PLACEHOLDER,
} }
root.fill(db) root.fill(db)
return &IAVLTree{db:db, root:root} return &IAVLTree{db: db, root: root}
} }
func (t *IAVLTree) Root() Node { func (t *IAVLTree) Root() Node {
@ -35,17 +35,23 @@ func (t *IAVLTree) Root() Node {
} }
func (t *IAVLTree) Size() uint64 { func (t *IAVLTree) Size() uint64 {
if t.root == nil { return 0 } if t.root == nil {
return 0
}
return t.root.Size() return t.root.Size()
} }
func (t *IAVLTree) Height() uint8 { func (t *IAVLTree) Height() uint8 {
if t.root == nil { return 0 } if t.root == nil {
return 0
}
return t.root.Height() return t.root.Height()
} }
func (t *IAVLTree) Has(key Key) bool { func (t *IAVLTree) Has(key Key) bool {
if t.root == nil { return false } if t.root == nil {
return false
}
return t.root.has(t.db, key) return t.root.has(t.db, key)
} }
@ -59,12 +65,16 @@ func (t *IAVLTree) Put(key Key, value Value) (updated bool) {
} }
func (t *IAVLTree) Hash() (ByteSlice, uint64) { func (t *IAVLTree) Hash() (ByteSlice, uint64) {
if t.root == nil { return nil, 0 } if t.root == nil {
return nil, 0
}
return t.root.Hash() return t.root.Hash()
} }
func (t *IAVLTree) Save() { func (t *IAVLTree) Save() {
if t.root == nil { return } if t.root == nil {
return
}
if t.root.hash == nil { if t.root.hash == nil {
t.root.Hash() t.root.Hash()
} }
@ -72,12 +82,16 @@ func (t *IAVLTree) Save() {
} }
func (t *IAVLTree) Get(key Key) (value Value) { func (t *IAVLTree) Get(key Key) (value Value) {
if t.root == nil { return nil } if t.root == nil {
return nil
}
return t.root.get(t.db, key) return t.root.get(t.db, key)
} }
func (t *IAVLTree) Remove(key Key) (value Value, err error) { func (t *IAVLTree) Remove(key Key) (value Value, err error) {
if t.root == nil { return nil, NotFound(key) } if t.root == nil {
return nil, NotFound(key)
}
newRoot, _, value, err := t.root.remove(t.db, key) newRoot, _, value, err := t.root.remove(t.db, key)
if err != nil { if err != nil {
return nil, err return nil, err
@ -87,14 +101,16 @@ func (t *IAVLTree) Remove(key Key) (value Value, err error) {
} }
func (t *IAVLTree) Copy() Tree { func (t *IAVLTree) Copy() Tree {
return &IAVLTree{db:t.db, root:t.root} return &IAVLTree{db: t.db, root: t.root}
} }
// Traverses all the nodes of the tree in prefix order. // Traverses all the nodes of the tree in prefix order.
// return true from cb to halt iteration. // return true from cb to halt iteration.
// node.Height() == 0 if you just want a value node. // node.Height() == 0 if you just want a value node.
func (t *IAVLTree) Traverse(cb func(Node) bool) { func (t *IAVLTree) Traverse(cb func(Node) bool) {
if t.root == nil { return } if t.root == nil {
return
}
t.root.traverse(t.db, cb) t.root.traverse(t.db, cb)
} }
@ -103,7 +119,9 @@ func (t *IAVLTree) Values() <-chan Value {
ch := make(chan Value) ch := make(chan Value)
go func() { go func() {
root.traverse(t.db, func(n Node) bool { root.traverse(t.db, func(n Node) bool {
if n.Height() == 0 { ch <- n.Value() } if n.Height() == 0 {
ch <- n.Value()
}
return true return true
}) })
close(ch) close(ch)

View File

@ -1,8 +1,8 @@
package merkle package merkle
import ( import (
. "github.com/tendermint/tendermint/binary"
"fmt" "fmt"
. "github.com/tendermint/tendermint/binary"
) )
type Value interface { type Value interface {
@ -41,7 +41,7 @@ type Tree interface {
Put(Key, Value) bool Put(Key, Value) bool
Remove(Key) (Value, error) Remove(Key) (Value, error)
Copy() Tree Copy() Tree
Traverse(func(Node)bool) Traverse(func(Node) bool)
Values() <-chan Value Values() <-chan Value
} }

View File

@ -1,10 +1,10 @@
package merkle package merkle
import ( import (
"crypto/sha256"
"fmt"
. "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/binary"
"os" "os"
"fmt"
"crypto/sha256"
) )
/* /*
@ -17,14 +17,20 @@ func HashFromBinarySlice(items []Binary) ByteSlice {
case 1: case 1:
hasher := sha256.New() hasher := sha256.New()
_, err := items[0].WriteTo(hasher) _, err := items[0].WriteTo(hasher)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return ByteSlice(hasher.Sum(nil)) return ByteSlice(hasher.Sum(nil))
default: default:
hasher := sha256.New() hasher := sha256.New()
_, err := HashFromBinarySlice(items[0:len(items)/2]).WriteTo(hasher) _, err := HashFromBinarySlice(items[0 : len(items)/2]).WriteTo(hasher)
if err != nil { panic(err) } if err != nil {
panic(err)
}
_, err = HashFromBinarySlice(items[len(items)/2:]).WriteTo(hasher) _, err = HashFromBinarySlice(items[len(items)/2:]).WriteTo(hasher)
if err != nil { panic(err) } if err != nil {
panic(err)
}
return ByteSlice(hasher.Sum(nil)) return ByteSlice(hasher.Sum(nil))
} }
} }
@ -39,7 +45,7 @@ func PrintIAVLNode(node *IAVLNode) {
func printIAVLNode(node *IAVLNode, indent int) { func printIAVLNode(node *IAVLNode, indent int) {
indentPrefix := "" indentPrefix := ""
for i:=0; i<indent; i++ { for i := 0; i < indent; i++ {
indentPrefix += " " indentPrefix += " "
} }
@ -75,4 +81,3 @@ func maxUint8(a, b uint8) uint8 {
} }
return b return b
} }

View File

@ -5,19 +5,19 @@
package peer package peer
import ( import (
. "github.com/tendermint/tendermint/binary"
crand "crypto/rand" // for seeding crand "crypto/rand" // for seeding
"encoding/binary" "encoding/binary"
"encoding/json" "encoding/json"
"fmt"
. "github.com/tendermint/tendermint/binary"
"io" "io"
"math" "math"
"math/rand" "math/rand"
"net" "net"
"os"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
"os"
"fmt"
) )
/* AddrBook - concurrency safe peer address manager */ /* AddrBook - concurrency safe peer address manager */
@ -114,7 +114,9 @@ func (a *AddrBook) init() {
} }
func (a *AddrBook) Start() { func (a *AddrBook) Start() {
if atomic.AddInt32(&a.started, 1) != 1 { return } if atomic.AddInt32(&a.started, 1) != 1 {
return
}
log.Trace("Starting address manager") log.Trace("Starting address manager")
a.loadFromFile(a.filePath) a.loadFromFile(a.filePath)
a.wg.Add(1) a.wg.Add(1)
@ -122,14 +124,17 @@ func (a *AddrBook) Start() {
} }
func (a *AddrBook) Stop() { func (a *AddrBook) Stop() {
if atomic.AddInt32(&a.shutdown, 1) != 1 { return } if atomic.AddInt32(&a.shutdown, 1) != 1 {
return
}
log.Infof("Address manager shutting down") log.Infof("Address manager shutting down")
close(a.quit) close(a.quit)
a.wg.Wait() a.wg.Wait()
} }
func (a *AddrBook) AddAddress(addr *NetAddress, src *NetAddress) { func (a *AddrBook) AddAddress(addr *NetAddress, src *NetAddress) {
a.mtx.Lock(); defer a.mtx.Unlock() a.mtx.Lock()
defer a.mtx.Unlock()
a.addAddress(addr, src) a.addAddress(addr, src)
} }
@ -138,17 +143,25 @@ func (a *AddrBook) NeedMoreAddresses() bool {
} }
func (a *AddrBook) NumAddresses() int { func (a *AddrBook) NumAddresses() int {
a.mtx.Lock(); defer a.mtx.Unlock() a.mtx.Lock()
defer a.mtx.Unlock()
return a.nOld + a.nNew return a.nOld + a.nNew
} }
// Pick a new address to connect to. // Pick a new address to connect to.
func (a *AddrBook) PickAddress(class string, newBias int) *KnownAddress { func (a *AddrBook) PickAddress(class string, newBias int) *KnownAddress {
a.mtx.Lock(); defer a.mtx.Unlock() a.mtx.Lock()
defer a.mtx.Unlock()
if a.nOld == 0 && a.nNew == 0 { return nil } if a.nOld == 0 && a.nNew == 0 {
if newBias > 100 { newBias = 100 } return nil
if newBias < 0 { newBias = 0 } }
if newBias > 100 {
newBias = 100
}
if newBias < 0 {
newBias = 0
}
// Bias between new and old addresses. // Bias between new and old addresses.
oldCorrelation := math.Sqrt(float64(a.nOld)) * (100.0 - float64(newBias)) oldCorrelation := math.Sqrt(float64(a.nOld)) * (100.0 - float64(newBias))
@ -182,9 +195,12 @@ func (a *AddrBook) PickAddress(class string, newBias int) *KnownAddress {
} }
func (a *AddrBook) MarkGood(addr *NetAddress) { func (a *AddrBook) MarkGood(addr *NetAddress) {
a.mtx.Lock(); defer a.mtx.Unlock() a.mtx.Lock()
defer a.mtx.Unlock()
ka := a.addrIndex[addr.String()] ka := a.addrIndex[addr.String()]
if ka == nil { return } if ka == nil {
return
}
ka.MarkAttempt(true) ka.MarkAttempt(true)
if ka.OldBucket == -1 { if ka.OldBucket == -1 {
a.moveToOld(ka) a.moveToOld(ka)
@ -192,9 +208,12 @@ func (a *AddrBook) MarkGood(addr *NetAddress) {
} }
func (a *AddrBook) MarkAttempt(addr *NetAddress) { func (a *AddrBook) MarkAttempt(addr *NetAddress) {
a.mtx.Lock(); defer a.mtx.Unlock() a.mtx.Lock()
defer a.mtx.Unlock()
ka := a.addrIndex[addr.String()] ka := a.addrIndex[addr.String()]
if ka == nil { return } if ka == nil {
return
}
ka.MarkAttempt(false) ka.MarkAttempt(false)
} }
@ -225,13 +244,17 @@ func (a *AddrBook) saveToFile(filePath string) {
enc := json.NewEncoder(w) enc := json.NewEncoder(w)
defer w.Close() defer w.Close()
err = enc.Encode(&aJSON) err = enc.Encode(&aJSON)
if err != nil { panic(err) } if err != nil {
panic(err)
}
} }
func (a *AddrBook) loadFromFile(filePath string) { func (a *AddrBook) loadFromFile(filePath string) {
// If doesn't exist, do nothing. // If doesn't exist, do nothing.
_, err := os.Stat(filePath) _, err := os.Stat(filePath)
if os.IsNotExist(err) { return } if os.IsNotExist(err) {
return
}
// Load addrBookJSON{} // Load addrBookJSON{}
@ -266,7 +289,6 @@ func (a *AddrBook) loadFromFile(filePath string) {
} }
} }
/* Private methods */ /* Private methods */
func (a *AddrBook) addressHandler() { func (a *AddrBook) addressHandler() {
@ -287,15 +309,21 @@ out:
} }
func (a *AddrBook) addAddress(addr, src *NetAddress) { func (a *AddrBook) addAddress(addr, src *NetAddress) {
if !addr.Routable() { return } if !addr.Routable() {
return
}
key := addr.String() key := addr.String()
ka := a.addrIndex[key] ka := a.addrIndex[key]
if ka != nil { if ka != nil {
// Already added // Already added
if ka.OldBucket != -1 { return } if ka.OldBucket != -1 {
if ka.NewRefs == newBucketsPerAddress { return } return
}
if ka.NewRefs == newBucketsPerAddress {
return
}
// The more entries we have, the less likely we are to add more. // The more entries we have, the less likely we are to add more.
factor := int32(2 * ka.NewRefs) factor := int32(2 * ka.NewRefs)
@ -381,7 +409,9 @@ func (a *AddrBook) moveToOld(ka *KnownAddress) {
} }
} }
a.nNew-- a.nNew--
if freedBucket == -1 { panic("Expected to find addr in at least one new bucket") } if freedBucket == -1 {
panic("Expected to find addr in at least one new bucket")
}
oldBucket := a.getOldBucket(ka.Addr) oldBucket := a.getOldBucket(ka.Addr)
@ -469,12 +499,11 @@ func (a *AddrBook) getOldBucket(addr *NetAddress) int {
return int(binary.LittleEndian.Uint64(hash2) % oldBucketCount) return int(binary.LittleEndian.Uint64(hash2) % oldBucketCount)
} }
// Return a string representing the network group of this address. // Return a string representing the network group of this address.
// This is the /16 for IPv6, the /32 (/36 for he.net) for IPv6, the string // This is the /16 for IPv6, the /32 (/36 for he.net) for IPv6, the string
// "local" for a local address and the string "unroutable for an unroutable // "local" for a local address and the string "unroutable for an unroutable
// address. // address.
func GroupKey (na *NetAddress) string { func GroupKey(na *NetAddress) string {
if na.Local() { if na.Local() {
return "local" return "local"
} }

View File

@ -1,12 +1,12 @@
package peer package peer
import ( import (
. "github.com/tendermint/tendermint/common"
. "github.com/tendermint/tendermint/binary"
"github.com/tendermint/tendermint/merkle"
"sync/atomic"
"sync"
"errors" "errors"
. "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
"github.com/tendermint/tendermint/merkle"
"sync"
"sync/atomic"
) )
/* Client /* Client
@ -82,13 +82,17 @@ func (c *Client) Stop() {
} }
func (c *Client) AddPeerWithConnection(conn *Connection, outgoing bool) (*Peer, error) { func (c *Client) AddPeerWithConnection(conn *Connection, outgoing bool) (*Peer, error) {
if atomic.LoadUint32(&c.stopped) == 1 { return nil, CLIENT_STOPPED_ERROR } if atomic.LoadUint32(&c.stopped) == 1 {
return nil, CLIENT_STOPPED_ERROR
}
log.Infof("Adding peer with connection: %v, outgoing: %v", conn, outgoing) log.Infof("Adding peer with connection: %v, outgoing: %v", conn, outgoing)
peer := c.makePeerFn(conn) peer := c.makePeerFn(conn)
peer.outgoing = outgoing peer.outgoing = outgoing
err := c.addPeer(peer) err := c.addPeer(peer)
if err != nil { return nil, err } if err != nil {
return nil, err
}
go peer.Start(c.recvQueues) go peer.Start(c.recvQueues)
@ -96,7 +100,9 @@ func (c *Client) AddPeerWithConnection(conn *Connection, outgoing bool) (*Peer,
} }
func (c *Client) Broadcast(pkt Packet) { func (c *Client) Broadcast(pkt Packet) {
if atomic.LoadUint32(&c.stopped) == 1 { return } if atomic.LoadUint32(&c.stopped) == 1 {
return
}
log.Tracef("Broadcast on [%v] len: %v", pkt.Channel, len(pkt.Bytes)) log.Tracef("Broadcast on [%v] len: %v", pkt.Channel, len(pkt.Bytes))
for v := range c.Peers().Values() { for v := range c.Peers().Values() {
@ -112,11 +118,15 @@ func (c *Client) Broadcast(pkt Packet) {
// blocks until a message is popped. // blocks until a message is popped.
func (c *Client) Receive(chName String) *InboundPacket { func (c *Client) Receive(chName String) *InboundPacket {
if atomic.LoadUint32(&c.stopped) == 1 { return nil } if atomic.LoadUint32(&c.stopped) == 1 {
return nil
}
log.Tracef("Receive on [%v]", chName) log.Tracef("Receive on [%v]", chName)
q := c.recvQueues[chName] q := c.recvQueues[chName]
if q == nil { Panicf("Expected recvQueues[%f], found none", chName) } if q == nil {
Panicf("Expected recvQueues[%f], found none", chName)
}
for { for {
select { select {
@ -130,7 +140,8 @@ func (c *Client) Receive(chName String) *InboundPacket {
func (c *Client) Peers() merkle.Tree { func (c *Client) Peers() merkle.Tree {
// lock & defer // lock & defer
c.mtx.Lock(); defer c.mtx.Unlock() c.mtx.Lock()
defer c.mtx.Unlock()
return c.peers.Copy() return c.peers.Copy()
// unlock deferred // unlock deferred
} }
@ -152,8 +163,11 @@ func (c *Client) addPeer(peer *Peer) error {
addr := peer.RemoteAddress() addr := peer.RemoteAddress()
// lock & defer // lock & defer
c.mtx.Lock(); defer c.mtx.Unlock() c.mtx.Lock()
if c.stopped == 1 { return CLIENT_STOPPED_ERROR } defer c.mtx.Unlock()
if c.stopped == 1 {
return CLIENT_STOPPED_ERROR
}
if !c.peers.Has(addr) { if !c.peers.Has(addr) {
log.Tracef("Actually putting addr: %v, peer: %v", addr, peer) log.Tracef("Actually putting addr: %v, peer: %v", addr, peer)
c.peers.Put(addr, peer) c.peers.Put(addr, peer)

View File

@ -80,7 +80,6 @@ func TestClients(t *testing.T) {
c2.Stop() c2.Stop()
} }
func BenchmarkClients(b *testing.B) { func BenchmarkClients(b *testing.B) {
b.StopTimer() b.StopTimer()
@ -91,7 +90,7 @@ func BenchmarkClients(b *testing.B) {
// Create a sink on either channel to just pop off messages. // Create a sink on either channel to just pop off messages.
// TODO: ensure that when clients stop, this goroutine stops. // TODO: ensure that when clients stop, this goroutine stops.
func recvHandler(c *Client) { recvHandler := func(c *Client) {
} }
go recvHandler(c1) go recvHandler(c1)

View File

@ -1,12 +1,12 @@
package peer package peer
import ( import (
. "github.com/tendermint/tendermint/common"
. "github.com/tendermint/tendermint/binary"
"sync/atomic"
"net"
"time"
"fmt" "fmt"
. "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
"net"
"sync/atomic"
"time"
) )
const ( const (
@ -96,7 +96,7 @@ func (c *Connection) sendHandler() {
// TODO: catch panics & stop connection. // TODO: catch panics & stop connection.
FOR_LOOP: FOR_LOOP:
for { for {
var err error var err error
select { select {
@ -105,7 +105,9 @@ func (c *Connection) sendHandler() {
case sendPkt := <-c.sendQueue: case sendPkt := <-c.sendQueue:
log.Tracef("Found pkt from sendQueue. Writing pkt to underlying connection") log.Tracef("Found pkt from sendQueue. Writing pkt to underlying connection")
_, err = PACKET_TYPE_MSG.WriteTo(c.conn) _, err = PACKET_TYPE_MSG.WriteTo(c.conn)
if err != nil { break } if err != nil {
break
}
_, err = sendPkt.WriteTo(c.conn) _, err = sendPkt.WriteTo(c.conn)
case <-c.pong: case <-c.pong:
_, err = PACKET_TYPE_PONG.WriteTo(c.conn) _, err = PACKET_TYPE_PONG.WriteTo(c.conn)
@ -131,7 +133,7 @@ func (c *Connection) recvHandler(channels map[String]*Channel) {
// TODO: catch panics & stop connection. // TODO: catch panics & stop connection.
FOR_LOOP: FOR_LOOP:
for { for {
pktType, err := ReadUInt8Safe(c.conn) pktType, err := ReadUInt8Safe(c.conn)
if err != nil { if err != nil {
@ -178,7 +180,6 @@ func (c *Connection) recvHandler(channels map[String]*Channel) {
} }
} }
/* IOStats */ /* IOStats */
type IOStats struct { type IOStats struct {
TimeConnected Time TimeConnected Time

View File

@ -2,8 +2,8 @@ package peer
import ( import (
. "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/binary"
"time"
"io" "io"
"time"
) )
/* /*

View File

@ -2,8 +2,8 @@ package peer
import ( import (
. "github.com/tendermint/tendermint/common" . "github.com/tendermint/tendermint/common"
"sync/atomic"
"net" "net"
"sync/atomic"
) )
const ( const (
@ -18,7 +18,6 @@ type Listener interface {
Stop() Stop()
} }
/* DefaultListener */ /* DefaultListener */
type DefaultListener struct { type DefaultListener struct {
@ -33,7 +32,9 @@ const (
func NewDefaultListener(protocol string, listenAddr string) Listener { func NewDefaultListener(protocol string, listenAddr string) Listener {
listener, err := net.Listen(protocol, listenAddr) listener, err := net.Listen(protocol, listenAddr)
if err != nil { panic(err) } if err != nil {
panic(err)
}
dl := &DefaultListener{ dl := &DefaultListener{
listener: listener, listener: listener,
@ -49,11 +50,15 @@ func (l *DefaultListener) listenHandler() {
for { for {
conn, err := l.listener.Accept() conn, err := l.listener.Accept()
if atomic.LoadUint32(&l.stopped) == 1 { return } if atomic.LoadUint32(&l.stopped) == 1 {
return
}
// listener wasn't stopped, // listener wasn't stopped,
// yet we encountered an error. // yet we encountered an error.
if err != nil { panic(err) } if err != nil {
panic(err)
}
c := NewConnection(conn) c := NewConnection(conn)
l.connections <- c l.connections <- c
@ -80,15 +85,18 @@ func (l *DefaultListener) Stop() {
} }
} }
/* local address helpers */ /* local address helpers */
func GetLocalAddress() *NetAddress { func GetLocalAddress() *NetAddress {
laddr := GetUPNPLocalAddress() laddr := GetUPNPLocalAddress()
if laddr != nil { return laddr } if laddr != nil {
return laddr
}
laddr = GetDefaultLocalAddress() laddr = GetDefaultLocalAddress()
if laddr != nil { return laddr } if laddr != nil {
return laddr
}
panic("Could not determine local address") panic("Could not determine local address")
} }
@ -97,13 +105,19 @@ func GetLocalAddress() *NetAddress {
// TODO: more flexible internal & external ports // TODO: more flexible internal & external ports
func GetUPNPLocalAddress() *NetAddress { func GetUPNPLocalAddress() *NetAddress {
nat, err := Discover() nat, err := Discover()
if err != nil { return nil } if err != nil {
return nil
}
ext, err := nat.GetExternalAddress() ext, err := nat.GetExternalAddress()
if err != nil { return nil } if err != nil {
return nil
}
_, err = nat.AddPortMapping("tcp", DEFAULT_PORT, DEFAULT_PORT, "tendermint", 0) _, err = nat.AddPortMapping("tcp", DEFAULT_PORT, DEFAULT_PORT, "tendermint", 0)
if err != nil { return nil } if err != nil {
return nil
}
return NewNetAddressIPPort(ext, DEFAULT_PORT) return NewNetAddressIPPort(ext, DEFAULT_PORT)
} }
@ -112,16 +126,20 @@ func GetUPNPLocalAddress() *NetAddress {
// TODO: use syscalls to get actual ourIP. http://pastebin.com/9exZG4rh // TODO: use syscalls to get actual ourIP. http://pastebin.com/9exZG4rh
func GetDefaultLocalAddress() *NetAddress { func GetDefaultLocalAddress() *NetAddress {
addrs, err := net.InterfaceAddrs() addrs, err := net.InterfaceAddrs()
if err != nil { Panicf("Unexpected error fetching interface addresses: %v", err) } if err != nil {
Panicf("Unexpected error fetching interface addresses: %v", err)
}
for _, a := range addrs { for _, a := range addrs {
ipnet, ok := a.(*net.IPNet) ipnet, ok := a.(*net.IPNet)
if !ok { continue } if !ok {
continue
}
v4 := ipnet.IP.To4() v4 := ipnet.IP.To4()
if v4 == nil || v4[0] == 127 { continue } // loopback if v4 == nil || v4[0] == 127 {
continue
} // loopback
return NewNetAddressIPPort(ipnet.IP, DEFAULT_PORT) return NewNetAddressIPPort(ipnet.IP, DEFAULT_PORT)
} }
return nil return nil
} }

View File

@ -21,5 +21,7 @@ func init() {
var err error var err error
log, err = seelog.LoggerFromConfigAsBytes([]byte(config)) log, err = seelog.LoggerFromConfigAsBytes([]byte(config))
if err != nil { panic(err) } if err != nil {
panic(err)
}
} }

View File

@ -28,14 +28,17 @@ func (p Packet) WriteTo(w io.Writer) (n int64, err error) {
func ReadPacketSafe(r io.Reader) (pkt Packet, err error) { func ReadPacketSafe(r io.Reader) (pkt Packet, err error) {
chName, err := ReadStringSafe(r) chName, err := ReadStringSafe(r)
if err != nil { return } if err != nil {
return
}
// TODO: packet length sanity check. // TODO: packet length sanity check.
bytes, err := ReadByteSliceSafe(r) bytes, err := ReadByteSliceSafe(r)
if err != nil { return } if err != nil {
return
}
return NewPacket(chName, bytes), nil return NewPacket(chName, bytes), nil
} }
/* InboundPacket */ /* InboundPacket */
type InboundPacket struct { type InboundPacket struct {
@ -45,7 +48,6 @@ type InboundPacket struct {
Packet Packet
} }
/* NewFilterMsg */ /* NewFilterMsg */
type NewFilterMsg struct { type NewFilterMsg struct {

View File

@ -5,8 +5,8 @@
package peer package peer
import ( import (
. "github.com/tendermint/tendermint/common"
. "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
"io" "io"
"net" "net"
"strconv" "strconv"
@ -22,7 +22,9 @@ type NetAddress struct {
// TODO: socks proxies? // TODO: socks proxies?
func NewNetAddress(addr net.Addr) *NetAddress { func NewNetAddress(addr net.Addr) *NetAddress {
tcpAddr, ok := addr.(*net.TCPAddr) tcpAddr, ok := addr.(*net.TCPAddr)
if !ok { Panicf("Only TCPAddrs are supported. Got: %v", addr) } if !ok {
Panicf("Only TCPAddrs are supported. Got: %v", addr)
}
ip := tcpAddr.IP ip := tcpAddr.IP
port := UInt16(tcpAddr.Port) port := UInt16(tcpAddr.Port)
return NewNetAddressIPPort(ip, port) return NewNetAddressIPPort(ip, port)
@ -30,10 +32,14 @@ func NewNetAddress(addr net.Addr) *NetAddress {
func NewNetAddressString(addr string) *NetAddress { func NewNetAddressString(addr string) *NetAddress {
host, portStr, err := net.SplitHostPort(addr) host, portStr, err := net.SplitHostPort(addr)
if err != nil { panic(err) } if err != nil {
panic(err)
}
ip := net.ParseIP(host) ip := net.ParseIP(host)
port, err := strconv.ParseUint(portStr, 10, 16) port, err := strconv.ParseUint(portStr, 10, 16)
if err != nil { panic(err) } if err != nil {
panic(err)
}
na := NewNetAddressIPPort(ip, UInt16(port)) na := NewNetAddressIPPort(ip, UInt16(port))
return na return na
} }
@ -83,7 +89,9 @@ func (na *NetAddress) String() string {
func (na *NetAddress) Dial() (*Connection, error) { func (na *NetAddress) Dial() (*Connection, error) {
conn, err := net.Dial("tcp", na.String()) conn, err := net.Dial("tcp", na.String())
if err != nil { return nil, err } if err != nil {
return nil, err
}
return NewConnection(conn), nil return NewConnection(conn), nil
} }
@ -175,9 +183,11 @@ var rfc6052 = net.IPNet{IP: net.ParseIP("64:FF9B::"), Mask: net.CIDRMa
var rfc6145 = net.IPNet{IP: net.ParseIP("::FFFF:0:0:0"), Mask: net.CIDRMask(96, 128)} var rfc6145 = net.IPNet{IP: net.ParseIP("::FFFF:0:0:0"), Mask: net.CIDRMask(96, 128)}
var zero4 = net.IPNet{IP: net.ParseIP("0.0.0.0"), Mask: net.CIDRMask(8, 32)} var zero4 = net.IPNet{IP: net.ParseIP("0.0.0.0"), Mask: net.CIDRMask(8, 32)}
func (na *NetAddress) RFC1918() bool { return rfc1918_10.Contains(na.IP) || func (na *NetAddress) RFC1918() bool {
return rfc1918_10.Contains(na.IP) ||
rfc1918_192.Contains(na.IP) || rfc1918_192.Contains(na.IP) ||
rfc1918_172.Contains(na.IP) } rfc1918_172.Contains(na.IP)
}
func (na *NetAddress) RFC3849() bool { return rfc3849.Contains(na.IP) } func (na *NetAddress) RFC3849() bool { return rfc3849.Contains(na.IP) }
func (na *NetAddress) RFC3927() bool { return rfc3927.Contains(na.IP) } func (na *NetAddress) RFC3927() bool { return rfc3927.Contains(na.IP) }
func (na *NetAddress) RFC3964() bool { return rfc3964.Contains(na.IP) } func (na *NetAddress) RFC3964() bool { return rfc3964.Contains(na.IP) }

View File

@ -1,12 +1,12 @@
package peer package peer
import ( import (
. "github.com/tendermint/tendermint/binary"
"sync/atomic"
"sync"
"io"
"time"
"fmt" "fmt"
. "github.com/tendermint/tendermint/binary"
"io"
"sync"
"sync/atomic"
"time"
) )
/* Peer */ /* Peer */
@ -29,7 +29,7 @@ func NewPeer(conn *Connection) *Peer {
} }
} }
func (p *Peer) Start(peerRecvQueues map[String]chan *InboundPacket ) { func (p *Peer) Start(peerRecvQueues map[String]chan *InboundPacket) {
log.Debugf("Starting %v", p) log.Debugf("Starting %v", p)
p.conn.Start(p.channels) p.conn.Start(p.channels)
for chName, _ := range p.channels { for chName, _ := range p.channels {
@ -69,8 +69,11 @@ func (p *Peer) TrySend(pkt Packet) bool {
sendQueue := channel.SendQueue() sendQueue := channel.SendQueue()
// lock & defer // lock & defer
p.mtx.Lock(); defer p.mtx.Unlock() p.mtx.Lock()
if p.stopped == 1 { return false } defer p.mtx.Unlock()
if p.stopped == 1 {
return false
}
select { select {
case sendQueue <- pkt: case sendQueue <- pkt:
return true return true
@ -93,7 +96,7 @@ func (p *Peer) recvHandler(chName String, inboundPacketQueue chan<- *InboundPack
channel := p.channels[chName] channel := p.channels[chName]
recvQueue := channel.RecvQueue() recvQueue := channel.RecvQueue()
FOR_LOOP: FOR_LOOP:
for { for {
select { select {
case <-p.quit: case <-p.quit:
@ -123,7 +126,7 @@ func (p *Peer) recvHandler(chName String, inboundPacketQueue chan<- *InboundPack
func (p *Peer) sendHandler(chName String) { func (p *Peer) sendHandler(chName String) {
log.Tracef("%v sendHandler [%v]", p, chName) log.Tracef("%v sendHandler [%v]", p, chName)
chSendQueue := p.channels[chName].sendQueue chSendQueue := p.channels[chName].sendQueue
FOR_LOOP: FOR_LOOP:
for { for {
select { select {
case <-p.quit: case <-p.quit:
@ -141,7 +144,6 @@ func (p *Peer) sendHandler(chName String) {
// (none) // (none)
} }
/* Channel */ /* Channel */
type Channel struct { type Channel struct {

View File

@ -1,7 +1,6 @@
package peer package peer
import ( import ()
)
/* Server */ /* Server */