Return error if RPC returns empty header

- Enables graceful failure if RPC returns empty data with no error
This commit is contained in:
Rob Mulholand 2018-09-20 17:15:06 -05:00
parent 92525ca575
commit a0ba6ca6bd
3 changed files with 25 additions and 3 deletions

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
@ -19,6 +18,7 @@ type MockRpcClient struct {
passedContext context.Context passedContext context.Context
passedMethod string passedMethod string
passedResult interface{} passedResult interface{}
returnPOAHeader core.POAHeader
supportedModules map[string]string supportedModules map[string]string
} }
@ -45,8 +45,7 @@ func (client *MockRpcClient) CallContext(ctx context.Context, result interface{}
*p = types.Header{Number: big.NewInt(123)} *p = types.Header{Number: big.NewInt(123)}
} }
if p, ok := result.(*core.POAHeader); ok { if p, ok := result.(*core.POAHeader); ok {
n := hexutil.Big(*big.NewInt(123)) *p = client.returnPOAHeader
*p = core.POAHeader{Number: &n}
} }
if client.callContextErr != nil { if client.callContextErr != nil {
return client.callContextErr return client.callContextErr
@ -91,6 +90,10 @@ func (client *MockRpcClient) SetCallContextErr(err error) {
client.callContextErr = err client.callContextErr = err
} }
func (client *MockRpcClient) SetReturnPOAHeader(header core.POAHeader) {
client.returnPOAHeader = header
}
func (client *MockRpcClient) AssertCallContextCalledWith(ctx context.Context, result interface{}, method string) { func (client *MockRpcClient) AssertCallContextCalledWith(ctx context.Context, result interface{}, method string) {
Expect(client.passedContext).To(Equal(ctx)) Expect(client.passedContext).To(Equal(ctx))
Expect(client.passedResult).To(BeAssignableToTypeOf(result)) Expect(client.passedResult).To(BeAssignableToTypeOf(result))

View File

@ -9,10 +9,13 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/pkg/errors"
"github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/core"
vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common" vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
) )
var ErrEmptyHeader = errors.New("empty header returned over RPC")
type BlockChain struct { type BlockChain struct {
blockConverter vulcCommon.BlockConverter blockConverter vulcCommon.BlockConverter
ethClient core.EthClient ethClient core.EthClient
@ -62,6 +65,9 @@ func (blockChain *BlockChain) getPOAHeader(blockNumber int64) (header core.Heade
if err != nil { if err != nil {
return header, err return header, err
} }
if POAHeader.Number == nil {
return header, ErrEmptyHeader
}
return blockChain.headerConverter.Convert(&types.Header{ return blockChain.headerConverter.Convert(&types.Header{
ParentHash: POAHeader.ParentHash, ParentHash: POAHeader.ParentHash,
UncleHash: POAHeader.UncleHash, UncleHash: POAHeader.UncleHash,

View File

@ -10,6 +10,7 @@ import (
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/ethereum/go-ethereum/common/hexutil"
vulcCore "github.com/vulcanize/vulcanizedb/pkg/core" vulcCore "github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/fakes" "github.com/vulcanize/vulcanizedb/pkg/fakes"
"github.com/vulcanize/vulcanizedb/pkg/geth" "github.com/vulcanize/vulcanizedb/pkg/geth"
@ -75,6 +76,8 @@ var _ = Describe("Geth blockchain", func() {
Describe("POA/Kovan", func() { Describe("POA/Kovan", func() {
It("fetches header from rpcClient", func() { It("fetches header from rpcClient", func() {
node.NetworkID = vulcCore.KOVAN_NETWORK_ID node.NetworkID = vulcCore.KOVAN_NETWORK_ID
blockNumber := hexutil.Big(*big.NewInt(123))
mockRpcClient.SetReturnPOAHeader(vulcCore.POAHeader{Number: &blockNumber})
blockChain = geth.NewBlockChain(mockClient, mockRpcClient, node, cold_db.NewColdDbTransactionConverter()) blockChain = geth.NewBlockChain(mockClient, mockRpcClient, node, cold_db.NewColdDbTransactionConverter())
_, err := blockChain.GetHeaderByNumber(100) _, err := blockChain.GetHeaderByNumber(100)
@ -93,6 +96,16 @@ var _ = Describe("Geth blockchain", func() {
Expect(err).To(HaveOccurred()) Expect(err).To(HaveOccurred())
Expect(err).To(MatchError(fakes.FakeError)) Expect(err).To(MatchError(fakes.FakeError))
}) })
It("returns error if returned header is empty", func() {
node.NetworkID = vulcCore.KOVAN_NETWORK_ID
blockChain = geth.NewBlockChain(mockClient, mockRpcClient, node, cold_db.NewColdDbTransactionConverter())
_, err := blockChain.GetHeaderByNumber(100)
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError(geth.ErrEmptyHeader))
})
}) })
}) })