// Copyright 2017 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 . package core import ( "math/big" "reflect" "sync" "testing" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/istanbul" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "gopkg.in/karalabe/cookiejar.v2/collections/prque" ) func TestCheckRequestMsg(t *testing.T) { c := &core{ state: StateAcceptRequest, current: newRoundState(&istanbul.View{ Sequence: big.NewInt(1), Round: big.NewInt(0), }, newTestValidatorSet(4), common.Hash{}, nil, nil, nil), } // invalid request err := c.checkRequestMsg(nil) if err != errInvalidMessage { t.Errorf("error mismatch: have %v, want %v", err, errInvalidMessage) } r := &istanbul.Request{ Proposal: nil, } err = c.checkRequestMsg(r) if err != errInvalidMessage { t.Errorf("error mismatch: have %v, want %v", err, errInvalidMessage) } // old request r = &istanbul.Request{ Proposal: makeBlock(0), } err = c.checkRequestMsg(r) if err != errOldMessage { t.Errorf("error mismatch: have %v, want %v", err, errOldMessage) } // future request r = &istanbul.Request{ Proposal: makeBlock(2), } err = c.checkRequestMsg(r) if err != errFutureMessage { t.Errorf("error mismatch: have %v, want %v", err, errFutureMessage) } // current request r = &istanbul.Request{ Proposal: makeBlock(1), } err = c.checkRequestMsg(r) if err != nil { t.Errorf("error mismatch: have %v, want nil", err) } } func TestStoreRequestMsg(t *testing.T) { backend := &testSystemBackend{ events: new(event.TypeMux), } c := &core{ logger: log.New("backend", "test", "id", 0), backend: backend, state: StateAcceptRequest, current: newRoundState(&istanbul.View{ Sequence: big.NewInt(0), Round: big.NewInt(0), }, newTestValidatorSet(4), common.Hash{}, nil, nil, nil), pendingRequests: prque.New(), pendingRequestsMu: new(sync.Mutex), } requests := []istanbul.Request{ { Proposal: makeBlock(1), }, { Proposal: makeBlock(2), }, { Proposal: makeBlock(3), }, } c.storeRequestMsg(&requests[1]) c.storeRequestMsg(&requests[0]) c.storeRequestMsg(&requests[2]) if c.pendingRequests.Size() != len(requests) { t.Errorf("the size of pending requests mismatch: have %v, want %v", c.pendingRequests.Size(), len(requests)) } c.current.sequence = big.NewInt(3) c.subscribeEvents() defer c.unsubscribeEvents() c.processPendingRequests() const timeoutDura = 2 * time.Second timeout := time.NewTimer(timeoutDura) select { case ev := <-c.events.Chan(): e, ok := ev.Data.(istanbul.RequestEvent) if !ok { t.Errorf("unexpected event comes: %v", reflect.TypeOf(ev.Data)) } if e.Proposal.Number().Cmp(requests[2].Proposal.Number()) != 0 { t.Errorf("the number of proposal mismatch: have %v, want %v", e.Proposal.Number(), requests[2].Proposal.Number()) } case <-timeout.C: t.Error("unexpected timeout occurs") } }