prysm-pulse/beacon-chain/powchain/block_reader_test.go
Nishant Das 8977e5088e Handle ETH1 Node Failure (#3914)
* refactor powchain config

* send mock eth1 votes when proposing blocks

* fix all tests

* lint

* fix all tests

* fix blockchain test

* Apply suggestions from code review

Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com>

* raul's review

* add warning
2019-11-02 14:56:03 -05:00

241 lines
6.2 KiB
Go

package powchain
import (
"bytes"
"context"
"math/big"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
dbutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
contracts "github.com/prysmaticlabs/prysm/contracts/deposit-contract"
)
var endpoint = "ws://127.0.0.1"
func setDefaultMocks(service *Service) *Service {
service.reader = &goodReader{}
service.blockFetcher = &goodFetcher{}
service.logger = &goodLogger{}
service.httpLogger = &goodLogger{}
return service
}
func TestLatestMainchainInfo_OK(t *testing.T) {
testAcc, err := contracts.Setup()
if err != nil {
t.Fatalf("Unable to set up simulated backend %v", err)
}
beaconDB := dbutil.SetupDB(t)
defer dbutil.TeardownDB(t, beaconDB)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
ETH1Endpoint: endpoint,
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
if err != nil {
t.Fatalf("unable to setup web3 ETH1.0 chain service: %v", err)
}
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
if err != nil {
t.Fatal(err)
}
testAcc.Backend.Commit()
exitRoutine := make(chan bool)
go func() {
web3Service.run(web3Service.ctx.Done())
<-exitRoutine
}()
header := &gethTypes.Header{
Number: big.NewInt(42),
Time: 308534400,
}
web3Service.headerChan <- header
web3Service.cancel()
exitRoutine <- true
if web3Service.blockHeight.Cmp(header.Number) != 0 {
t.Errorf("block number not set, expected %v, got %v", header.Number, web3Service.blockHeight)
}
if web3Service.blockHash.Hex() != header.Hash().Hex() {
t.Errorf("block hash not set, expected %v, got %v", header.Hash().Hex(), web3Service.blockHash.Hex())
}
if web3Service.blockTime != time.Unix(int64(header.Time), 0) {
t.Errorf("block time not set, expected %v, got %v", time.Unix(int64(header.Time), 0), web3Service.blockTime)
}
blockInfoExistsInCache, info, err := web3Service.blockCache.BlockInfoByHash(web3Service.blockHash)
if err != nil {
t.Fatal(err)
}
if !blockInfoExistsInCache {
t.Error("Expected block info to exist in cache")
}
if info.Hash != web3Service.blockHash {
t.Errorf(
"Expected block info hash to be %v, got %v",
web3Service.blockHash,
info.Hash,
)
}
}
func TestBlockHashByHeight_ReturnsHash(t *testing.T) {
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
ETH1Endpoint: endpoint,
})
if err != nil {
t.Fatalf("unable to setup web3 ETH1.0 chain service: %v", err)
}
web3Service = setDefaultMocks(web3Service)
ctx := context.Background()
block := gethTypes.NewBlock(
&gethTypes.Header{
Number: big.NewInt(15),
Time: 150,
},
[]*gethTypes.Transaction{},
[]*gethTypes.Header{},
[]*gethTypes.Receipt{},
)
wanted := block.Hash()
hash, err := web3Service.BlockHashByHeight(ctx, big.NewInt(0))
if err != nil {
t.Fatalf("Could not get block hash with given height %v", err)
}
if !bytes.Equal(hash.Bytes(), wanted.Bytes()) {
t.Fatalf("Block hash did not equal expected hash, expected: %v, got: %v", wanted, hash)
}
exists, _, err := web3Service.blockCache.BlockInfoByHash(wanted)
if err != nil {
t.Fatal(err)
}
if !exists {
t.Error("Expected block info to be cached")
}
}
func TestBlockExists_ValidHash(t *testing.T) {
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
ETH1Endpoint: endpoint,
})
if err != nil {
t.Fatalf("unable to setup web3 ETH1.0 chain service: %v", err)
}
web3Service = setDefaultMocks(web3Service)
block := gethTypes.NewBlock(
&gethTypes.Header{
Number: big.NewInt(0),
},
[]*gethTypes.Transaction{},
[]*gethTypes.Header{},
[]*gethTypes.Receipt{},
)
exists, height, err := web3Service.BlockExists(context.Background(), block.Hash())
if err != nil {
t.Fatalf("Could not get block hash with given height %v", err)
}
if !exists {
t.Fatal("Expected BlockExists to return true.")
}
if height.Cmp(block.Number()) != 0 {
t.Fatalf("Block height did not equal expected height, expected: %v, got: %v", big.NewInt(42), height)
}
exists, _, err = web3Service.blockCache.BlockInfoByHeight(height)
if err != nil {
t.Fatal(err)
}
if !exists {
t.Error("Expected block to be cached")
}
}
func TestBlockExists_InvalidHash(t *testing.T) {
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
ETH1Endpoint: endpoint,
})
if err != nil {
t.Fatalf("unable to setup web3 ETH1.0 chain service: %v", err)
}
web3Service = setDefaultMocks(web3Service)
_, _, err = web3Service.BlockExists(context.Background(), common.BytesToHash([]byte{0}))
if err == nil {
t.Fatal("Expected BlockExists to error with invalid hash")
}
}
func TestBlockExists_UsesCachedBlockInfo(t *testing.T) {
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
ETH1Endpoint: endpoint,
})
if err != nil {
t.Fatalf("unable to setup web3 ETH1.0 chain service: %v", err)
}
// nil blockFetcher would panic if cached value not used
web3Service.blockFetcher = nil
block := gethTypes.NewBlock(
&gethTypes.Header{
Number: big.NewInt(0),
},
[]*gethTypes.Transaction{},
[]*gethTypes.Header{},
[]*gethTypes.Receipt{},
)
if err := web3Service.blockCache.AddBlock(block); err != nil {
t.Fatal(err)
}
exists, height, err := web3Service.BlockExists(context.Background(), block.Hash())
if err != nil {
t.Fatalf("Could not get block hash with given height %v", err)
}
if !exists {
t.Fatal("Expected BlockExists to return true.")
}
if height.Cmp(block.Number()) != 0 {
t.Fatalf("Block height did not equal expected height, expected: %v, got: %v", big.NewInt(42), height)
}
}
func TestBlockNumberByTimestamp(t *testing.T) {
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
ETH1Endpoint: endpoint,
})
if err != nil {
t.Fatal(err)
}
web3Service = setDefaultMocks(web3Service)
web3Service.client = nil
ctx := context.Background()
bn, err := web3Service.BlockNumberByTimestamp(ctx, 150000 /* time */)
if err != nil {
t.Fatal(err)
}
if bn.Cmp(big.NewInt(0)) == 0 {
t.Error("Returned a block with zero number, expected to be non zero")
}
}