Get head block number

- Allows us to refuse to sync past current head
- Creates the opportunity to add a flag for syncing all blocks
This commit is contained in:
Rob Mulholand 2018-05-03 16:58:45 -05:00
parent 5f6bf32ec1
commit 5a5e08bd13
7 changed files with 129 additions and 43 deletions

View File

@ -49,10 +49,6 @@ func init() {
}
func coldImport() {
if endingBlockNumber < startingBlockNumber {
log.Fatal("Ending block number must be greater than starting block number for cold import.")
}
// init eth db
ethDBConfig := ethereum.CreateDatabaseConfig(ethereum.Level, levelDbPath)
ethDB, err := ethereum.CreateDatabase(ethDBConfig)
@ -60,6 +56,14 @@ func coldImport() {
log.Fatal("Error connecting to ethereum db: ", err)
}
if endingBlockNumber < startingBlockNumber {
log.Fatal("Ending block number must be greater than starting block number for cold import.")
}
mostRecentBlockNumberInDb := ethDB.GetHeadBlockNumber()
if endingBlockNumber > mostRecentBlockNumberInDb {
log.Fatal("Ending block number is greater than most recent block in db: ", mostRecentBlockNumberInDb)
}
// init pg db
genesisBlockHash := common.BytesToHash(ethDB.GetBlockHash(0)).String()
coldNode := core.Node{

View File

@ -13,6 +13,7 @@ type Database interface {
GetBlock(hash []byte, blockNumber int64) *types.Block
GetBlockHash(blockNumber int64) []byte
GetBlockReceipts(blockHash []byte, blockNumber int64) types.Receipts
GetHeadBlockNumber() int64
}
func CreateDatabase(config DatabaseConfig) (Database, error) {

View File

@ -32,3 +32,9 @@ func (l LevelDatabase) GetBlockReceipts(blockHash []byte, blockNumber int64) typ
h := common.BytesToHash(blockHash)
return l.reader.GetBlockReceipts(h, n)
}
func (l LevelDatabase) GetHeadBlockNumber() int64 {
h := l.reader.GetHeadBlockHash()
n := l.reader.GetBlockNumber(h)
return int64(n)
}

View File

@ -8,26 +8,36 @@ import (
type Reader interface {
GetBlock(hash common.Hash, number uint64) *types.Block
GetBlockNumber(hash common.Hash) uint64
GetBlockReceipts(hash common.Hash, number uint64) types.Receipts
GetCanonicalHash(number uint64) common.Hash
GetHeadBlockHash() common.Hash
}
type LevelDatabaseReader struct {
core.DatabaseReader
reader core.DatabaseReader
}
func NewLevelDatabaseReader(reader core.DatabaseReader) *LevelDatabaseReader {
return &LevelDatabaseReader{DatabaseReader: reader}
return &LevelDatabaseReader{reader: reader}
}
func (ldbr *LevelDatabaseReader) GetBlock(hash common.Hash, number uint64) *types.Block {
return core.GetBlock(ldbr.DatabaseReader, hash, number)
return core.GetBlock(ldbr.reader, hash, number)
}
func (ldbr *LevelDatabaseReader) GetBlockNumber(hash common.Hash) uint64 {
return core.GetBlockNumber(ldbr.reader, hash)
}
func (ldbr *LevelDatabaseReader) GetBlockReceipts(hash common.Hash, number uint64) types.Receipts {
return core.GetBlockReceipts(ldbr.DatabaseReader, hash, number)
return core.GetBlockReceipts(ldbr.reader, hash, number)
}
func (ldbr *LevelDatabaseReader) GetCanonicalHash(number uint64) common.Hash {
return core.GetCanonicalHash(ldbr.DatabaseReader, number)
return core.GetCanonicalHash(ldbr.reader, number)
}
func (ldbr *LevelDatabaseReader) GetHeadBlockHash() common.Hash {
return core.GetHeadBlockHash(ldbr.reader)
}

View File

@ -3,24 +3,12 @@ package level_test
import (
"github.com/ethereum/go-ethereum/common"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/datastore/ethereum/level"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
)
var _ = Describe("Level database", func() {
Describe("Getting a block hash", func() {
It("converts block number to uint64 to fetch hash from reader", func() {
mockReader := fakes.NewMockLevelDatabaseReader()
ldb := level.NewLevelDatabase(mockReader)
blockNumber := int64(12345)
ldb.GetBlockHash(blockNumber)
expectedBlockNumber := uint64(blockNumber)
mockReader.AssertGetCanonicalHashCalledWith(expectedBlockNumber)
})
})
Describe("Getting a block", func() {
It("converts block number to uint64 and hash to common.Hash to fetch block from reader", func() {
mockReader := fakes.NewMockLevelDatabaseReader()
@ -36,6 +24,19 @@ var _ = Describe("Level database", func() {
})
})
Describe("Getting a block hash", func() {
It("converts block number to uint64 to fetch hash from reader", func() {
mockReader := fakes.NewMockLevelDatabaseReader()
ldb := level.NewLevelDatabase(mockReader)
blockNumber := int64(12345)
ldb.GetBlockHash(blockNumber)
expectedBlockNumber := uint64(blockNumber)
mockReader.AssertGetCanonicalHashCalledWith(expectedBlockNumber)
})
})
Describe("Getting a block's receipts", func() {
It("converts block number to uint64 and hash to common.Hash to fetch receipts from reader", func() {
mockReader := fakes.NewMockLevelDatabaseReader()
@ -50,4 +51,21 @@ var _ = Describe("Level database", func() {
mockReader.AssertGetBlockReceiptsCalledWith(expectedBlockHash, expectedBlockNumber)
})
})
Describe("Getting the latest block number", func() {
It("invokes the database reader to get the latest block number by hash and converts result to int64", func() {
mockReader := fakes.NewMockLevelDatabaseReader()
fakeHash := common.BytesToHash([]byte{1, 2, 3, 4, 5})
mockReader.SetHeadBlockHashReturnHash(fakeHash)
fakeBlockNumber := uint64(123456789)
mockReader.SetReturnBlockNumber(fakeBlockNumber)
ldb := level.NewLevelDatabase(mockReader)
result := ldb.GetHeadBlockNumber()
mockReader.AssertGetHeadBlockHashCalled()
mockReader.AssertGetBlockNumberCalledWith(fakeHash)
Expect(result).To(Equal(int64(fakeBlockNumber)))
})
})
})

View File

@ -18,6 +18,8 @@ type MockEthereumDatabase struct {
getBlockReceiptsPassedHash []byte
getBlockReceiptsPassedNumber int64
getBlockReceiptsReturnReceipts types.Receipts
getHeadBlockNumberCalled bool
getHeadBlockNumberReturnVal int64
}
func NewMockEthereumDatabase() *MockEthereumDatabase {
@ -33,6 +35,8 @@ func NewMockEthereumDatabase() *MockEthereumDatabase {
getBlockReceiptsPassedHash: nil,
getBlockReceiptsPassedNumber: 0,
getBlockReceiptsReturnReceipts: nil,
getHeadBlockNumberCalled: false,
getHeadBlockNumberReturnVal: 0,
}
}
@ -68,6 +72,11 @@ func (med *MockEthereumDatabase) GetBlockReceipts(blockHash []byte, blockNumber
return med.getBlockReceiptsReturnReceipts
}
func (med *MockEthereumDatabase) GetHeadBlockNumber() int64 {
med.getHeadBlockNumberCalled = true
return med.getHeadBlockNumberReturnVal
}
func (med *MockEthereumDatabase) AssertGetBlockCalledWith(hash []byte, blockNumber int64) {
Expect(med.getBlockCalled).To(BeTrue())
Expect(med.getBlockPassedHash).To(Equal(hash))

View File

@ -8,32 +8,42 @@ import (
type MockLevelDatabaseReader struct {
getBlockCalled bool
getBlockReceiptsCalled bool
getCanonicalHashCalled bool
passedHash common.Hash
getCanonicalHashPassedNumber uint64
getBlockNumberCalled bool
getBlockNumberPassedHash common.Hash
getBlockPassedHash common.Hash
getBlockPassedNumber uint64
getBlockReceiptsCalled bool
getBlockReceiptsPassedHash common.Hash
getBlockReceiptsPassedNumber uint64
getCanonicalHashCalled bool
getCanonicalHashPassedNumber uint64
getCanonicalHashReturnHash common.Hash
getHeadBlockHashCalled bool
getHeadBlockHashReturnHash common.Hash
passedHash common.Hash
returnBlock *types.Block
returnHash common.Hash
returnBlockNumber uint64
returnReceipts types.Receipts
}
func NewMockLevelDatabaseReader() *MockLevelDatabaseReader {
return &MockLevelDatabaseReader{
getBlockCalled: false,
getBlockReceiptsCalled: false,
getCanonicalHashCalled: false,
passedHash: common.Hash{},
getCanonicalHashPassedNumber: 0,
getBlockNumberCalled: false,
getBlockNumberPassedHash: common.Hash{},
getBlockPassedHash: common.Hash{},
getBlockPassedNumber: 0,
getBlockReceiptsCalled: false,
getBlockReceiptsPassedHash: common.Hash{},
getBlockReceiptsPassedNumber: 0,
getCanonicalHashCalled: false,
getCanonicalHashPassedNumber: 0,
getCanonicalHashReturnHash: common.Hash{},
getHeadBlockHashCalled: false,
getHeadBlockHashReturnHash: common.Hash{},
passedHash: common.Hash{},
returnBlock: nil,
returnHash: common.Hash{},
returnBlockNumber: 0,
returnReceipts: nil,
}
}
@ -42,20 +52,22 @@ func (mldr *MockLevelDatabaseReader) SetReturnBlock(block *types.Block) {
mldr.returnBlock = block
}
func (mldr *MockLevelDatabaseReader) SetReturnHash(hash common.Hash) {
mldr.returnHash = hash
func (mldr *MockLevelDatabaseReader) SetReturnBlockNumber(n uint64) {
mldr.returnBlockNumber = n
}
func (mldr *MockLevelDatabaseReader) SetGetCanonicalHashReturnHash(hash common.Hash) {
mldr.getCanonicalHashReturnHash = hash
}
func (mldr *MockLevelDatabaseReader) SetHeadBlockHashReturnHash(hash common.Hash) {
mldr.getHeadBlockHashReturnHash = hash
}
func (mldr *MockLevelDatabaseReader) SetReturnReceipts(receipts types.Receipts) {
mldr.returnReceipts = receipts
}
func (mldr *MockLevelDatabaseReader) GetCanonicalHash(number uint64) common.Hash {
mldr.getCanonicalHashCalled = true
mldr.getCanonicalHashPassedNumber = number
return mldr.returnHash
}
func (mldr *MockLevelDatabaseReader) GetBlock(hash common.Hash, number uint64) *types.Block {
mldr.getBlockCalled = true
mldr.getBlockPassedHash = hash
@ -70,9 +82,21 @@ func (mldr *MockLevelDatabaseReader) GetBlockReceipts(hash common.Hash, number u
return mldr.returnReceipts
}
func (mldr *MockLevelDatabaseReader) AssertGetCanonicalHashCalledWith(number uint64) {
Expect(mldr.getCanonicalHashCalled).To(BeTrue())
Expect(mldr.getCanonicalHashPassedNumber).To(Equal(number))
func (mldr *MockLevelDatabaseReader) GetBlockNumber(hash common.Hash) uint64 {
mldr.getBlockNumberCalled = true
mldr.getBlockNumberPassedHash = hash
return mldr.returnBlockNumber
}
func (mldr *MockLevelDatabaseReader) GetCanonicalHash(number uint64) common.Hash {
mldr.getCanonicalHashCalled = true
mldr.getCanonicalHashPassedNumber = number
return mldr.getCanonicalHashReturnHash
}
func (mldr *MockLevelDatabaseReader) GetHeadBlockHash() common.Hash {
mldr.getHeadBlockHashCalled = true
return mldr.getHeadBlockHashReturnHash
}
func (mldr *MockLevelDatabaseReader) AssertGetBlockCalledWith(hash common.Hash, number uint64) {
@ -81,8 +105,22 @@ func (mldr *MockLevelDatabaseReader) AssertGetBlockCalledWith(hash common.Hash,
Expect(mldr.getBlockPassedNumber).To(Equal(number))
}
func (mldr *MockLevelDatabaseReader) AssertGetBlockNumberCalledWith(hash common.Hash) {
Expect(mldr.getBlockNumberCalled).To(BeTrue())
Expect(mldr.getBlockNumberPassedHash).To(Equal(hash))
}
func (mldr *MockLevelDatabaseReader) AssertGetBlockReceiptsCalledWith(hash common.Hash, number uint64) {
Expect(mldr.getBlockReceiptsCalled).To(BeTrue())
Expect(mldr.getBlockReceiptsPassedHash).To(Equal(hash))
Expect(mldr.getBlockReceiptsPassedNumber).To(Equal(number))
}
func (mldr *MockLevelDatabaseReader) AssertGetCanonicalHashCalledWith(number uint64) {
Expect(mldr.getCanonicalHashCalled).To(BeTrue())
Expect(mldr.getCanonicalHashPassedNumber).To(Equal(number))
}
func (mldr *MockLevelDatabaseReader) AssertGetHeadBlockHashCalled() {
Expect(mldr.getHeadBlockHashCalled).To(BeTrue())
}