Commit c18ea4de authored by obscuren's avatar obscuren

Merge branch 'blockpool2' of https://github.com/ethersphere/go-ethereum into ethersphere-blockpool2

parents 37e6870f 16ecda95
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
package blockpool
import (
"testing"
"time"
"github.com/ethereum/go-ethereum/blockpool/test"
)
func TestBlockPoolConfig(t *testing.T) {
test.LogInit()
blockPool := &BlockPool{Config: &Config{}}
blockPool.Start()
c := blockPool.Config
test.CheckInt("BlockHashesBatchSize", c.BlockHashesBatchSize, blockHashesBatchSize, t)
test.CheckInt("BlockBatchSize", c.BlockBatchSize, blockBatchSize, t)
test.CheckInt("BlocksRequestRepetition", c.BlocksRequestRepetition, blocksRequestRepetition, t)
test.CheckInt("BlocksRequestMaxIdleRounds", c.BlocksRequestMaxIdleRounds, blocksRequestMaxIdleRounds, t)
test.CheckDuration("BlockHashesRequestInterval", c.BlockHashesRequestInterval, blockHashesRequestInterval, t)
test.CheckDuration("BlocksRequestInterval", c.BlocksRequestInterval, blocksRequestInterval, t)
test.CheckDuration("BlockHashesTimeout", c.BlockHashesTimeout, blockHashesTimeout, t)
test.CheckDuration("BlocksTimeout", c.BlocksTimeout, blocksTimeout, t)
}
func TestBlockPoolOverrideConfig(t *testing.T) {
test.LogInit()
blockPool := &BlockPool{Config: &Config{}}
c := &Config{128, 32, 1, 0, 300 * time.Millisecond, 100 * time.Millisecond, 90 * time.Second, 0}
blockPool.Config = c
blockPool.Start()
test.CheckInt("BlockHashesBatchSize", c.BlockHashesBatchSize, 128, t)
test.CheckInt("BlockBatchSize", c.BlockBatchSize, 32, t)
test.CheckInt("BlocksRequestRepetition", c.BlocksRequestRepetition, blocksRequestRepetition, t)
test.CheckInt("BlocksRequestMaxIdleRounds", c.BlocksRequestMaxIdleRounds, blocksRequestMaxIdleRounds, t)
test.CheckDuration("BlockHashesRequestInterval", c.BlockHashesRequestInterval, 300*time.Millisecond, t)
test.CheckDuration("BlocksRequestInterval", c.BlocksRequestInterval, 100*time.Millisecond, t)
test.CheckDuration("BlockHashesTimeout", c.BlockHashesTimeout, 90*time.Second, t)
test.CheckDuration("BlocksTimeout", c.BlocksTimeout, blocksTimeout, t)
}
package blockpool
import (
"testing"
"time"
"github.com/ethereum/go-ethereum/blockpool/test"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/pow"
)
func TestInvalidBlock(t *testing.T) {
test.LogInit()
_, blockPool, blockPoolTester := newTestBlockPool(t)
blockPoolTester.blockChain[0] = nil
blockPoolTester.initRefBlockChain(2)
blockPoolTester.refBlockChain[2] = []int{}
blockPool.Start()
peer1 := blockPoolTester.newPeer("peer1", 1, 3)
peer1.AddPeer()
go peer1.serveBlocks(2, 3)
go peer1.serveBlockHashes(3, 2, 1, 0)
peer1.serveBlocks(0, 1, 2)
blockPool.Wait(waitTimeout)
blockPool.Stop()
blockPoolTester.refBlockChain[2] = []int{}
blockPoolTester.checkBlockChain(blockPoolTester.refBlockChain)
if len(peer1.peerErrors) == 1 {
if peer1.peerErrors[0] != ErrInvalidBlock {
t.Errorf("wrong error, got %v, expected %v", peer1.peerErrors[0], ErrInvalidBlock)
}
} else {
t.Errorf("expected %v error, got %v", ErrInvalidBlock, peer1.peerErrors)
}
}
func TestVerifyPoW(t *testing.T) {
test.LogInit()
_, blockPool, blockPoolTester := newTestBlockPool(t)
blockPoolTester.blockChain[0] = nil
blockPoolTester.initRefBlockChain(3)
first := false
blockPoolTester.blockPool.verifyPoW = func(b pow.Block) bool {
bb, _ := b.(*types.Block)
indexes := blockPoolTester.hashPool.HashesToIndexes([][]byte{bb.Hash()})
if indexes[0] == 2 && !first {
first = true
return false
} else {
return true
}
}
blockPool.Start()
peer1 := blockPoolTester.newPeer("peer1", 1, 3)
peer2 := blockPoolTester.newPeer("peer2", 1, 3)
peer1.AddPeer()
peer2.AddPeer()
go peer1.serveBlocks(2, 3)
go peer1.serveBlockHashes(3, 2, 1, 0)
peer1.serveBlocks(0, 1, 2, 3)
blockPoolTester.blockPool.verifyPoW = func(b pow.Block) bool {
return true
}
peer2.serveBlocks(1, 2)
blockPool.Wait(waitTimeout)
blockPool.Stop()
blockPoolTester.refBlockChain[3] = []int{}
blockPoolTester.checkBlockChain(blockPoolTester.refBlockChain)
if len(peer1.peerErrors) == 1 {
if peer1.peerErrors[0] != ErrInvalidPoW {
t.Errorf("wrong error, expected %v, got %v", ErrInvalidPoW, peer1.peerErrors[0])
}
} else {
t.Errorf("expected %v error, got %v", ErrInvalidPoW, peer1.peerErrors)
}
}
func TestUnrequestedBlock(t *testing.T) {
test.LogInit()
_, blockPool, blockPoolTester := newTestBlockPool(t)
blockPoolTester.blockChain[0] = nil
blockPool.Start()
peer1 := blockPoolTester.newPeer("peer1", 1, 3)
peer1.AddPeer()
peer1.sendBlocks(1, 2)
// blockPool.Wait(waitTimeout)
blockPool.Stop()
if len(peer1.peerErrors) == 1 {
if peer1.peerErrors[0] != ErrUnrequestedBlock {
t.Errorf("wrong error, got %v, expected %v", peer1.peerErrors[0], ErrUnrequestedBlock)
}
} else {
t.Errorf("expected %v error, got %v", ErrUnrequestedBlock, peer1.peerErrors)
}
}
func TestErrInsufficientChainInfo(t *testing.T) {
test.LogInit()
_, blockPool, blockPoolTester := newTestBlockPool(t)
blockPool.Config.BlockHashesTimeout = 100 * time.Millisecond
blockPool.Start()
peer1 := blockPoolTester.newPeer("peer1", 1, 3)
peer1.AddPeer()
blockPool.Wait(waitTimeout)
blockPool.Stop()
if len(peer1.peerErrors) == 1 {
if peer1.peerErrors[0] != ErrInsufficientChainInfo {
t.Errorf("wrong error, got %v, expected %v", peer1.peerErrors[0], ErrInsufficientChainInfo)
}
} else {
t.Errorf("expected %v error, got %v", ErrInsufficientChainInfo, peer1.peerErrors)
}
}
This diff is collapsed.
package blockpool
import (
"math/big"
"testing"
"github.com/ethereum/go-ethereum/blockpool/test"
)
// the actual tests
func TestAddPeer(t *testing.T) {
test.LogInit()
_, blockPool, blockPoolTester := newTestBlockPool(t)
peer0 := blockPoolTester.newPeer("peer0", 1, 0)
peer1 := blockPoolTester.newPeer("peer1", 2, 1)
peer2 := blockPoolTester.newPeer("peer2", 3, 2)
var bestpeer *peer
blockPool.Start()
// pool
best := peer0.AddPeer()
if !best {
t.Errorf("peer0 (TD=1) not accepted as best")
}
if blockPool.peers.best.id != "peer0" {
t.Errorf("peer0 (TD=1) not set as best")
}
best = peer2.AddPeer()
if !best {
t.Errorf("peer2 (TD=3) not accepted as best")
}
if blockPool.peers.best.id != "peer2" {
t.Errorf("peer2 (TD=3) not set as best")
}
peer2.waitBlocksRequests(2)
best = peer1.AddPeer()
if best {
t.Errorf("peer1 (TD=2) accepted as best")
}
if blockPool.peers.best.id != "peer2" {
t.Errorf("peer2 (TD=3) not set any more as best")
}
if blockPool.peers.best.td.Cmp(big.NewInt(int64(3))) != 0 {
t.Errorf("peer1 TD not set")
}
peer2.td = 4
peer2.currentBlock = 3
best = peer2.AddPeer()
if !best {
t.Errorf("peer2 (TD=4) not accepted as best")
}
if blockPool.peers.best.id != "peer2" {
t.Errorf("peer2 (TD=4) not set as best")
}
if blockPool.peers.best.td.Cmp(big.NewInt(int64(4))) != 0 {
t.Errorf("peer2 TD not updated")
}
peer2.waitBlocksRequests(3)
peer1.td = 3
peer1.currentBlock = 2
best = peer1.AddPeer()
if best {
t.Errorf("peer1 (TD=3) should not be set as best")
}
if blockPool.peers.best.id == "peer1" {
t.Errorf("peer1 (TD=3) should not be set as best")
}
bestpeer, best = blockPool.peers.getPeer("peer1")
if bestpeer.td.Cmp(big.NewInt(int64(3))) != 0 {
t.Errorf("peer1 TD should be updated")
}
blockPool.RemovePeer("peer2")
bestpeer, best = blockPool.peers.getPeer("peer2")
if bestpeer != nil {
t.Errorf("peer2 not removed")
}
if blockPool.peers.best.id != "peer1" {
t.Errorf("existing peer1 (TD=3) should be set as best peer")
}
peer1.waitBlocksRequests(2)
blockPool.RemovePeer("peer1")
bestpeer, best = blockPool.peers.getPeer("peer1")
if bestpeer != nil {
t.Errorf("peer1 not removed")
}
if blockPool.peers.best.id != "peer0" {
t.Errorf("existing peer0 (TD=1) should be set as best peer")
}
peer0.waitBlocksRequests(0)
blockPool.RemovePeer("peer0")
bestpeer, best = blockPool.peers.getPeer("peer0")
if bestpeer != nil {
t.Errorf("peer1 not removed")
}
// adding back earlier peer ok
peer0.currentBlock = 3
best = peer0.AddPeer()
if !best {
t.Errorf("peer0 (TD=1) should be set as best")
}
if blockPool.peers.best.id != "peer0" {
t.Errorf("peer0 (TD=1) should be set as best")
}
peer0.waitBlocksRequests(3)
blockPool.Stop()
}
This diff is collapsed.
package blockpool
import (
"fmt"
"sync"
)
type statusValues struct {
BlockHashes int // number of hashes fetched this session
BlockHashesInPool int // number of hashes currently in the pool
Blocks int // number of blocks fetched this session
BlocksInPool int // number of blocks currently in the pool
BlocksInChain int // number of blocks inserted/connected to the blockchain this session
NewBlocks int // number of new blocks (received with new blocks msg) this session
Forks int // number of chain forks in the blockchain (poolchain) this session
LongestChain int // the longest chain inserted since the start of session (aka session blockchain height)
BestPeer []byte //Pubkey
Syncing bool // requesting, updating etc
Peers int // cumulative number of all different registered peers since the start of this session
ActivePeers int // cumulative number of all different peers that contributed a hash or block since the start of this session
LivePeers int // number of live peers registered with the block pool (supposed to be redundant but good sanity check
BestPeers int // cumulative number of all peers that at some point were promoted as best peer (peer with highest TD status) this session
BadPeers int // cumulative number of all peers that violated the protocol (invalid block or pow, unrequested hash or block, etc)
}
type status struct {
lock sync.Mutex
values statusValues
chain map[string]int
peers map[string]int
bestPeers map[string]int
badPeers map[string]int
activePeers map[string]int
}
func newStatus() *status {
return &status{
chain: make(map[string]int),
peers: make(map[string]int),
bestPeers: make(map[string]int),
badPeers: make(map[string]int),
activePeers: make(map[string]int),
}
}
type Status struct {
statusValues
}
// blockpool status for reporting
func (self *BlockPool) Status() *Status {
self.status.lock.Lock()
defer self.status.lock.Unlock()
self.status.values.BlockHashesInPool = len(self.pool)
self.status.values.ActivePeers = len(self.status.activePeers)
self.status.values.BestPeers = len(self.status.bestPeers)
self.status.values.BadPeers = len(self.status.badPeers)
self.status.values.LivePeers = len(self.peers.peers)
self.status.values.Peers = len(self.status.peers)
self.status.values.BlockHashesInPool = len(self.pool)
return &Status{self.status.values}
}
func (self *Status) String() string {
return fmt.Sprintf(`
Syncing: %v
BlockHashes: %v
BlockHashesInPool: %v
Blocks: %v
BlocksInPool: %v
BlocksInChain: %v
NewBlocks: %v
Forks: %v
LongestChain: %v
Peers: %v
LivePeers: %v
ActivePeers: %v
BestPeers: %v
BadPeers: %v
`,
self.Syncing,
self.BlockHashes,
self.BlockHashesInPool,
self.Blocks,
self.BlocksInPool,
self.BlocksInChain,
self.NewBlocks,
self.Forks,
self.LongestChain,
self.Peers,
self.LivePeers,
self.ActivePeers,
self.BestPeers,
self.BadPeers,
)
}
func (self *BlockPool) syncing() {
self.status.lock.Lock()
defer self.status.lock.Unlock()
if !self.status.values.Syncing {
self.status.values.Syncing = true
go func() {
self.wg.Wait()
self.status.lock.Lock()
self.status.values.Syncing = false
self.status.lock.Unlock()
}()
}
}
package blockpool
import (
"fmt"
"testing"
// "time"
"github.com/ethereum/go-ethereum/blockpool/test"
)
var statusFields = []string{
"BlockHashes",
"BlockHashesInPool",
"Blocks",
"BlocksInPool",
"BlocksInChain",
"NewBlocks",
"Forks",
"LongestChain",
"Peers",
"LivePeers",
"ActivePeers",
"BestPeers",
"BadPeers",
}
func getStatusValues(s *Status) []int {
return []int{
s.BlockHashes,
s.BlockHashesInPool,
s.Blocks,
s.BlocksInPool,
s.BlocksInChain,
s.NewBlocks,
s.Forks,
s.LongestChain,
s.Peers,
s.LivePeers,
s.ActivePeers,
s.BestPeers,
s.BadPeers,
}
}
func checkStatus(t *testing.T, bp *BlockPool, syncing bool, expected []int) (err error) {
s := bp.Status()
if s.Syncing != syncing {
t.Errorf("status for Syncing incorrect. expected %v, got %v", syncing, s.Syncing)
}
got := getStatusValues(s)
for i, v := range expected {
err = test.CheckInt(statusFields[i], got[i], v, t)
if err != nil {
return err
}
fmt.Printf("%v: %v (%v)\n", statusFields[i], got[i], v)
}
return
}
// func TestBlockPoolStatus(t *testing.T) {
// test.LogInit()
// _, blockPool, blockPoolTester := newTestBlockPool(t)
// blockPoolTester.blockChain[0] = nil
// blockPoolTester.initRefBlockChain(12)
// blockPoolTester.refBlockChain[3] = []int{4, 7}
// delete(blockPoolTester.refBlockChain, 6)
// blockPool.Start()
// peer1 := blockPoolTester.newPeer("peer1", 1, 9)
// peer2 := blockPoolTester.newPeer("peer2", 2, 6)
// peer3 := blockPoolTester.newPeer("peer3", 3, 11)
// peer4 := blockPoolTester.newPeer("peer4", 1, 9)
// peer2.blocksRequestsMap = peer1.blocksRequestsMap
// var expected []int
// var err error
// expected = []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
// err = checkStatus(t, blockPool, false, expected)
// if err != nil {
// return
// }
// peer1.AddPeer()
// expected = []int{0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer1.serveBlocks(8, 9)
// expected = []int{0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer1.serveBlockHashes(9, 8, 7, 3, 2)
// expected = []int{5, 5, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer1.serveBlocks(3, 7, 8)
// expected = []int{5, 5, 3, 3, 0, 1, 0, 0, 1, 1, 1, 1, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer1.serveBlocks(2, 3)
// expected = []int{5, 5, 4, 4, 0, 1, 0, 0, 1, 1, 1, 1, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer4.AddPeer()
// expected = []int{5, 5, 4, 4, 0, 2, 0, 0, 2, 2, 1, 1, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer4.sendBlockHashes(12, 11)
// expected = []int{5, 5, 4, 4, 0, 2, 0, 0, 2, 2, 1, 1, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer2.AddPeer()
// expected = []int{5, 5, 4, 4, 0, 3, 0, 0, 3, 3, 1, 2, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer2.serveBlocks(5, 6)
// peer2.serveBlockHashes(6, 5, 4, 3, 2)
// expected = []int{8, 8, 5, 5, 0, 3, 1, 0, 3, 3, 2, 2, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer2.serveBlocks(2, 3, 4)
// expected = []int{8, 8, 6, 6, 0, 3, 1, 0, 3, 3, 2, 2, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// blockPool.RemovePeer("peer2")
// expected = []int{8, 8, 6, 6, 0, 3, 1, 0, 3, 2, 2, 2, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer1.serveBlockHashes(2, 1, 0)
// expected = []int{9, 9, 6, 6, 0, 3, 1, 0, 3, 2, 2, 2, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer1.serveBlocks(1, 2)
// expected = []int{9, 9, 7, 7, 0, 3, 1, 0, 3, 2, 2, 2, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer1.serveBlocks(4, 5)
// expected = []int{9, 9, 8, 8, 0, 3, 1, 0, 3, 2, 2, 2, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer3.AddPeer()
// expected = []int{9, 9, 8, 8, 0, 4, 1, 0, 4, 3, 2, 3, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer3.serveBlocks(10, 11)
// expected = []int{9, 9, 9, 9, 0, 4, 1, 0, 4, 3, 3, 3, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer3.serveBlockHashes(11, 10, 9)
// expected = []int{11, 11, 9, 9, 0, 4, 1, 0, 4, 3, 3, 3, 0}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer4.sendBlocks(11, 12)
// expected = []int{11, 11, 9, 9, 0, 4, 1, 0, 4, 3, 4, 3, 1}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer3.serveBlocks(9, 10)
// expected = []int{11, 11, 10, 10, 0, 4, 1, 0, 4, 3, 4, 3, 1}
// err = checkStatus(t, blockPool, true, expected)
// if err != nil {
// return
// }
// peer3.serveBlocks(0, 1)
// blockPool.Wait(waitTimeout)
// time.Sleep(200 * time.Millisecond)
// expected = []int{11, 3, 11, 3, 8, 4, 1, 8, 4, 3, 4, 3, 1}
// err = checkStatus(t, blockPool, false, expected)
// if err != nil {
// return
// }
// blockPool.Stop()
// }
package test
import (
"sync"
"github.com/ethereum/go-ethereum/crypto"
)
// test helpers
// TODO: move into common test helper package (see p2p/crypto etc.)
func NewHashPool() *TestHashPool {
return &TestHashPool{intToHash: make(intToHash), hashToInt: make(hashToInt)}
}
type intToHash map[int][]byte
type hashToInt map[string]int
// hashPool is a test helper, that allows random hashes to be referred to by integers
type TestHashPool struct {
intToHash
hashToInt
lock sync.Mutex
}
func newHash(i int) []byte {
return crypto.Sha3([]byte(string(i)))
}
func (self *TestHashPool) IndexesToHashes(indexes []int) (hashes [][]byte) {
self.lock.Lock()
defer self.lock.Unlock()
for _, i := range indexes {
hash, found := self.intToHash[i]
if !found {
hash = newHash(i)
self.intToHash[i] = hash
self.hashToInt[string(hash)] = i
}
hashes = append(hashes, hash)
}
return
}
func (self *TestHashPool) HashesToIndexes(hashes [][]byte) (indexes []int) {
self.lock.Lock()
defer self.lock.Unlock()
for _, hash := range hashes {
i, found := self.hashToInt[string(hash)]
if !found {
i = -1
}
indexes = append(indexes, i)
}
return
}
package test
import (
"log"
"os"
"sync"
"testing"
"github.com/ethereum/go-ethereum/logger"
)
var once sync.Once
/* usage:
func TestFunc(t *testing.T) {
test.LogInit()
// test
}
*/
func LogInit() {
once.Do(func() {
var logsys = logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.LogLevel(logger.DebugDetailLevel))
logger.AddLogSystem(logsys)
})
}
type testLogger struct{ t *testing.T }
/* usage:
func TestFunc(t *testing.T) {
defer test.Testlog.Detach()
// test
}
*/
func Testlog(t *testing.T) testLogger {
logger.Reset()
l := testLogger{t}
logger.AddLogSystem(l)
return l
}
func (testLogger) GetLogLevel() logger.LogLevel { return logger.DebugLevel }
func (testLogger) SetLogLevel(logger.LogLevel) {}
func (l testLogger) LogPrint(level logger.LogLevel, msg string) {
l.t.Logf("%s", msg)
}
func (testLogger) Detach() {
logger.Flush()
logger.Reset()
}
type benchLogger struct{ b *testing.B }
/* usage:
func BenchmarkFunc(b *testing.B) {
defer test.Benchlog.Detach()
// test
}
*/
func Benchlog(b *testing.B) benchLogger {
logger.Reset()
l := benchLogger{b}
logger.AddLogSystem(l)
return l
}
func (benchLogger) GetLogLevel() logger.LogLevel { return logger.Silence }
func (benchLogger) SetLogLevel(logger.LogLevel) {}
func (l benchLogger) LogPrint(level logger.LogLevel, msg string) {
l.b.Logf("%s", msg)
}
func (benchLogger) Detach() {
logger.Flush()
logger.Reset()
}
package test
import (
"fmt"
"testing"
"time"
)
func CheckInt(name string, got int, expected int, t *testing.T) (err error) {
if got != expected {
t.Errorf("status for %v incorrect. expected %v, got %v", name, expected, got)
err = fmt.Errorf("")
}
return
}
func CheckDuration(name string, got time.Duration, expected time.Duration, t *testing.T) (err error) {
if got != expected {
t.Errorf("status for %v incorrect. expected %v, got %v", name, expected, got)
err = fmt.Errorf("")
}
return
}
func ArrayEq(a, b []int) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
package errs
import (
"fmt"
"github.com/ethereum/go-ethereum/logger"
)
/*
Errors implements an error handler providing standardised errors for a package.
Fields:
Errors:
a map from error codes to description
Package:
name of the package/component
Level:
a function mapping error code to logger.LogLevel (severity)
if not given, errors default to logger.InfoLevel
*/
type Errors struct {
Errors map[int]string
Package string
Level func(code int) logger.LogLevel
}
/*
Error implements the standard go error interface.
errors.New(code, format, params ...interface{})
Prints as:
[package] description: details
where details is fmt.Sprintf(self.format, self.params...)
*/
type Error struct {
Code int
Name string
Package string
level logger.LogLevel
message string
format string
params []interface{}
}
func (self *Errors) New(code int, format string, params ...interface{}) *Error {
name, ok := self.Errors[code]
if !ok {
panic("invalid error code")
}
level := logger.InfoLevel
if self.Level != nil {
level = self.Level(code)
}
return &Error{
Code: code,
Name: name,
Package: self.Package,
level: level,
format: format,
params: params,
}
}
func (self Error) Error() (message string) {
if len(message) == 0 {
self.message = fmt.Sprintf("[%s] %s", self.Package, self.Name)
if self.format != "" {
self.message += ": " + fmt.Sprintf(self.format, self.params...)
}
}
return self.message
}
func (self Error) Log(log *logger.Logger) {
log.Sendln(self.level, self)
}
/*
err.Fatal() is true if err's severity level is 0 or 1 (logger.ErrorLevel or logger.Silence)
*/
func (self *Error) Fatal() (fatal bool) {
if self.level < logger.WarnLevel {
fatal = true
}
return
}
package errs
import (
"fmt"
"testing"
"github.com/ethereum/go-ethereum/logger"
)
func testErrors() *Errors {
return &Errors{
Package: "TEST",
Errors: map[int]string{
0: "zero",
1: "one",
},
Level: func(i int) (l logger.LogLevel) {
if i == 0 {
l = logger.ErrorLevel
} else {
l = logger.WarnLevel
}
return
},
}
}
func TestErrorMessage(t *testing.T) {
err := testErrors().New(0, "zero detail %v", "available")
message := fmt.Sprintf("%v", err)
exp := "[TEST] zero: zero detail available"
if message != exp {
t.Errorf("error message incorrect. expected %v, got %v", exp, message)
}
}
func TestErrorSeverity(t *testing.T) {
err0 := testErrors().New(0, "zero detail")
if !err0.Fatal() {
t.Errorf("error should be fatal")
}
err1 := testErrors().New(1, "one detail")
if err1.Fatal() {
t.Errorf("error should not be fatal")
}
}
......@@ -7,6 +7,7 @@ import (
"path"
"strings"
"github.com/ethereum/go-ethereum/blockpool"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
......@@ -117,7 +118,7 @@ type Ethereum struct {
blockProcessor *core.BlockProcessor
txPool *core.TxPool
chainManager *core.ChainManager
blockPool *BlockPool
blockPool *blockpool.BlockPool
whisper *whisper.Whisper
net *p2p.Server
......@@ -185,7 +186,7 @@ func New(config *Config) (*Ethereum, error) {
hasBlock := eth.chainManager.HasBlock
insertChain := eth.chainManager.InsertChain
eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify)
eth.blockPool = blockpool.New(hasBlock, insertChain, ezp.Verify)
netprv, err := config.nodeKey()
if err != nil {
......@@ -220,7 +221,7 @@ func (s *Ethereum) Name() string { return s.net.Name }
func (s *Ethereum) ChainManager() *core.ChainManager { return s.chainManager }
func (s *Ethereum) BlockProcessor() *core.BlockProcessor { return s.blockProcessor }
func (s *Ethereum) TxPool() *core.TxPool { return s.txPool }
func (s *Ethereum) BlockPool() *BlockPool { return s.blockPool }
func (s *Ethereum) BlockPool() *blockpool.BlockPool { return s.blockPool }
func (s *Ethereum) Whisper() *whisper.Whisper { return s.whisper }
func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
func (s *Ethereum) Db() ethutil.Database { return s.db }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#!/bin/bash
# bootstrap chains - used to regenerate tests/chains/*.chain
mkdir -p chains
bash ./mine.sh 00 10
bash ./mine.sh 01 5 00
bash ./mine.sh 02 10 00
bash ./mine.sh 03 5 02
bash ./mine.sh 04 10 02
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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