diff --git a/environments/local.toml.example b/environments/local.toml.example index ffe4c461..0d75c769 100644 --- a/environments/local.toml.example +++ b/environments/local.toml.example @@ -14,5 +14,5 @@ mcd_flop = "0x6191C9b0086c2eBF92300cC507009b53996FbFFa" pep = "0xB1997239Cfc3d15578A3a09730f7f84A90BB4975" pip = "0x9FfFE440258B79c5d6604001674A4722FfC0f7Bc" pit = "0xe7cf3198787c9a4daac73371a38f29aaeeced87e" -rep = "0xf88bbdc1e2718f8857f30a180076ec38d53cf296" +rep = "0xf88bBDc1E2718F8857F30A180076ec38d53cf296" vat = "0xcd726790550afcd77e9a7a47e86a3f9010af126b" \ No newline at end of file diff --git a/environments/public.toml.example b/environments/public.toml.example index 0423e990..ad6af0ee 100644 --- a/environments/public.toml.example +++ b/environments/public.toml.example @@ -15,5 +15,5 @@ mcd_flop = "0x6191C9b0086c2eBF92300cC507009b53996FbFFa" pep = "0xB1997239Cfc3d15578A3a09730f7f84A90BB4975" pip = "0x9FfFE440258B79c5d6604001674A4722FfC0f7Bc" pit = "0xe7cf3198787c9a4daac73371a38f29aaeeced87e" -rep = "0xf88bbdc1e2718f8857f30a180076ec38d53cf296" +rep = "0xf88bBDc1E2718F8857F30A180076ec38d53cf296" vat = "0xcd726790550afcd77e9a7a47e86a3f9010af126b" \ No newline at end of file diff --git a/pkg/transformers/integration_tests/price_feeds.go b/pkg/transformers/integration_tests/price_feeds.go index 25877a43..3178058e 100644 --- a/pkg/transformers/integration_tests/price_feeds.go +++ b/pkg/transformers/integration_tests/price_feeds.go @@ -20,7 +20,9 @@ import ( "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" + "github.com/vulcanize/vulcanizedb/pkg/transformers/factories" "github.com/vulcanize/vulcanizedb/pkg/transformers/price_feeds" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared" "github.com/vulcanize/vulcanizedb/test_config" ) @@ -43,13 +45,18 @@ var _ = Describe("Price feeds transformer", func() { blockNumber := int64(8763054) err := persistHeader(db, blockNumber) Expect(err).NotTo(HaveOccurred()) - config := price_feeds.IPriceFeedConfig{ - ContractAddresses: []string{"0x9FfFE440258B79c5d6604001674A4722FfC0f7Bc"}, - StartingBlockNumber: blockNumber, - EndingBlockNumber: blockNumber, + config := price_feeds.PriceFeedConfig + config.ContractAddresses = []string{shared.PipContractAddress} + config.StartingBlockNumber = blockNumber + config.EndingBlockNumber = blockNumber + + transformerInitializer := factories.Transformer{ + Config: config, + Converter: &price_feeds.PriceFeedConverter{}, + Repository: &price_feeds.PriceFeedRepository{}, + Fetcher: &shared.Fetcher{}, } - transformerInitializer := price_feeds.PriceFeedTransformerInitializer{Config: config} - transformer := transformerInitializer.NewPriceFeedTransformer(db, blockChain) + transformer := transformerInitializer.NewTransformer(db, blockChain) err = transformer.Execute() @@ -65,13 +72,18 @@ var _ = Describe("Price feeds transformer", func() { blockNumber := int64(8763059) err := persistHeader(db, blockNumber) Expect(err).NotTo(HaveOccurred()) - config := price_feeds.IPriceFeedConfig{ - ContractAddresses: []string{"0xB1997239Cfc3d15578A3a09730f7f84A90BB4975"}, - StartingBlockNumber: blockNumber, - EndingBlockNumber: blockNumber, + config := price_feeds.PriceFeedConfig + config.ContractAddresses = []string{shared.PepContractAddress} + config.StartingBlockNumber = blockNumber + config.EndingBlockNumber = blockNumber + + transformerInitializer := factories.Transformer{ + Config: config, + Converter: &price_feeds.PriceFeedConverter{}, + Repository: &price_feeds.PriceFeedRepository{}, + Fetcher: &shared.Fetcher{}, } - transformerInitializer := price_feeds.PriceFeedTransformerInitializer{Config: config} - transformer := transformerInitializer.NewPriceFeedTransformer(db, blockChain) + transformer := transformerInitializer.NewTransformer(db, blockChain) err = transformer.Execute() @@ -87,13 +99,18 @@ var _ = Describe("Price feeds transformer", func() { blockNumber := int64(8763062) err := persistHeader(db, blockNumber) Expect(err).NotTo(HaveOccurred()) - config := price_feeds.IPriceFeedConfig{ - ContractAddresses: []string{"0xf88bBDc1E2718F8857F30A180076ec38d53cf296"}, - StartingBlockNumber: blockNumber, - EndingBlockNumber: blockNumber, + config := price_feeds.PriceFeedConfig + config.ContractAddresses = []string{shared.RepContractAddress} + config.StartingBlockNumber = blockNumber + config.EndingBlockNumber = blockNumber + + transformerInitializer := factories.Transformer{ + Config: config, + Converter: &price_feeds.PriceFeedConverter{}, + Repository: &price_feeds.PriceFeedRepository{}, + Fetcher: &shared.Fetcher{}, } - transformerInitializer := price_feeds.PriceFeedTransformerInitializer{Config: config} - transformer := transformerInitializer.NewPriceFeedTransformer(db, blockChain) + transformer := transformerInitializer.NewTransformer(db, blockChain) err = transformer.Execute() diff --git a/pkg/transformers/price_feeds/config.go b/pkg/transformers/price_feeds/config.go index 844a2431..5ca114d4 100644 --- a/pkg/transformers/price_feeds/config.go +++ b/pkg/transformers/price_feeds/config.go @@ -16,20 +16,15 @@ package price_feeds import "github.com/vulcanize/vulcanizedb/pkg/transformers/shared" -var () - -type IPriceFeedConfig struct { - ContractAddresses []string - StartingBlockNumber int64 - EndingBlockNumber int64 -} - -var PriceFeedConfig = IPriceFeedConfig{ +var PriceFeedConfig = shared.SingleTransformerConfig{ + TransformerName: shared.PriceFeedLabel, ContractAddresses: []string{ shared.PepContractAddress, shared.PipContractAddress, shared.RepContractAddress, }, + ContractAbi: shared.MedianizerABI, + Topic: shared.LogValueSignature, StartingBlockNumber: 0, EndingBlockNumber: 10000000, } diff --git a/pkg/transformers/price_feeds/converter.go b/pkg/transformers/price_feeds/converter.go index 7a966883..373d8eca 100644 --- a/pkg/transformers/price_feeds/converter.go +++ b/pkg/transformers/price_feeds/converter.go @@ -20,14 +20,11 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) -type Converter interface { - ToModels(logs []types.Log, headerID int64) ([]PriceFeedModel, error) -} - type PriceFeedConverter struct{} -func (converter PriceFeedConverter) ToModels(logs []types.Log, headerID int64) (results []PriceFeedModel, err error) { - for _, log := range logs { +func (converter PriceFeedConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) { + var results []interface{} + for _, log := range ethLogs { raw, err := json.Marshal(log) if err != nil { return nil, err @@ -42,5 +39,5 @@ func (converter PriceFeedConverter) ToModels(logs []types.Log, headerID int64) ( } results = append(results, model) } - return results, err + return results, nil } diff --git a/pkg/transformers/price_feeds/converter_test.go b/pkg/transformers/price_feeds/converter_test.go index e16142c3..c9a0df77 100644 --- a/pkg/transformers/price_feeds/converter_test.go +++ b/pkg/transformers/price_feeds/converter_test.go @@ -26,9 +26,8 @@ import ( var _ = Describe("Price feed Converter", func() { It("converts a log to a price feed model", func() { converter := price_feeds.PriceFeedConverter{} - headerID := int64(123) - models, err := converter.ToModels([]types.Log{test_data.EthPriceFeedLog}, headerID) + models, err := converter.ToModels([]types.Log{test_data.EthPriceFeedLog}) Expect(err).NotTo(HaveOccurred()) Expect(len(models)).To(Equal(1)) diff --git a/pkg/transformers/price_feeds/fetcher.go b/pkg/transformers/price_feeds/fetcher.go deleted file mode 100644 index 480710d2..00000000 --- a/pkg/transformers/price_feeds/fetcher.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright © 2018 Vulcanize -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package price_feeds - -import ( - "math/big" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/vulcanize/vulcanizedb/pkg/core" - "github.com/vulcanize/vulcanizedb/pkg/transformers/shared" -) - -type IPriceFeedFetcher interface { - FetchLogValues(blockNumber int64) ([]types.Log, error) -} - -type PriceFeedFetcher struct { - blockChain core.BlockChain - contractAddresses []string -} - -func NewPriceFeedFetcher(blockChain core.BlockChain, contractAddresses []string) PriceFeedFetcher { - return PriceFeedFetcher{ - blockChain: blockChain, - contractAddresses: contractAddresses, - } -} - -func (fetcher PriceFeedFetcher) FetchLogValues(blockNumber int64) ([]types.Log, error) { - var addresses []common.Address - for _, addr := range fetcher.contractAddresses { - addresses = append(addresses, common.HexToAddress(addr)) - } - n := big.NewInt(blockNumber) - query := ethereum.FilterQuery{ - FromBlock: n, - ToBlock: n, - Addresses: addresses, - Topics: [][]common.Hash{{common.HexToHash(shared.LogValueSignature)}}, - } - return fetcher.blockChain.GetEthLogsWithCustomQuery(query) -} diff --git a/pkg/transformers/price_feeds/fetcher_test.go b/pkg/transformers/price_feeds/fetcher_test.go deleted file mode 100644 index e6bb942a..00000000 --- a/pkg/transformers/price_feeds/fetcher_test.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright © 2018 Vulcanize -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package price_feeds_test - -import ( - "math/big" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "github.com/vulcanize/vulcanizedb/pkg/fakes" - "github.com/vulcanize/vulcanizedb/pkg/transformers/price_feeds" - "github.com/vulcanize/vulcanizedb/pkg/transformers/shared" -) - -var _ = Describe("Price fetcher", func() { - It("gets log value events from price feed medianizers", func() { - mockBlockChain := fakes.NewMockBlockChain() - mockBlockChain.SetGetEthLogsWithCustomQueryReturnLogs([]types.Log{{}}) - contractAddresses := []string{"pep-contract-address", "pip-contract-address", "rep-contract-address"} - fetcher := price_feeds.NewPriceFeedFetcher(mockBlockChain, contractAddresses) - blockNumber := int64(100) - - _, err := fetcher.FetchLogValues(blockNumber) - - Expect(err).NotTo(HaveOccurred()) - var expectedAddresses []common.Address - for _, address := range contractAddresses { - expectedAddresses = append(expectedAddresses, common.HexToAddress(address)) - } - expectedQuery := ethereum.FilterQuery{ - FromBlock: big.NewInt(blockNumber), - ToBlock: big.NewInt(blockNumber), - Addresses: expectedAddresses, - Topics: [][]common.Hash{{common.HexToHash(shared.LogValueSignature)}}, - } - mockBlockChain.AssertGetEthLogsWithCustomQueryCalledWith(expectedQuery) - }) - - It("returns error if getting logs fails", func() { - mockBlockChain := fakes.NewMockBlockChain() - mockBlockChain.SetGetEthLogsWithCustomQueryErr(fakes.FakeError) - fetcher := price_feeds.NewPriceFeedFetcher(mockBlockChain, []string{"contract-address"}) - - _, err := fetcher.FetchLogValues(100) - - Expect(err).To(HaveOccurred()) - Expect(err).To(MatchError(fakes.FakeError)) - }) -}) diff --git a/pkg/transformers/price_feeds/repository.go b/pkg/transformers/price_feeds/repository.go index 8f55fd4e..63691b96 100644 --- a/pkg/transformers/price_feeds/repository.go +++ b/pkg/transformers/price_feeds/repository.go @@ -15,32 +15,29 @@ package price_feeds import ( + "fmt" "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" ) -type IPriceFeedRepository interface { - Create(headerID int64, models []PriceFeedModel) error - MarkHeaderChecked(headerID int64) error - MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) -} - type PriceFeedRepository struct { db *postgres.DB } -func NewPriceFeedRepository(db *postgres.DB) PriceFeedRepository { - return PriceFeedRepository{db: db} -} - -func (repository PriceFeedRepository) Create(headerID int64, models []PriceFeedModel) error { +func (repository PriceFeedRepository) Create(headerID int64, models []interface{}) error { tx, err := repository.db.Begin() if err != nil { return err } for _, model := range models { + priceUpdate, ok := model.(PriceFeedModel) + if !ok { + tx.Rollback() + return fmt.Errorf("model of type %T, not %T", model, PriceFeedModel{}) + } + _, err = tx.Exec(`INSERT INTO maker.price_feeds (block_number, header_id, medianizer_address, usd_value, log_idx, tx_idx, raw_log) - VALUES ($1, $2, $3, $4::NUMERIC, $5, $6, $7)`, model.BlockNumber, headerID, model.MedianizerAddress, model.UsdValue, model.LogIndex, model.TransactionIndex, model.Raw) + VALUES ($1, $2, $3, $4::NUMERIC, $5, $6, $7)`, priceUpdate.BlockNumber, headerID, priceUpdate.MedianizerAddress, priceUpdate.UsdValue, priceUpdate.LogIndex, priceUpdate.TransactionIndex, priceUpdate.Raw) if err != nil { tx.Rollback() return err @@ -81,3 +78,7 @@ func (repository PriceFeedRepository) MissingHeaders(startingBlockNumber, ending ) return result, err } + +func (repository *PriceFeedRepository) SetDB(db *postgres.DB) { + repository.db = db +} diff --git a/pkg/transformers/price_feeds/repository_test.go b/pkg/transformers/price_feeds/repository_test.go index 9ff3e9e7..08c2d674 100644 --- a/pkg/transformers/price_feeds/repository_test.go +++ b/pkg/transformers/price_feeds/repository_test.go @@ -35,14 +35,15 @@ var _ = Describe("Price feeds repository", func() { db *postgres.DB err error headerRepository datastore.HeaderRepository - priceFeedRepository price_feeds.IPriceFeedRepository + priceFeedRepository price_feeds.PriceFeedRepository ) BeforeEach(func() { db = test_config.NewTestDB(core.Node{}) test_config.CleanTestDB(db) headerRepository = repositories.NewHeaderRepository(db) - priceFeedRepository = price_feeds.NewPriceFeedRepository(db) + priceFeedRepository = price_feeds.PriceFeedRepository{} + priceFeedRepository.SetDB(db) }) Describe("Create", func() { @@ -54,7 +55,7 @@ var _ = Describe("Price feeds repository", func() { }) It("persists a price feed update", func() { - err = priceFeedRepository.Create(headerID, []price_feeds.PriceFeedModel{test_data.PriceFeedModel}) + err = priceFeedRepository.Create(headerID, []interface{}{test_data.PriceFeedModel}) Expect(err).NotTo(HaveOccurred()) var dbPriceFeedUpdate price_feeds.PriceFeedModel @@ -69,7 +70,7 @@ var _ = Describe("Price feeds repository", func() { }) It("marks headerID as checked for price feed logs", func() { - err = priceFeedRepository.Create(headerID, []price_feeds.PriceFeedModel{test_data.PriceFeedModel}) + err = priceFeedRepository.Create(headerID, []interface{}{test_data.PriceFeedModel}) Expect(err).NotTo(HaveOccurred()) var headerChecked bool @@ -82,7 +83,7 @@ var _ = Describe("Price feeds repository", func() { _, err = db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerID) Expect(err).NotTo(HaveOccurred()) - err = priceFeedRepository.Create(headerID, []price_feeds.PriceFeedModel{test_data.PriceFeedModel}) + err = priceFeedRepository.Create(headerID, []interface{}{test_data.PriceFeedModel}) Expect(err).NotTo(HaveOccurred()) var headerChecked bool @@ -92,17 +93,17 @@ var _ = Describe("Price feeds repository", func() { }) It("does not duplicate price feed updates", func() { - err = priceFeedRepository.Create(headerID, []price_feeds.PriceFeedModel{test_data.PriceFeedModel}) + err = priceFeedRepository.Create(headerID, []interface{}{test_data.PriceFeedModel}) Expect(err).NotTo(HaveOccurred()) - err = priceFeedRepository.Create(headerID, []price_feeds.PriceFeedModel{test_data.PriceFeedModel}) + err = priceFeedRepository.Create(headerID, []interface{}{test_data.PriceFeedModel}) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint")) }) It("removes price feed if corresponding header is deleted", func() { - err = priceFeedRepository.Create(headerID, []price_feeds.PriceFeedModel{test_data.PriceFeedModel}) + err = priceFeedRepository.Create(headerID, []interface{}{test_data.PriceFeedModel}) Expect(err).NotTo(HaveOccurred()) _, err = db.Exec(`DELETE FROM headers WHERE id = $1`, headerID) @@ -113,6 +114,12 @@ var _ = Describe("Price feeds repository", func() { Expect(err).To(HaveOccurred()) Expect(err).To(MatchError(sql.ErrNoRows)) }) + + It("returns an error if model is of wrong type", func() { + err = priceFeedRepository.Create(headerID, []interface{}{test_data.WrongModel{}}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("model of type")) + }) }) Describe("MarkHeaderChecked", func() { @@ -200,7 +207,8 @@ var _ = Describe("Price feeds repository", func() { _, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n)) Expect(err).NotTo(HaveOccurred()) } - priceFeedRepositoryTwo := price_feeds.NewPriceFeedRepository(dbTwo) + priceFeedRepositoryTwo := price_feeds.PriceFeedRepository{} + priceFeedRepositoryTwo.SetDB(dbTwo) err := priceFeedRepository.MarkHeaderChecked(headerIDs[0]) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/transformers/price_feeds/transformer.go b/pkg/transformers/price_feeds/transformer.go deleted file mode 100644 index 0958e61c..00000000 --- a/pkg/transformers/price_feeds/transformer.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright © 2018 Vulcanize -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package price_feeds - -import ( - "log" - - "github.com/vulcanize/vulcanizedb/pkg/core" - "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" - "github.com/vulcanize/vulcanizedb/pkg/transformers/shared" -) - -type PriceFeedTransformerInitializer struct { - Config IPriceFeedConfig -} - -func (initializer PriceFeedTransformerInitializer) NewPriceFeedTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer { - converter := PriceFeedConverter{} - fetcher := NewPriceFeedFetcher(blockChain, initializer.Config.ContractAddresses) - repository := NewPriceFeedRepository(db) - return PriceFeedTransformer{ - Config: initializer.Config, - Converter: converter, - Fetcher: fetcher, - Repository: repository, - } -} - -type PriceFeedTransformer struct { - Config IPriceFeedConfig - Converter Converter - Fetcher IPriceFeedFetcher - Repository IPriceFeedRepository -} - -func (transformer PriceFeedTransformer) Execute() error { - headers, err := transformer.Repository.MissingHeaders(transformer.Config.StartingBlockNumber, transformer.Config.EndingBlockNumber) - if err != nil { - return err - } - log.Printf("Fetching price feed event logs for %d headers \n", len(headers)) - for _, header := range headers { - logs, err := transformer.Fetcher.FetchLogValues(header.BlockNumber) - if err != nil { - return err - } - if len(logs) < 1 { - err := transformer.Repository.MarkHeaderChecked(header.Id) - if err != nil { - return err - } - } - models, err := transformer.Converter.ToModels(logs, header.Id) - if err != nil { - return err - } - err = transformer.Repository.Create(header.Id, models) - if err != nil { - return err - } - } - return nil -} diff --git a/pkg/transformers/price_feeds/transformer_test.go b/pkg/transformers/price_feeds/transformer_test.go index 39f97cc8..9810a048 100644 --- a/pkg/transformers/price_feeds/transformer_test.go +++ b/pkg/transformers/price_feeds/transformer_test.go @@ -19,39 +19,57 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/ethereum/go-ethereum/common" "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/fakes" + "github.com/vulcanize/vulcanizedb/pkg/transformers/factories" "github.com/vulcanize/vulcanizedb/pkg/transformers/price_feeds" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared" "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data" - price_feeds_mocks "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks/price_feeds" + "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks" + "math/rand" ) var _ = Describe("Price feed transformer", func() { - It("gets missing headers for price feeds", func() { - mockConverter := &price_feeds_mocks.MockPriceFeedConverter{} - mockRepository := &price_feeds_mocks.MockPriceFeedRepository{} - transformer := price_feeds.PriceFeedTransformer{ - Config: price_feeds.PriceFeedConfig, - Converter: mockConverter, - Fetcher: &price_feeds_mocks.MockPriceFeedFetcher{}, - Repository: mockRepository, - } + var ( + config = price_feeds.PriceFeedConfig + fetcher mocks.MockLogFetcher + converter mocks.MockConverter + repository mocks.MockRepository + transformer shared.Transformer + headerOne core.Header + headerTwo core.Header + ) + BeforeEach(func() { + fetcher = mocks.MockLogFetcher{} + converter = mocks.MockConverter{} + repository = mocks.MockRepository{} + headerOne = core.Header{Id: rand.Int63(), BlockNumber: rand.Int63()} + headerTwo = core.Header{Id: rand.Int63(), BlockNumber: rand.Int63()} + transformer = factories.Transformer{ + Config: config, + Converter: &converter, + Fetcher: &fetcher, + Repository: &repository, + }.NewTransformer(nil, nil) + }) + + It("sets the blockchain and db", func() { + Expect(fetcher.SetBcCalled).To(BeTrue()) + Expect(repository.SetDbCalled).To(BeTrue()) + }) + + It("gets missing headers for price feeds", func() { err := transformer.Execute() Expect(err).NotTo(HaveOccurred()) - mockRepository.AssertMissingHeadersCalledwith(price_feeds.PriceFeedConfig.StartingBlockNumber, price_feeds.PriceFeedConfig.EndingBlockNumber) + Expect(repository.PassedStartingBlockNumber).To(Equal(config.StartingBlockNumber)) + Expect(repository.PassedEndingBlockNumber).To(Equal(config.EndingBlockNumber)) }) It("returns error is missing headers call returns err", func() { - mockConverter := &price_feeds_mocks.MockPriceFeedConverter{} - mockRepository := &price_feeds_mocks.MockPriceFeedRepository{} - mockRepository.SetMissingHeadersErr(fakes.FakeError) - transformer := price_feeds.PriceFeedTransformer{ - Converter: mockConverter, - Fetcher: &price_feeds_mocks.MockPriceFeedFetcher{}, - Repository: mockRepository, - } + repository.SetMissingHeadersError(fakes.FakeError) err := transformer.Execute() @@ -60,35 +78,19 @@ var _ = Describe("Price feed transformer", func() { }) It("fetches logs for missing headers", func() { - mockConverter := &price_feeds_mocks.MockPriceFeedConverter{} - mockRepository := &price_feeds_mocks.MockPriceFeedRepository{} - blockNumberOne := int64(1) - blockNumberTwo := int64(2) - mockRepository.SetMissingHeaders([]core.Header{{BlockNumber: blockNumberOne}, {BlockNumber: blockNumberTwo}}) - mockFetcher := &price_feeds_mocks.MockPriceFeedFetcher{} - transformer := price_feeds.PriceFeedTransformer{ - Converter: mockConverter, - Fetcher: mockFetcher, - Repository: mockRepository, - } + repository.SetMissingHeaders([]core.Header{headerOne, headerTwo}) err := transformer.Execute() Expect(err).NotTo(HaveOccurred()) - mockFetcher.AssertFetchLogValuesCalledWith([]int64{blockNumberOne, blockNumberTwo}) + Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{config.ContractAddresses, config.ContractAddresses})) + Expect(fetcher.FetchedTopics).To(Equal([][]common.Hash{{common.HexToHash(config.Topic)}})) + Expect(fetcher.FetchedBlocks).To(Equal([]int64{headerOne.BlockNumber, headerTwo.BlockNumber})) }) It("returns err if fetcher returns err", func() { - mockConverter := &price_feeds_mocks.MockPriceFeedConverter{} - mockRepository := &price_feeds_mocks.MockPriceFeedRepository{} - mockRepository.SetMissingHeaders([]core.Header{{BlockNumber: 1}}) - mockFetcher := &price_feeds_mocks.MockPriceFeedFetcher{} - mockFetcher.SetReturnErr(fakes.FakeError) - transformer := price_feeds.PriceFeedTransformer{ - Converter: mockConverter, - Fetcher: mockFetcher, - Repository: mockRepository, - } + repository.SetMissingHeaders([]core.Header{headerOne}) + fetcher.SetFetcherError(fakes.FakeError) err := transformer.Execute() @@ -97,34 +99,17 @@ var _ = Describe("Price feed transformer", func() { }) It("marks header checked if no logs returned", func() { - mockConverter := &price_feeds_mocks.MockPriceFeedConverter{} - mockRepository := &price_feeds_mocks.MockPriceFeedRepository{} - headerID := int64(123) - mockRepository.SetMissingHeaders([]core.Header{{Id: headerID}}) - mockFetcher := &price_feeds_mocks.MockPriceFeedFetcher{} - transformer := price_feeds.PriceFeedTransformer{ - Converter: mockConverter, - Fetcher: mockFetcher, - Repository: mockRepository, - } + repository.SetMissingHeaders([]core.Header{headerOne}) err := transformer.Execute() Expect(err).NotTo(HaveOccurred()) - mockRepository.AssertMarkHeaderCheckedCalledWith(headerID) + repository.AssertMarkHeaderCheckedCalledWith(headerOne.Id) }) It("returns error if marking header checked returns err", func() { - mockConverter := &price_feeds_mocks.MockPriceFeedConverter{} - mockRepository := &price_feeds_mocks.MockPriceFeedRepository{} - mockRepository.SetMissingHeaders([]core.Header{{Id: int64(123)}}) - mockRepository.SetMarkHeaderCheckedErr(fakes.FakeError) - mockFetcher := &price_feeds_mocks.MockPriceFeedFetcher{} - transformer := price_feeds.PriceFeedTransformer{ - Converter: mockConverter, - Fetcher: mockFetcher, - Repository: mockRepository, - } + repository.SetMissingHeaders([]core.Header{headerOne}) + repository.SetMarkHeaderCheckedError(fakes.FakeError) err := transformer.Execute() @@ -133,38 +118,19 @@ var _ = Describe("Price feed transformer", func() { }) It("converts log to a model", func() { - mockConverter := &price_feeds_mocks.MockPriceFeedConverter{} - mockFetcher := &price_feeds_mocks.MockPriceFeedFetcher{} - mockFetcher.SetReturnLogs([]types.Log{test_data.EthPriceFeedLog}) - mockRepository := &price_feeds_mocks.MockPriceFeedRepository{} - headerID := int64(11111) - mockRepository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: headerID}}) - transformer := price_feeds.PriceFeedTransformer{ - Fetcher: mockFetcher, - Converter: mockConverter, - Repository: mockRepository, - } + fetcher.SetFetchedLogs([]types.Log{test_data.EthPriceFeedLog}) + repository.SetMissingHeaders([]core.Header{headerOne}) err := transformer.Execute() Expect(err).NotTo(HaveOccurred()) - Expect(mockConverter.PassedHeaderID).To(Equal(headerID)) - Expect(mockConverter.PassedLogs).To(Equal([]types.Log{test_data.EthPriceFeedLog})) + Expect(converter.PassedLogs).To(Equal([]types.Log{test_data.EthPriceFeedLog})) }) It("returns err if converter returns err", func() { - mockConverter := &price_feeds_mocks.MockPriceFeedConverter{} - mockConverter.SetConverterErr(fakes.FakeError) - mockFetcher := &price_feeds_mocks.MockPriceFeedFetcher{} - mockFetcher.SetReturnLogs([]types.Log{test_data.EthPriceFeedLog}) - mockRepository := &price_feeds_mocks.MockPriceFeedRepository{} - headerID := int64(11111) - mockRepository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: headerID}}) - transformer := price_feeds.PriceFeedTransformer{ - Fetcher: mockFetcher, - Converter: mockConverter, - Repository: mockRepository, - } + converter.SetConverterError(fakes.FakeError) + fetcher.SetFetchedLogs([]types.Log{test_data.EthPriceFeedLog}) + repository.SetMissingHeaders([]core.Header{headerOne}) err := transformer.Execute() @@ -173,36 +139,22 @@ var _ = Describe("Price feed transformer", func() { }) It("persists model converted from log", func() { - mockConverter := &price_feeds_mocks.MockPriceFeedConverter{} - mockRepository := &price_feeds_mocks.MockPriceFeedRepository{} - headerID := int64(11111) - mockRepository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: headerID}}) - mockFetcher := &price_feeds_mocks.MockPriceFeedFetcher{} - mockFetcher.SetReturnLogs([]types.Log{test_data.EthPriceFeedLog}) - transformer := price_feeds.PriceFeedTransformer{ - Converter: mockConverter, - Fetcher: mockFetcher, - Repository: mockRepository, - } + converter.SetReturnModels([]interface{}{test_data.PriceFeedModel}) + repository.SetMissingHeaders([]core.Header{headerOne}) + fetcher.SetFetchedLogs([]types.Log{test_data.EthPriceFeedLog}) err := transformer.Execute() Expect(err).NotTo(HaveOccurred()) - mockRepository.AssertCreateCalledWith(headerID, []price_feeds.PriceFeedModel{test_data.PriceFeedModel}) + Expect(repository.PassedHeaderID).To(Equal(headerOne.Id)) + Expect(len(repository.PassedModels)).To(Equal(1)) + Expect(repository.PassedModels[0]).To(Equal(test_data.PriceFeedModel)) }) It("returns error if creating price feed update returns error", func() { - mockConverter := &price_feeds_mocks.MockPriceFeedConverter{} - mockRepository := &price_feeds_mocks.MockPriceFeedRepository{} - mockRepository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: 2}}) - mockRepository.SetCreateErr(fakes.FakeError) - mockFetcher := &price_feeds_mocks.MockPriceFeedFetcher{} - mockFetcher.SetReturnLogs([]types.Log{{}}) - transformer := price_feeds.PriceFeedTransformer{ - Converter: mockConverter, - Fetcher: mockFetcher, - Repository: mockRepository, - } + repository.SetMissingHeaders([]core.Header{headerOne}) + repository.SetCreateError(fakes.FakeError) + fetcher.SetFetchedLogs([]types.Log{{}}) err := transformer.Execute() diff --git a/pkg/transformers/shared/constants.go b/pkg/transformers/shared/constants.go index eeb241c0..04bcad66 100644 --- a/pkg/transformers/shared/constants.go +++ b/pkg/transformers/shared/constants.go @@ -46,7 +46,7 @@ var ( PepContractAddress = getContractValue("contract.pep", "0xB1997239Cfc3d15578A3a09730f7f84A90BB4975") PipContractAddress = getContractValue("contract.pip", "0x9FfFE440258B79c5d6604001674A4722FfC0f7Bc") PitContractAddress = getContractValue("contract.pit", "0xe7cf3198787c9a4daac73371a38f29aaeeced87e") - RepContractAddress = getContractValue("contract.rep", "0xf88bbdc1e2718f8857f30a180076ec38d53cf296") + RepContractAddress = getContractValue("contract.rep", "0xf88bBDc1E2718F8857F30A180076ec38d53cf296") VatContractAddress = getContractValue("contract.vat", "0xcd726790550afcd77e9a7a47e86a3f9010af126b") VowContractAddress = getContractValue("contract.vow", "0x3728e9777B2a0a611ee0F89e00E01044ce4736d1") diff --git a/pkg/transformers/test_data/mocks/price_feeds/converter.go b/pkg/transformers/test_data/mocks/price_feeds/converter.go deleted file mode 100644 index c4f800da..00000000 --- a/pkg/transformers/test_data/mocks/price_feeds/converter.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2018 Vulcanize -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package price_feeds - -import ( - "github.com/ethereum/go-ethereum/core/types" - "github.com/vulcanize/vulcanizedb/pkg/transformers/price_feeds" - "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data" -) - -type MockPriceFeedConverter struct { - converterErr error - PassedLogs []types.Log - PassedHeaderID int64 -} - -func (converter *MockPriceFeedConverter) ToModels(logs []types.Log, headerID int64) ([]price_feeds.PriceFeedModel, error) { - converter.PassedLogs = logs - converter.PassedHeaderID = headerID - return []price_feeds.PriceFeedModel{test_data.PriceFeedModel}, converter.converterErr -} - -func (converter *MockPriceFeedConverter) SetConverterErr(e error) { - converter.converterErr = e -} diff --git a/pkg/transformers/test_data/mocks/price_feeds/fetcher.go b/pkg/transformers/test_data/mocks/price_feeds/fetcher.go deleted file mode 100644 index 951e6aa2..00000000 --- a/pkg/transformers/test_data/mocks/price_feeds/fetcher.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2018 Vulcanize -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package price_feeds - -import ( - "github.com/ethereum/go-ethereum/core/types" - . "github.com/onsi/gomega" -) - -type MockPriceFeedFetcher struct { - passedBlockNumbers []int64 - returnErr error - returnLogs []types.Log -} - -func (fetcher *MockPriceFeedFetcher) SetReturnErr(err error) { - fetcher.returnErr = err -} - -func (fetcher *MockPriceFeedFetcher) SetReturnLogs(logs []types.Log) { - fetcher.returnLogs = logs -} - -func (fetcher *MockPriceFeedFetcher) FetchLogValues(blockNumber int64) ([]types.Log, error) { - fetcher.passedBlockNumbers = append(fetcher.passedBlockNumbers, blockNumber) - return fetcher.returnLogs, fetcher.returnErr -} - -func (fetcher *MockPriceFeedFetcher) AssertFetchLogValuesCalledWith(blockNumbers []int64) { - Expect(fetcher.passedBlockNumbers).To(Equal(blockNumbers)) -} diff --git a/pkg/transformers/test_data/mocks/price_feeds/repository.go b/pkg/transformers/test_data/mocks/price_feeds/repository.go deleted file mode 100644 index a5c39d86..00000000 --- a/pkg/transformers/test_data/mocks/price_feeds/repository.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2018 Vulcanize -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package price_feeds - -import ( - . "github.com/onsi/gomega" - - "github.com/vulcanize/vulcanizedb/pkg/core" - "github.com/vulcanize/vulcanizedb/pkg/transformers/price_feeds" -) - -type MockPriceFeedRepository struct { - createErr error - createPassedHeaderID int64 - markHeaderCheckedErr error - markHeaderCheckedPassedHeaderID int64 - missingHeaders []core.Header - missingHeadersErr error - passedEndingBlockNumber int64 - passedModels []price_feeds.PriceFeedModel - passedStartingBlockNumber int64 -} - -func (repository *MockPriceFeedRepository) SetCreateErr(err error) { - repository.createErr = err -} - -func (repository *MockPriceFeedRepository) SetMarkHeaderCheckedErr(err error) { - repository.markHeaderCheckedErr = err -} - -func (repository *MockPriceFeedRepository) SetMissingHeadersErr(err error) { - repository.missingHeadersErr = err -} - -func (repository *MockPriceFeedRepository) SetMissingHeaders(headers []core.Header) { - repository.missingHeaders = headers -} - -func (repository *MockPriceFeedRepository) Create(headerID int64, models []price_feeds.PriceFeedModel) error { - repository.createPassedHeaderID = headerID - repository.passedModels = models - return repository.createErr -} - -func (repository *MockPriceFeedRepository) MarkHeaderChecked(headerID int64) error { - repository.markHeaderCheckedPassedHeaderID = headerID - return repository.markHeaderCheckedErr -} - -func (repository *MockPriceFeedRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) { - repository.passedStartingBlockNumber = startingBlockNumber - repository.passedEndingBlockNumber = endingBlockNumber - return repository.missingHeaders, repository.missingHeadersErr -} - -func (repository *MockPriceFeedRepository) AssertCreateCalledWith(headerID int64, models []price_feeds.PriceFeedModel) { - Expect(repository.createPassedHeaderID).To(Equal(headerID)) - Expect(repository.passedModels).To(Equal(models)) -} - -func (repository *MockPriceFeedRepository) AssertMarkHeaderCheckedCalledWith(headerID int64) { - Expect(repository.markHeaderCheckedPassedHeaderID).To(Equal(headerID)) -} - -func (repository *MockPriceFeedRepository) AssertMissingHeadersCalledwith(startingBlockNumber, endingBlockNumber int64) { - Expect(repository.passedStartingBlockNumber).To(Equal(startingBlockNumber)) - Expect(repository.passedEndingBlockNumber).To(Equal(endingBlockNumber)) -} diff --git a/pkg/transformers/transformers.go b/pkg/transformers/transformers.go index c5c8ae8b..22ed1ea7 100644 --- a/pkg/transformers/transformers.go +++ b/pkg/transformers/transformers.go @@ -109,8 +109,14 @@ var ( Fetcher: &shared.Fetcher{}, }.NewTransformer - PriceFeedTransformerInitializer = price_feeds.PriceFeedTransformerInitializer{Config: price_feeds.PriceFeedConfig}.NewPriceFeedTransformer - TendTransformerInitializer = factories.Transformer{ + PriceFeedTransformerInitializer = factories.Transformer{ + Config: price_feeds.PriceFeedConfig, + Converter: &price_feeds.PriceFeedConverter{}, + Repository: &price_feeds.PriceFeedRepository{}, + Fetcher: &shared.Fetcher{}, + }.NewTransformer + + TendTransformerInitializer = factories.Transformer{ Config: tend.TendConfig, Converter: &tend.TendConverter{}, Repository: &tend.TendRepository{},