github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/consensus/istanbul/core/request_test.go (about)

     1  // Copyright 2017 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  import (
    20  	"math/big"
    21  	"reflect"
    22  	"sync"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/ethereum/go-ethereum/common/prque"
    27  	"github.com/ethereum/go-ethereum/consensus/istanbul"
    28  	"github.com/ethereum/go-ethereum/event"
    29  	"github.com/ethereum/go-ethereum/log"
    30  )
    31  
    32  func TestCheckRequestMsg(t *testing.T) {
    33  	valSet := newTestValidatorSet(4)
    34  	c := &core{
    35  		current: newRoundState(&istanbul.View{
    36  			Sequence: big.NewInt(1),
    37  			Round:    big.NewInt(0),
    38  		}, valSet, valSet.GetByIndex(0)),
    39  	}
    40  
    41  	// invalid request
    42  	err := c.checkRequestMsg(nil)
    43  	if err != errInvalidMessage {
    44  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidMessage)
    45  	}
    46  	r := &istanbul.Request{
    47  		Proposal: nil,
    48  	}
    49  	err = c.checkRequestMsg(r)
    50  	if err != errInvalidMessage {
    51  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidMessage)
    52  	}
    53  
    54  	// old request
    55  	r = &istanbul.Request{
    56  		Proposal: makeBlock(0),
    57  	}
    58  	err = c.checkRequestMsg(r)
    59  	if err != errOldMessage {
    60  		t.Errorf("error mismatch: have %v, want %v", err, errOldMessage)
    61  	}
    62  
    63  	// future request
    64  	r = &istanbul.Request{
    65  		Proposal: makeBlock(2),
    66  	}
    67  	err = c.checkRequestMsg(r)
    68  	if err != errFutureMessage {
    69  		t.Errorf("error mismatch: have %v, want %v", err, errFutureMessage)
    70  	}
    71  
    72  	// current request
    73  	r = &istanbul.Request{
    74  		Proposal: makeBlock(1),
    75  	}
    76  	err = c.checkRequestMsg(r)
    77  	if err != nil {
    78  		t.Errorf("error mismatch: have %v, want nil", err)
    79  	}
    80  }
    81  
    82  func TestStoreRequestMsg(t *testing.T) {
    83  	backend := &testSystemBackend{
    84  		events: new(event.TypeMux),
    85  	}
    86  	valSet := newTestValidatorSet(4)
    87  	c := &core{
    88  		logger:  log.New("backend", "test", "id", 0),
    89  		backend: backend,
    90  		current: newRoundState(&istanbul.View{
    91  			Sequence: big.NewInt(0),
    92  			Round:    big.NewInt(0),
    93  		}, valSet, valSet.GetByIndex(0)),
    94  		pendingRequests:   prque.New(nil),
    95  		pendingRequestsMu: new(sync.Mutex),
    96  	}
    97  	requests := []istanbul.Request{
    98  		{
    99  			Proposal: makeBlock(1),
   100  		},
   101  		{
   102  			Proposal: makeBlock(2),
   103  		},
   104  		{
   105  			Proposal: makeBlock(3),
   106  		},
   107  	}
   108  
   109  	c.storeRequestMsg(&requests[1])
   110  	c.storeRequestMsg(&requests[0])
   111  	c.storeRequestMsg(&requests[2])
   112  	if c.pendingRequests.Size() != len(requests) {
   113  		t.Errorf("the size of pending requests mismatch: have %v, want %v", c.pendingRequests.Size(), len(requests))
   114  	}
   115  
   116  	c.current.(*roundStateImpl).sequence = big.NewInt(3)
   117  
   118  	c.subscribeEvents()
   119  	defer c.unsubscribeEvents()
   120  
   121  	c.processPendingRequests()
   122  
   123  	const timeoutDura = 2 * time.Second
   124  	timeout := time.NewTimer(timeoutDura)
   125  	select {
   126  	case ev := <-c.events.Chan():
   127  		e, ok := ev.Data.(istanbul.RequestEvent)
   128  		if !ok {
   129  			t.Errorf("unexpected event comes: %v", reflect.TypeOf(ev.Data))
   130  		}
   131  		if e.Proposal.Number().Cmp(requests[2].Proposal.Number()) != 0 {
   132  			t.Errorf("the number of proposal mismatch: have %v, want %v", e.Proposal.Number(), requests[2].Proposal.Number())
   133  		}
   134  	case <-timeout.C:
   135  		t.Error("unexpected timeout occurs")
   136  	}
   137  }