123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- // Copyright 2019 The go-ethereum Authors
- // This file is part of the go-ethereum library.
- //
- // The go-ethereum library is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Lesser General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // The go-ethereum library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Lesser General Public License for more details.
- //
- // You should have received a copy of the GNU Lesser General Public License
- // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
- package les
- import (
- "crypto/rand"
- "errors"
- "math/big"
- "reflect"
- "sort"
- "testing"
- "time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/forkid"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/enode"
- "github.com/ethereum/go-ethereum/params"
- )
- type testServerPeerSub struct {
- regCh chan *serverPeer
- unregCh chan *serverPeer
- }
- func newTestServerPeerSub() *testServerPeerSub {
- return &testServerPeerSub{
- regCh: make(chan *serverPeer, 1),
- unregCh: make(chan *serverPeer, 1),
- }
- }
- func (t *testServerPeerSub) registerPeer(p *serverPeer) { t.regCh <- p }
- func (t *testServerPeerSub) unregisterPeer(p *serverPeer) { t.unregCh <- p }
- func TestPeerSubscription(t *testing.T) {
- peers := newServerPeerSet()
- defer peers.close()
- checkIds := func(expect []string) {
- given := peers.ids()
- if len(given) == 0 && len(expect) == 0 {
- return
- }
- sort.Strings(given)
- sort.Strings(expect)
- if !reflect.DeepEqual(given, expect) {
- t.Fatalf("all peer ids mismatch, want %v, given %v", expect, given)
- }
- }
- checkPeers := func(peerCh chan *serverPeer) {
- select {
- case <-peerCh:
- case <-time.NewTimer(100 * time.Millisecond).C:
- t.Fatalf("timeout, no event received")
- }
- select {
- case <-peerCh:
- t.Fatalf("unexpected event received")
- case <-time.NewTimer(10 * time.Millisecond).C:
- }
- }
- checkIds([]string{})
- sub := newTestServerPeerSub()
- peers.subscribe(sub)
- // Generate a random id and create the peer
- var id enode.ID
- rand.Read(id[:])
- peer := newServerPeer(2, NetworkId, false, p2p.NewPeer(id, "name", nil), nil)
- peers.register(peer)
- checkIds([]string{peer.id})
- checkPeers(sub.regCh)
- peers.unregister(peer.id)
- checkIds([]string{})
- checkPeers(sub.unregCh)
- }
- type fakeChain struct{}
- func (f *fakeChain) Config() *params.ChainConfig { return params.MainnetChainConfig }
- func (f *fakeChain) Genesis() *types.Block {
- return core.DefaultGenesisBlock().ToBlock(rawdb.NewMemoryDatabase())
- }
- func (f *fakeChain) CurrentHeader() *types.Header { return &types.Header{Number: big.NewInt(10000000)} }
- func TestHandshake(t *testing.T) {
- // Create a message pipe to communicate through
- app, net := p2p.MsgPipe()
- // Generate a random id and create the peer
- var id enode.ID
- rand.Read(id[:])
- peer1 := newClientPeer(2, NetworkId, p2p.NewPeer(id, "name", nil), net)
- peer2 := newServerPeer(2, NetworkId, true, p2p.NewPeer(id, "name", nil), app)
- var (
- errCh1 = make(chan error, 1)
- errCh2 = make(chan error, 1)
- td = big.NewInt(100)
- head = common.HexToHash("deadbeef")
- headNum = uint64(10)
- genesis = common.HexToHash("cafebabe")
- chain1, chain2 = &fakeChain{}, &fakeChain{}
- forkID1 = forkid.NewID(chain1.Config(), chain1.Genesis().Hash(), chain1.CurrentHeader().Number.Uint64())
- forkID2 = forkid.NewID(chain2.Config(), chain2.Genesis().Hash(), chain2.CurrentHeader().Number.Uint64())
- filter1, filter2 = forkid.NewFilter(chain1), forkid.NewFilter(chain2)
- )
- go func() {
- errCh1 <- peer1.handshake(td, head, headNum, genesis, forkID1, filter1, func(list *keyValueList) {
- var announceType uint64 = announceTypeSigned
- *list = (*list).add("announceType", announceType)
- }, nil)
- }()
- go func() {
- errCh2 <- peer2.handshake(td, head, headNum, genesis, forkID2, filter2, nil, func(recv keyValueMap) error {
- var reqType uint64
- err := recv.get("announceType", &reqType)
- if err != nil {
- return err
- }
- if reqType != announceTypeSigned {
- return errors.New("Expected announceTypeSigned")
- }
- return nil
- })
- }()
- for i := 0; i < 2; i++ {
- select {
- case err := <-errCh1:
- if err != nil {
- t.Fatalf("handshake failed, %v", err)
- }
- case err := <-errCh2:
- if err != nil {
- t.Fatalf("handshake failed, %v", err)
- }
- case <-time.After(time.Second):
- t.Fatalf("timeout")
- }
- }
- }
|