- changed backend interface - using callbacks for blockPool - use rlp stream for lazy decoding - use peer as logger - add id (peer pubkey) to ethProtocol fields - add testPeer to protocol test (temporary)
		
			
				
	
	
		
			164 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package eth
 | |
| 
 | |
| import (
 | |
| 	"io"
 | |
| 	"math/big"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/ethereum/go-ethereum/core/types"
 | |
| 	"github.com/ethereum/go-ethereum/crypto"
 | |
| 	"github.com/ethereum/go-ethereum/p2p"
 | |
| )
 | |
| 
 | |
| type testMsgReadWriter struct {
 | |
| 	in  chan p2p.Msg
 | |
| 	out chan p2p.Msg
 | |
| }
 | |
| 
 | |
| func (self *testMsgReadWriter) In(msg p2p.Msg) {
 | |
| 	self.in <- msg
 | |
| }
 | |
| 
 | |
| func (self *testMsgReadWriter) Out(msg p2p.Msg) {
 | |
| 	self.in <- msg
 | |
| }
 | |
| 
 | |
| func (self *testMsgReadWriter) WriteMsg(msg p2p.Msg) error {
 | |
| 	self.out <- msg
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (self *testMsgReadWriter) EncodeMsg(code uint64, data ...interface{}) error {
 | |
| 	return self.WriteMsg(p2p.NewMsg(code, data))
 | |
| }
 | |
| 
 | |
| func (self *testMsgReadWriter) ReadMsg() (p2p.Msg, error) {
 | |
| 	msg, ok := <-self.in
 | |
| 	if !ok {
 | |
| 		return msg, io.EOF
 | |
| 	}
 | |
| 	return msg, nil
 | |
| }
 | |
| 
 | |
| func errorCheck(t *testing.T, expCode int, err error) {
 | |
| 	perr, ok := err.(*protocolError)
 | |
| 	if ok && perr != nil {
 | |
| 		if code := perr.Code; code != expCode {
 | |
| 			ok = false
 | |
| 		}
 | |
| 	}
 | |
| 	if !ok {
 | |
| 		t.Errorf("expected error code %v, got %v", ErrNoStatusMsg, err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type TestBackend struct {
 | |
| 	getTransactions func() []*types.Transaction
 | |
| 	addTransactions func(txs []*types.Transaction)
 | |
| 	getBlockHashes  func(hash []byte, amount uint32) (hashes [][]byte)
 | |
| 	addBlockHashes  func(next func() ([]byte, bool), peerId string)
 | |
| 	getBlock        func(hash []byte) *types.Block
 | |
| 	addBlock        func(block *types.Block, peerId string) (err error)
 | |
| 	addPeer         func(td *big.Int, currentBlock []byte, peerId string, requestHashes func([]byte) error, requestBlocks func([][]byte) error, invalidBlock func(error)) (best bool)
 | |
| 	removePeer      func(peerId string)
 | |
| 	status          func() (td *big.Int, currentBlock []byte, genesisBlock []byte)
 | |
| }
 | |
| 
 | |
| func (self *TestBackend) GetTransactions() (txs []*types.Transaction) {
 | |
| 	if self.getTransactions != nil {
 | |
| 		txs = self.getTransactions()
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (self *TestBackend) AddTransactions(txs []*types.Transaction) {
 | |
| 	if self.addTransactions != nil {
 | |
| 		self.addTransactions(txs)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (self *TestBackend) GetBlockHashes(hash []byte, amount uint32) (hashes [][]byte) {
 | |
| 	if self.getBlockHashes != nil {
 | |
| 		hashes = self.getBlockHashes(hash, amount)
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (self *TestBackend) AddBlockHashes(next func() ([]byte, bool), peerId string) {
 | |
| 	if self.addBlockHashes != nil {
 | |
| 		self.addBlockHashes(next, peerId)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (self *TestBackend) GetBlock(hash []byte) (block *types.Block) {
 | |
| 	if self.getBlock != nil {
 | |
| 		block = self.getBlock(hash)
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (self *TestBackend) AddBlock(block *types.Block, peerId string) (err error) {
 | |
| 	if self.addBlock != nil {
 | |
| 		err = self.addBlock(block, peerId)
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (self *TestBackend) AddPeer(td *big.Int, currentBlock []byte, peerId string, requestBlockHashes func([]byte) error, requestBlocks func([][]byte) error, invalidBlock func(error)) (best bool) {
 | |
| 	if self.addPeer != nil {
 | |
| 		best = self.addPeer(td, currentBlock, peerId, requestBlockHashes, requestBlocks, invalidBlock)
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (self *TestBackend) RemovePeer(peerId string) {
 | |
| 	if self.removePeer != nil {
 | |
| 		self.removePeer(peerId)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (self *TestBackend) Status() (td *big.Int, currentBlock []byte, genesisBlock []byte) {
 | |
| 	if self.status != nil {
 | |
| 		td, currentBlock, genesisBlock = self.status()
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // TODO: refactor this into p2p/client_identity
 | |
| type peerId struct {
 | |
| 	pubkey []byte
 | |
| }
 | |
| 
 | |
| func (self *peerId) String() string {
 | |
| 	return "test peer"
 | |
| }
 | |
| 
 | |
| func (self *peerId) Pubkey() (pubkey []byte) {
 | |
| 	pubkey = self.pubkey
 | |
| 	if len(pubkey) == 0 {
 | |
| 		pubkey = crypto.GenerateNewKeyPair().PublicKey
 | |
| 		self.pubkey = pubkey
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func testPeer() *p2p.Peer {
 | |
| 	return p2p.NewPeer(&peerId{}, []p2p.Cap{})
 | |
| }
 | |
| 
 | |
| func TestErrNoStatusMsg(t *testing.T) {
 | |
| 	quit := make(chan bool)
 | |
| 	rw := &testMsgReadWriter{make(chan p2p.Msg, 10), make(chan p2p.Msg, 10)}
 | |
| 	testBackend := &TestBackend{}
 | |
| 	var err error
 | |
| 	go func() {
 | |
| 		err = runEthProtocol(testBackend, testPeer(), rw)
 | |
| 		close(quit)
 | |
| 	}()
 | |
| 	statusMsg := p2p.NewMsg(4)
 | |
| 	rw.In(statusMsg)
 | |
| 	<-quit
 | |
| 	errorCheck(t, ErrNoStatusMsg, err)
 | |
| 	// read(t, remote, []byte("hello, world"), nil)
 | |
| }
 |