2018-07-31 04:41:27 +00:00
|
|
|
package simulator
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2018-08-24 04:09:59 +00:00
|
|
|
"io/ioutil"
|
2018-07-31 04:41:27 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/ethereum/go-ethereum/event"
|
|
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/types"
|
2018-07-31 18:54:45 +00:00
|
|
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
2018-08-18 03:34:56 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared/database"
|
2018-07-31 04:41:27 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared/p2p"
|
|
|
|
"github.com/prysmaticlabs/prysm/shared/testutil"
|
2018-08-24 04:09:59 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
2018-07-31 04:41:27 +00:00
|
|
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
|
|
|
)
|
|
|
|
|
2018-08-24 04:09:59 +00:00
|
|
|
func init() {
|
|
|
|
logrus.SetLevel(logrus.DebugLevel)
|
|
|
|
logrus.SetOutput(ioutil.Discard)
|
|
|
|
}
|
|
|
|
|
2018-07-31 04:41:27 +00:00
|
|
|
type mockP2P struct{}
|
|
|
|
|
|
|
|
func (mp *mockP2P) Subscribe(msg interface{}, channel interface{}) event.Subscription {
|
|
|
|
return new(event.Feed).Subscribe(channel)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mp *mockP2P) Broadcast(msg interface{}) {}
|
|
|
|
|
|
|
|
func (mp *mockP2P) Send(msg interface{}, peer p2p.Peer) {}
|
|
|
|
|
|
|
|
type mockPOWChainService struct{}
|
|
|
|
|
|
|
|
func (mpow *mockPOWChainService) LatestBlockHash() common.Hash {
|
|
|
|
return common.BytesToHash([]byte{})
|
|
|
|
}
|
|
|
|
|
|
|
|
type mockChainService struct{}
|
|
|
|
|
|
|
|
func (mc *mockChainService) CurrentActiveState() *types.ActiveState {
|
2018-08-29 00:55:56 +00:00
|
|
|
return types.NewActiveState(&pb.ActiveState{}, make(map[*common.Hash]*types.VoteCache))
|
2018-07-31 04:41:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (mc *mockChainService) CurrentCrystallizedState() *types.CrystallizedState {
|
2018-08-05 23:23:31 +00:00
|
|
|
return types.NewCrystallizedState(&pb.CrystallizedState{})
|
2018-07-31 04:41:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestLifecycle(t *testing.T) {
|
|
|
|
hook := logTest.NewGlobal()
|
2018-08-18 03:34:56 +00:00
|
|
|
db := database.NewKVStore()
|
|
|
|
cfg := &Config{
|
|
|
|
Delay: time.Second,
|
|
|
|
BlockRequestBuf: 0,
|
|
|
|
P2P: &mockP2P{},
|
|
|
|
Web3Service: &mockPOWChainService{},
|
|
|
|
ChainService: &mockChainService{},
|
|
|
|
BeaconDB: db,
|
2018-08-20 15:50:11 +00:00
|
|
|
Validator: false,
|
2018-08-18 03:34:56 +00:00
|
|
|
}
|
|
|
|
sim := NewSimulator(context.Background(), cfg)
|
2018-07-31 04:41:27 +00:00
|
|
|
|
|
|
|
sim.Start()
|
|
|
|
testutil.AssertLogsContain(t, hook, "Starting service")
|
|
|
|
sim.Stop()
|
|
|
|
testutil.AssertLogsContain(t, hook, "Stopping service")
|
|
|
|
|
|
|
|
// The context should have been canceled.
|
|
|
|
if sim.ctx.Err() == nil {
|
|
|
|
t.Error("context was not canceled")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBroadcastBlockHash(t *testing.T) {
|
|
|
|
hook := logTest.NewGlobal()
|
2018-08-18 03:34:56 +00:00
|
|
|
db := database.NewKVStore()
|
|
|
|
cfg := &Config{
|
|
|
|
Delay: time.Second,
|
|
|
|
BlockRequestBuf: 0,
|
|
|
|
P2P: &mockP2P{},
|
|
|
|
Web3Service: &mockPOWChainService{},
|
|
|
|
ChainService: &mockChainService{},
|
|
|
|
BeaconDB: db,
|
2018-08-20 15:50:11 +00:00
|
|
|
Validator: false,
|
2018-08-18 03:34:56 +00:00
|
|
|
}
|
|
|
|
sim := NewSimulator(context.Background(), cfg)
|
2018-07-31 04:41:27 +00:00
|
|
|
|
|
|
|
delayChan := make(chan time.Time)
|
|
|
|
doneChan := make(chan struct{})
|
|
|
|
exitRoutine := make(chan bool)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
sim.run(delayChan, doneChan)
|
|
|
|
<-exitRoutine
|
|
|
|
}()
|
|
|
|
|
|
|
|
delayChan <- time.Time{}
|
|
|
|
doneChan <- struct{}{}
|
|
|
|
|
|
|
|
testutil.AssertLogsContain(t, hook, "Announcing block hash")
|
|
|
|
|
|
|
|
exitRoutine <- true
|
|
|
|
|
|
|
|
if len(sim.broadcastedBlockHashes) != 1 {
|
|
|
|
t.Error("Did not store the broadcasted block hash")
|
|
|
|
}
|
|
|
|
hook.Reset()
|
|
|
|
}
|
|
|
|
|
2018-08-05 23:23:31 +00:00
|
|
|
func TestBlockRequest(t *testing.T) {
|
2018-07-31 04:41:27 +00:00
|
|
|
hook := logTest.NewGlobal()
|
2018-08-18 03:34:56 +00:00
|
|
|
db := database.NewKVStore()
|
|
|
|
cfg := &Config{
|
|
|
|
Delay: time.Second,
|
|
|
|
BlockRequestBuf: 0,
|
|
|
|
P2P: &mockP2P{},
|
|
|
|
Web3Service: &mockPOWChainService{},
|
|
|
|
ChainService: &mockChainService{},
|
|
|
|
BeaconDB: db,
|
2018-08-20 15:50:11 +00:00
|
|
|
Validator: true,
|
2018-08-18 03:34:56 +00:00
|
|
|
}
|
|
|
|
sim := NewSimulator(context.Background(), cfg)
|
2018-07-31 04:41:27 +00:00
|
|
|
|
|
|
|
delayChan := make(chan time.Time)
|
|
|
|
doneChan := make(chan struct{})
|
|
|
|
exitRoutine := make(chan bool)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
sim.run(delayChan, doneChan)
|
|
|
|
<-exitRoutine
|
|
|
|
}()
|
|
|
|
|
2018-08-18 03:34:56 +00:00
|
|
|
block := types.NewBlock(&pb.BeaconBlock{ParentHash: make([]byte, 32)})
|
2018-07-31 04:41:27 +00:00
|
|
|
h, err := block.Hash()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
data := &pb.BeaconBlockRequest{
|
|
|
|
Hash: h[:],
|
|
|
|
}
|
|
|
|
|
|
|
|
msg := p2p.Message{
|
|
|
|
Peer: p2p.Peer{},
|
|
|
|
Data: data,
|
|
|
|
}
|
|
|
|
|
2018-08-18 03:34:56 +00:00
|
|
|
sim.broadcastedBlocks[h] = block
|
2018-07-31 04:41:27 +00:00
|
|
|
|
|
|
|
sim.blockRequestChan <- msg
|
|
|
|
doneChan <- struct{}{}
|
|
|
|
exitRoutine <- true
|
|
|
|
|
|
|
|
testutil.AssertLogsContain(t, hook, fmt.Sprintf("Responding to full block request for hash: 0x%x", h))
|
|
|
|
}
|
2018-08-01 15:24:55 +00:00
|
|
|
|
2018-08-18 03:34:56 +00:00
|
|
|
func TestLastSimulatedSession(t *testing.T) {
|
|
|
|
db := database.NewKVStore()
|
|
|
|
cfg := &Config{
|
|
|
|
Delay: time.Second,
|
|
|
|
BlockRequestBuf: 0,
|
|
|
|
P2P: &mockP2P{},
|
|
|
|
Web3Service: &mockPOWChainService{},
|
|
|
|
ChainService: &mockChainService{},
|
|
|
|
BeaconDB: db,
|
2018-08-20 15:50:11 +00:00
|
|
|
Validator: true,
|
2018-08-18 03:34:56 +00:00
|
|
|
}
|
|
|
|
sim := NewSimulator(context.Background(), cfg)
|
|
|
|
if err := db.Put([]byte("last-simulated-block"), []byte{}); err != nil {
|
|
|
|
t.Fatalf("Could not store last simulated block: %v", err)
|
|
|
|
}
|
|
|
|
if _, err := sim.lastSimulatedSessionBlock(); err != nil {
|
|
|
|
t.Errorf("could not fetch last simulated session block: %v", err)
|
|
|
|
}
|
|
|
|
}
|
2018-08-20 15:50:11 +00:00
|
|
|
|
|
|
|
func TestDefaultConfig(t *testing.T) {
|
|
|
|
if DefaultConfig().BlockRequestBuf != 100 {
|
|
|
|
t.Errorf("incorrect default config for block request buffer")
|
|
|
|
}
|
|
|
|
if DefaultConfig().Delay != time.Second*5 {
|
|
|
|
t.Errorf("incorrect default config for delay")
|
|
|
|
}
|
|
|
|
}
|