aboutsummaryrefslogblamecommitdiffstats
path: root/eth/protocol_test.go
blob: a166ea6cdc210fbf2bcd864c9381a8d90f327baa (plain) (tree)
1
2
3
4
5
6
7
8
9







                                                    
                                                
















































                                                                                  
                                                                       
                                                      


                                                                                                                                                                                         






















                                                                                       


                                                                                    
         
 
 






                                                                     
                                                                                  
                                 
                                                  



              
                                                                                                                                                                                                    
                                
                                                                                                              



              





                                                    






                                                                                           






















                                                              




                                                                                
                                                                 







                                                       
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)
}