github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/les/ulc_test.go (about)

     1  package les
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"fmt"
     6  	"math/big"
     7  	"net"
     8  	"reflect"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/ethereum/go-ethereum/common/mclock"
    13  	"github.com/ethereum/go-ethereum/core"
    14  	"github.com/ethereum/go-ethereum/core/rawdb"
    15  	"github.com/ethereum/go-ethereum/crypto"
    16  	"github.com/ethereum/go-ethereum/eth"
    17  	"github.com/ethereum/go-ethereum/light"
    18  	"github.com/ethereum/go-ethereum/p2p"
    19  	"github.com/ethereum/go-ethereum/p2p/enode"
    20  )
    21  
    22  func TestULCSyncWithOnePeer(t *testing.T) {
    23  	f := newFullPeerPair(t, 1, 4, testChainGen)
    24  	ulcConfig := &eth.ULCConfig{
    25  		MinTrustedFraction: 100,
    26  		TrustedServers:     []string{f.Node.String()},
    27  	}
    28  
    29  	l := newLightPeer(t, ulcConfig)
    30  
    31  	if reflect.DeepEqual(f.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) {
    32  		t.Fatal("blocks are equal")
    33  	}
    34  
    35  	_, _, err := connectPeers(f, l, 2)
    36  	if err != nil {
    37  		t.Fatal(err)
    38  	}
    39  
    40  	l.PM.fetcher.lock.Lock()
    41  	l.PM.fetcher.nextRequest()
    42  	l.PM.fetcher.lock.Unlock()
    43  
    44  	if !reflect.DeepEqual(f.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) {
    45  		t.Fatal("sync doesn't work")
    46  	}
    47  }
    48  
    49  func TestULCReceiveAnnounce(t *testing.T) {
    50  	f := newFullPeerPair(t, 1, 4, testChainGen)
    51  	ulcConfig := &eth.ULCConfig{
    52  		MinTrustedFraction: 100,
    53  		TrustedServers:     []string{f.Node.String()},
    54  	}
    55  
    56  	l := newLightPeer(t, ulcConfig)
    57  	fPeer, lPeer, err := connectPeers(f, l, 2)
    58  	if err != nil {
    59  		t.Fatal(err)
    60  	}
    61  
    62  	l.PM.synchronise(fPeer)
    63  
    64  	//check that the sync is finished correctly
    65  	if !reflect.DeepEqual(f.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) {
    66  		t.Fatal("sync doesn't work")
    67  	}
    68  
    69  	l.PM.peers.lock.Lock()
    70  	if len(l.PM.peers.peers) == 0 {
    71  		t.Fatal("peer list should not be empty")
    72  	}
    73  	l.PM.peers.lock.Unlock()
    74  
    75  	time.Sleep(time.Second)
    76  	//send a signed announce message(payload doesn't matter)
    77  	td := f.PM.blockchain.GetTd(l.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Number.Uint64())
    78  	announce := announceData{
    79  		Number: l.PM.blockchain.CurrentHeader().Number.Uint64() + 1,
    80  		Td:     td.Add(td, big.NewInt(1)),
    81  	}
    82  	announce.sign(f.Key)
    83  	lPeer.SendAnnounce(announce)
    84  }
    85  
    86  func TestULCShouldNotSyncWithTwoPeersOneHaveEmptyChain(t *testing.T) {
    87  	f1 := newFullPeerPair(t, 1, 4, testChainGen)
    88  	f2 := newFullPeerPair(t, 2, 0, nil)
    89  	ulcConf := &ulc{minTrustedFraction: 100, trustedKeys: make(map[string]struct{})}
    90  	ulcConf.trustedKeys[f1.Node.ID().String()] = struct{}{}
    91  	ulcConf.trustedKeys[f2.Node.ID().String()] = struct{}{}
    92  	ulcConfig := &eth.ULCConfig{
    93  		MinTrustedFraction: 100,
    94  		TrustedServers:     []string{f1.Node.String(), f2.Node.String()},
    95  	}
    96  	l := newLightPeer(t, ulcConfig)
    97  	l.PM.ulc.minTrustedFraction = 100
    98  
    99  	_, _, err := connectPeers(f1, l, 2)
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  	_, _, err = connectPeers(f2, l, 2)
   104  	if err != nil {
   105  		t.Fatal(err)
   106  	}
   107  
   108  	l.PM.fetcher.lock.Lock()
   109  	l.PM.fetcher.nextRequest()
   110  	l.PM.fetcher.lock.Unlock()
   111  
   112  	if reflect.DeepEqual(f2.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) {
   113  		t.Fatal("Incorrect hash: second peer has empty chain")
   114  	}
   115  }
   116  
   117  func TestULCShouldNotSyncWithThreePeersOneHaveEmptyChain(t *testing.T) {
   118  	f1 := newFullPeerPair(t, 1, 3, testChainGen)
   119  	f2 := newFullPeerPair(t, 2, 4, testChainGen)
   120  	f3 := newFullPeerPair(t, 3, 0, nil)
   121  
   122  	ulcConfig := &eth.ULCConfig{
   123  		MinTrustedFraction: 60,
   124  		TrustedServers:     []string{f1.Node.String(), f2.Node.String(), f3.Node.String()},
   125  	}
   126  
   127  	l := newLightPeer(t, ulcConfig)
   128  	_, _, err := connectPeers(f1, l, 2)
   129  	if err != nil {
   130  		t.Fatal(err)
   131  	}
   132  
   133  	_, _, err = connectPeers(f2, l, 2)
   134  	if err != nil {
   135  		t.Fatal(err)
   136  	}
   137  
   138  	_, _, err = connectPeers(f3, l, 2)
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  
   143  	l.PM.fetcher.lock.Lock()
   144  	l.PM.fetcher.nextRequest()
   145  	l.PM.fetcher.lock.Unlock()
   146  
   147  	if !reflect.DeepEqual(f1.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) {
   148  		t.Fatal("Incorrect hash")
   149  	}
   150  }
   151  
   152  type pairPeer struct {
   153  	Name string
   154  	Node *enode.Node
   155  	PM   *ProtocolManager
   156  	Key  *ecdsa.PrivateKey
   157  }
   158  
   159  func connectPeers(full, light pairPeer, version int) (*peer, *peer, error) {
   160  	// Create a message pipe to communicate through
   161  	app, net := p2p.MsgPipe()
   162  
   163  	peerLight := full.PM.newPeer(version, NetworkId, p2p.NewPeer(light.Node.ID(), light.Name, nil), net)
   164  	peerFull := light.PM.newPeer(version, NetworkId, p2p.NewPeer(full.Node.ID(), full.Name, nil), app)
   165  
   166  	// Start the peerLight on a new thread
   167  	errc1 := make(chan error, 1)
   168  	errc2 := make(chan error, 1)
   169  	go func() {
   170  		select {
   171  		case light.PM.newPeerCh <- peerFull:
   172  			errc1 <- light.PM.handle(peerFull)
   173  		case <-light.PM.quitSync:
   174  			errc1 <- p2p.DiscQuitting
   175  		}
   176  	}()
   177  	go func() {
   178  		select {
   179  		case full.PM.newPeerCh <- peerLight:
   180  			errc2 <- full.PM.handle(peerLight)
   181  		case <-full.PM.quitSync:
   182  			errc2 <- p2p.DiscQuitting
   183  		}
   184  	}()
   185  
   186  	select {
   187  	case <-time.After(time.Millisecond * 100):
   188  	case err := <-errc1:
   189  		return nil, nil, fmt.Errorf("peerLight handshake error: %v", err)
   190  	case err := <-errc2:
   191  		return nil, nil, fmt.Errorf("peerFull handshake error: %v", err)
   192  	}
   193  
   194  	return peerFull, peerLight, nil
   195  }
   196  
   197  // newFullPeerPair creates node with full sync mode
   198  func newFullPeerPair(t *testing.T, index int, numberOfblocks int, chainGen func(int, *core.BlockGen)) pairPeer {
   199  	db := rawdb.NewMemoryDatabase()
   200  
   201  	pmFull := newTestProtocolManagerMust(t, false, numberOfblocks, chainGen, nil, nil, db, nil)
   202  
   203  	peerPairFull := pairPeer{
   204  		Name: "full node",
   205  		PM:   pmFull,
   206  	}
   207  	key, err := crypto.GenerateKey()
   208  	if err != nil {
   209  		t.Fatal("generate key err:", err)
   210  	}
   211  	peerPairFull.Key = key
   212  	peerPairFull.Node = enode.NewV4(&key.PublicKey, net.ParseIP("127.0.0.1"), 35000, 35000)
   213  	return peerPairFull
   214  }
   215  
   216  // newLightPeer creates node with light sync mode
   217  func newLightPeer(t *testing.T, ulcConfig *eth.ULCConfig) pairPeer {
   218  	peers := newPeerSet()
   219  	dist := newRequestDistributor(peers, make(chan struct{}), &mclock.System{})
   220  	rm := newRetrieveManager(peers, dist, nil)
   221  	ldb := rawdb.NewMemoryDatabase()
   222  
   223  	odr := NewLesOdr(ldb, light.DefaultClientIndexerConfig, rm)
   224  
   225  	pmLight := newTestProtocolManagerMust(t, true, 0, nil, odr, peers, ldb, ulcConfig)
   226  	peerPairLight := pairPeer{
   227  		Name: "ulc node",
   228  		PM:   pmLight,
   229  	}
   230  
   231  	key, err := crypto.GenerateKey()
   232  	if err != nil {
   233  		t.Fatal("generate key err:", err)
   234  	}
   235  	peerPairLight.Key = key
   236  	peerPairLight.Node = enode.NewV4(&key.PublicKey, net.IP{}, 35000, 35000)
   237  	return peerPairLight
   238  }