Merge pull request #73 from 8thlight/transformer-refactoring
Transformer factory evaluation
This commit is contained in:
commit
f10bddf353
@ -86,33 +86,33 @@ func getTransformerInititalizers(transformerNames []string) []shared2.Transforme
|
||||
func buildTransformerInitializerMap() map[string]shared2.TransformerInitializer {
|
||||
transformerInitializerMap := make(map[string]shared2.TransformerInitializer)
|
||||
|
||||
transformerInitializerMap["bite"] = transformers.BiteTransformerInitializer
|
||||
transformerInitializerMap["catFileChopLump"] = transformers.CatFileChopLumpTransformerInitializer
|
||||
transformerInitializerMap["catFileFlip"] = transformers.CatFileFlipTransformerInitializer
|
||||
transformerInitializerMap["catFilePitVow"] = transformers.CatFilePitVowTransformerInitializer
|
||||
transformerInitializerMap["deal"] = transformers.DealTransformerInitializer
|
||||
transformerInitializerMap["dent"] = transformers.DentTransformerInitializer
|
||||
transformerInitializerMap["dripDrip"] = transformers.DripDripTransformerInitializer
|
||||
transformerInitializerMap["dripFileIlk"] = transformers.DripFileIlkTransformerInitializer
|
||||
transformerInitializerMap["dripFileRepo"] = transformers.DripFileRepoTransformerInitializer
|
||||
transformerInitializerMap["dripFileVow"] = transformers.DripFileVowTransfromerInitializer
|
||||
transformerInitializerMap["flipKick"] = transformers.FlipKickTransformerInitializer
|
||||
transformerInitializerMap["flopKick"] = transformers.FlopKickTransformerInitializer
|
||||
transformerInitializerMap["frob"] = transformers.FrobTransformerInitializer
|
||||
transformerInitializerMap["pitFileDebtCeiling"] = transformers.PitFileDebtCeilingTransformerInitializer
|
||||
transformerInitializerMap["pitFileIlk"] = transformers.PitFileIlkTransformerInitializer
|
||||
transformerInitializerMap["pitFileStabilityFee"] = transformers.PitFileStabilityFeeTransformerInitializer
|
||||
transformerInitializerMap["priceFeed"] = transformers.PriceFeedTransformerInitializer
|
||||
transformerInitializerMap["tend"] = transformers.TendTransformerInitializer
|
||||
transformerInitializerMap["vatGrab"] = transformers.VatGrabTransformerInitializer
|
||||
transformerInitializerMap["vatInit"] = transformers.VatInitTransformerInitializer
|
||||
transformerInitializerMap["vatMove"] = transformers.VatMoveTransformerInitializer
|
||||
transformerInitializerMap["vatHeal"] = transformers.VatHealTransformerInitializer
|
||||
transformerInitializerMap["vatFold"] = transformers.VatFoldTransformerInitializer
|
||||
transformerInitializerMap["vatSlip"] = transformers.VatSlipTransformerInitializer
|
||||
transformerInitializerMap["vatToll"] = transformers.VatTollTransformerInitializer
|
||||
transformerInitializerMap["vatTune"] = transformers.VatTuneTransformerInitializer
|
||||
transformerInitializerMap["vatFlux"] = transformers.VatFluxTransformerInitializer
|
||||
transformerInitializerMap[shared2.BiteLabel] = transformers.BiteTransformerInitializer
|
||||
transformerInitializerMap[shared2.CatFileChopLumpLabel] = transformers.CatFileChopLumpTransformerInitializer
|
||||
transformerInitializerMap[shared2.CatFileFlipLabel] = transformers.CatFileFlipTransformerInitializer
|
||||
transformerInitializerMap[shared2.CatFilePitVowLabel] = transformers.CatFilePitVowTransformerInitializer
|
||||
transformerInitializerMap[shared2.DealLabel] = transformers.DealTransformerInitializer
|
||||
transformerInitializerMap[shared2.DentLabel] = transformers.DentTransformerInitializer
|
||||
transformerInitializerMap[shared2.DripDripLabel] = transformers.DripDripTransformerInitializer
|
||||
transformerInitializerMap[shared2.DripFileIlkLabel] = transformers.DripFileIlkTransformerInitializer
|
||||
transformerInitializerMap[shared2.DripFileRepoLabel] = transformers.DripFileRepoTransformerInitializer
|
||||
transformerInitializerMap[shared2.DripFileVowLabel] = transformers.DripFileVowTransfromerInitializer
|
||||
transformerInitializerMap[shared2.FlipKickLabel] = transformers.FlipKickTransformerInitializer
|
||||
transformerInitializerMap[shared2.FlopKickLabel] = transformers.FlopKickTransformerInitializer
|
||||
transformerInitializerMap[shared2.FrobLabel] = transformers.FrobTransformerInitializer
|
||||
transformerInitializerMap[shared2.PitFileDebtCeilingLabel] = transformers.PitFileDebtCeilingTransformerInitializer
|
||||
transformerInitializerMap[shared2.PitFileIlkLabel] = transformers.PitFileIlkTransformerInitializer
|
||||
transformerInitializerMap[shared2.PitFileStabilityFeeLabel] = transformers.PitFileStabilityFeeTransformerInitializer
|
||||
transformerInitializerMap[shared2.PriceFeedLabel] = transformers.PriceFeedTransformerInitializer
|
||||
transformerInitializerMap[shared2.TendLabel] = transformers.TendTransformerInitializer
|
||||
transformerInitializerMap[shared2.VatGrabLabel] = transformers.VatGrabTransformerInitializer
|
||||
transformerInitializerMap[shared2.VatInitLabel] = transformers.VatInitTransformerInitializer
|
||||
transformerInitializerMap[shared2.VatMoveLabel] = transformers.VatMoveTransformerInitializer
|
||||
transformerInitializerMap[shared2.VatHealLabel] = transformers.VatHealTransformerInitializer
|
||||
transformerInitializerMap[shared2.VatFoldLabel] = transformers.VatFoldTransformerInitializer
|
||||
transformerInitializerMap[shared2.VatSlipLabel] = transformers.VatSlipTransformerInitializer
|
||||
transformerInitializerMap[shared2.VatTollLabel] = transformers.VatTollTransformerInitializer
|
||||
transformerInitializerMap[shared2.VatTuneLabel] = transformers.VatTuneTransformerInitializer
|
||||
transformerInitializerMap[shared2.VatFluxLabel] = transformers.VatFluxTransformerInitializer
|
||||
|
||||
return transformerInitializerMap
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
-- Dumped from database version 10.3
|
||||
-- Dumped by pg_dump version 10.3
|
||||
-- Dumped from database version 10.5
|
||||
-- Dumped by pg_dump version 10.5
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
|
@ -12,14 +12,15 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package drip_file
|
||||
package ilk
|
||||
|
||||
import "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
var DripFileConfig = shared.TransformerConfig{
|
||||
var DripFileIlkConfig = shared.SingleTransformerConfig{
|
||||
TransformerName: shared.DripFileIlkLabel,
|
||||
ContractAddresses: []string{shared.DripContractAddress},
|
||||
ContractAbi: shared.DripABI,
|
||||
Topics: []string{shared.DripFileIlkSignature, shared.DripFileRepoSignature},
|
||||
Topic: shared.DripFileIlkSignature,
|
||||
StartingBlockNumber: 0,
|
||||
EndingBlockNumber: 10000000,
|
||||
}
|
@ -24,19 +24,16 @@ import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type Converter interface {
|
||||
ToModels(ethLogs []types.Log) ([]DripFileIlkModel, error)
|
||||
}
|
||||
|
||||
type DripFileIlkConverter struct{}
|
||||
|
||||
func (DripFileIlkConverter) ToModels(ethLogs []types.Log) ([]DripFileIlkModel, error) {
|
||||
var models []DripFileIlkModel
|
||||
func (DripFileIlkConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
var models []interface{}
|
||||
for _, ethLog := range ethLogs {
|
||||
err := verifyLog(ethLog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ilk := string(bytes.Trim(ethLog.Topics[2].Bytes(), "\x00"))
|
||||
vow := string(bytes.Trim(ethLog.Topics[3].Bytes(), "\x00"))
|
||||
taxBytes := ethLog.Data[len(ethLog.Data)-shared.DataItemLength:]
|
||||
@ -45,6 +42,7 @@ func (DripFileIlkConverter) ToModels(ethLogs []types.Log) ([]DripFileIlkModel, e
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
model := DripFileIlkModel{
|
||||
Ilk: ilk,
|
||||
Vow: vow,
|
||||
|
@ -56,6 +56,6 @@ var _ = Describe("Drip file ilk converter", func() {
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(models)).To(Equal(1))
|
||||
Expect(models[0]).To(Equal(test_data.DripFileIlkModel))
|
||||
Expect(models[0].(ilk.DripFileIlkModel)).To(Equal(test_data.DripFileIlkModel))
|
||||
})
|
||||
})
|
||||
|
@ -15,35 +15,34 @@
|
||||
package ilk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(headerID int64, models []DripFileIlkModel) error
|
||||
MarkHeaderChecked(headerID int64) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
}
|
||||
|
||||
type DripFileIlkRepository struct {
|
||||
db *postgres.DB
|
||||
}
|
||||
|
||||
func NewDripFileIlkRepository(db *postgres.DB) DripFileIlkRepository {
|
||||
return DripFileIlkRepository{db: db}
|
||||
}
|
||||
|
||||
func (repository DripFileIlkRepository) Create(headerID int64, models []DripFileIlkModel) error {
|
||||
func (repository DripFileIlkRepository) Create(headerID int64, models []interface{}) error {
|
||||
tx, err := repository.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, model := range models {
|
||||
ilk, ok := model.(DripFileIlkModel)
|
||||
if !ok {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("model of type %T, not %T", model, DripFileIlkModel{})
|
||||
}
|
||||
|
||||
_, err = tx.Exec(
|
||||
`INSERT into maker.drip_file_ilk (header_id, ilk, vow, tax, log_idx, tx_idx, raw_log)
|
||||
VALUES($1, $2, $3, $4::NUMERIC, $5, $6, $7)`,
|
||||
headerID, model.Ilk, model.Vow, model.Tax, model.LogIndex, model.TransactionIndex, model.Raw,
|
||||
VALUES($1, $2, $3, $4::NUMERIC, $5, $6, $7)`,
|
||||
headerID, ilk.Ilk, ilk.Vow, ilk.Tax, ilk.LogIndex, ilk.TransactionIndex, ilk.Raw,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
@ -51,20 +50,21 @@ func (repository DripFileIlkRepository) Create(headerID int64, models []DripFile
|
||||
}
|
||||
_, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, drip_file_ilk_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_ilk_checked = $2`, headerID, true)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_ilk_checked = $2`, headerID, true)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (repository DripFileIlkRepository) MarkHeaderChecked(headerID int64) error {
|
||||
_, err := repository.db.Exec(`INSERT INTO public.checked_headers (header_id, drip_file_ilk_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_ilk_checked = $2`, headerID, true)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_ilk_checked = $2`, headerID, true)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -73,14 +73,18 @@ func (repository DripFileIlkRepository) MissingHeaders(startingBlockNumber, endi
|
||||
err := repository.db.Select(
|
||||
&result,
|
||||
`SELECT headers.id, headers.block_number FROM headers
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
WHERE (header_id ISNULL OR drip_file_ilk_checked IS FALSE)
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
WHERE (header_id ISNULL OR drip_file_ilk_checked IS FALSE)
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
startingBlockNumber,
|
||||
endingBlockNumber,
|
||||
repository.db.Node.ID,
|
||||
)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (repository *DripFileIlkRepository) SetDB(db *postgres.DB) {
|
||||
repository.db = db
|
||||
}
|
||||
|
@ -16,10 +16,8 @@ package ilk_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
@ -33,7 +31,7 @@ import (
|
||||
var _ = Describe("Drip file ilk repository", func() {
|
||||
var (
|
||||
db *postgres.DB
|
||||
dripFileIlkRepository ilk.Repository
|
||||
dripFileIlkRepository ilk.DripFileIlkRepository
|
||||
err error
|
||||
headerRepository datastore.HeaderRepository
|
||||
)
|
||||
@ -42,7 +40,8 @@ var _ = Describe("Drip file ilk repository", func() {
|
||||
db = test_config.NewTestDB(test_config.NewTestNode())
|
||||
test_config.CleanTestDB(db)
|
||||
headerRepository = repositories.NewHeaderRepository(db)
|
||||
dripFileIlkRepository = ilk.NewDripFileIlkRepository(db)
|
||||
dripFileIlkRepository = ilk.DripFileIlkRepository{}
|
||||
dripFileIlkRepository.SetDB(db)
|
||||
})
|
||||
|
||||
Describe("Create", func() {
|
||||
@ -52,7 +51,7 @@ var _ = Describe("Drip file ilk repository", func() {
|
||||
headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = dripFileIlkRepository.Create(headerID, []ilk.DripFileIlkModel{test_data.DripFileIlkModel})
|
||||
err = dripFileIlkRepository.Create(headerID, []interface{}{test_data.DripFileIlkModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -69,7 +68,6 @@ var _ = Describe("Drip file ilk repository", func() {
|
||||
})
|
||||
|
||||
It("marks header as checked for logs", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var headerChecked bool
|
||||
err = db.Get(&headerChecked, `SELECT drip_file_ilk_checked FROM public.checked_headers WHERE header_id = $1`, headerID)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@ -77,7 +75,7 @@ var _ = Describe("Drip file ilk repository", func() {
|
||||
})
|
||||
|
||||
It("does not duplicate drip file events", func() {
|
||||
err = dripFileIlkRepository.Create(headerID, []ilk.DripFileIlkModel{test_data.DripFileIlkModel})
|
||||
err = dripFileIlkRepository.Create(headerID, []interface{}{test_data.DripFileIlkModel})
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
|
||||
@ -92,6 +90,12 @@ var _ = Describe("Drip file ilk repository", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(sql.ErrNoRows))
|
||||
})
|
||||
|
||||
It("Returns an error if model is of wrong type", func() {
|
||||
err = dripFileIlkRepository.Create(headerID, []interface{}{test_data.WrongModel{}})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("model of type"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MarkHeaderChecked", func() {
|
||||
@ -139,12 +143,12 @@ var _ = Describe("Drip file ilk repository", func() {
|
||||
blockNumbers = []int64{startingBlock, dripFileBlock, endingBlock, endingBlock + 1}
|
||||
|
||||
headerIDs = []int64{}
|
||||
|
||||
for _, n := range blockNumbers {
|
||||
headerID, err := headerRepository.CreateOrUpdateHeader(fakes.GetFakeHeader(n))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
headerIDs = append(headerIDs, headerID)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
It("returns headers with no associated drip file event", func() {
|
||||
@ -179,7 +183,8 @@ var _ = Describe("Drip file ilk repository", func() {
|
||||
_, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
dripFileIlkRepositoryTwo := ilk.NewDripFileIlkRepository(dbTwo)
|
||||
dripFileIlkRepositoryTwo := ilk.DripFileIlkRepository{}
|
||||
dripFileIlkRepositoryTwo.SetDB(dbTwo)
|
||||
err := dripFileIlkRepository.MarkHeaderChecked(headerIDs[0])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -1,79 +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 ilk
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type DripFileIlkTransformer struct {
|
||||
Config shared.TransformerConfig
|
||||
Converter Converter
|
||||
Fetcher shared.LogFetcher
|
||||
Repository Repository
|
||||
}
|
||||
|
||||
type DripFileIlkTransformerInitializer struct {
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
func (initializer DripFileIlkTransformerInitializer) NewDripFileIlkTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
converter := DripFileIlkConverter{}
|
||||
fetcher := shared.NewFetcher(blockChain)
|
||||
repository := NewDripFileIlkRepository(db)
|
||||
return DripFileIlkTransformer{
|
||||
Config: initializer.Config,
|
||||
Converter: converter,
|
||||
Fetcher: fetcher,
|
||||
Repository: repository,
|
||||
}
|
||||
}
|
||||
|
||||
func (transformer DripFileIlkTransformer) Execute() error {
|
||||
missingHeaders, err := transformer.Repository.MissingHeaders(transformer.Config.StartingBlockNumber, transformer.Config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Fetching drip file ilk event logs for %d headers \n", len(missingHeaders))
|
||||
for _, header := range missingHeaders {
|
||||
topics := [][]common.Hash{{common.HexToHash(shared.DripFileIlkSignature)}}
|
||||
matchingLogs, err := transformer.Fetcher.FetchLogs(drip_file.DripFileConfig.ContractAddresses, topics, header.BlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(matchingLogs) < 1 {
|
||||
err = transformer.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
model, err := transformer.Converter.ToModels(matchingLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = transformer.Repository.Create(header.Id, model)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -19,10 +19,11 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"math/rand"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/ilk"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
@ -31,31 +32,45 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Drip file ilk transformer", func() {
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
repository := &ilk_mocks.MockDripFileIlkRepository{}
|
||||
transformer := ilk.DripFileIlkTransformer{
|
||||
Config: drip_file.DripFileConfig,
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &ilk_mocks.MockDripFileIlkConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
var (
|
||||
config = ilk.DripFileIlkConfig
|
||||
fetcher mocks.MockLogFetcher
|
||||
converter ilk_mocks.MockDripFileIlkConverter
|
||||
repository ilk_mocks.MockDripFileIlkRepository
|
||||
transformer shared.Transformer
|
||||
headerOne core.Header
|
||||
headerTwo core.Header
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fetcher = mocks.MockLogFetcher{}
|
||||
converter = ilk_mocks.MockDripFileIlkConverter{}
|
||||
repository = ilk_mocks.MockDripFileIlkRepository{}
|
||||
transformer = factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}.NewTransformer(nil, nil)
|
||||
headerOne = core.Header{BlockNumber: rand.Int63(), Id: rand.Int63()}
|
||||
headerTwo = core.Header{BlockNumber: rand.Int63(), Id: rand.Int63()}
|
||||
})
|
||||
|
||||
It("sets the blockchain and database", func() {
|
||||
Expect(fetcher.SetBcCalled).To(BeTrue())
|
||||
Expect(repository.SetDbCalled).To(BeTrue())
|
||||
})
|
||||
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(drip_file.DripFileConfig.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(drip_file.DripFileConfig.EndingBlockNumber))
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(config.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(config.EndingBlockNumber))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for missing headers", func() {
|
||||
repository := &ilk_mocks.MockDripFileIlkRepository{}
|
||||
repository.SetMissingHeadersErr(fakes.FakeError)
|
||||
transformer := ilk.DripFileIlkTransformer{
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &ilk_mocks.MockDripFileIlkConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
repository.SetMissingHeadersError(fakes.FakeError)
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
@ -63,33 +78,18 @@ var _ = Describe("Drip file ilk transformer", func() {
|
||||
})
|
||||
|
||||
It("fetches logs for missing headers", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
repository := &ilk_mocks.MockDripFileIlkRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}, {BlockNumber: 2}})
|
||||
transformer := ilk.DripFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &ilk_mocks.MockDripFileIlkConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{1, 2}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{drip_file.DripFileConfig.ContractAddresses, drip_file.DripFileConfig.ContractAddresses}))
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{headerOne.BlockNumber, headerTwo.BlockNumber}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{config.ContractAddresses, config.ContractAddresses}))
|
||||
Expect(fetcher.FetchedTopics).To(Equal([][]common.Hash{{common.HexToHash(shared.DripFileIlkSignature)}}))
|
||||
})
|
||||
|
||||
It("returns error if fetcher returns error", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetcherError(fakes.FakeError)
|
||||
repository := &ilk_mocks.MockDripFileIlkRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := ilk.DripFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &ilk_mocks.MockDripFileIlkConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -98,34 +98,16 @@ var _ = Describe("Drip file ilk transformer", func() {
|
||||
})
|
||||
|
||||
It("marks header checked if no logs returned", func() {
|
||||
mockConverter := &ilk_mocks.MockDripFileIlkConverter{}
|
||||
mockRepository := &ilk_mocks.MockDripFileIlkRepository{}
|
||||
headerID := int64(123)
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: headerID}})
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := ilk.DripFileIlkTransformer{
|
||||
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 := &ilk_mocks.MockDripFileIlkConverter{}
|
||||
mockRepository := &ilk_mocks.MockDripFileIlkRepository{}
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: int64(123)}})
|
||||
mockRepository.SetMarkHeaderCheckedErr(fakes.FakeError)
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := ilk.DripFileIlkTransformer{
|
||||
Converter: mockConverter,
|
||||
Fetcher: mockFetcher,
|
||||
Repository: mockRepository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetMarkHeaderCheckedError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -134,16 +116,8 @@ var _ = Describe("Drip file ilk transformer", func() {
|
||||
})
|
||||
|
||||
It("converts matching logs", func() {
|
||||
converter := &ilk_mocks.MockDripFileIlkConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileIlkLog})
|
||||
repository := &ilk_mocks.MockDripFileIlkRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := ilk.DripFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -152,17 +126,9 @@ var _ = Describe("Drip file ilk transformer", func() {
|
||||
})
|
||||
|
||||
It("returns error if converter returns error", func() {
|
||||
converter := &ilk_mocks.MockDripFileIlkConverter{}
|
||||
converter.SetConverterError(fakes.FakeError)
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileIlkLog})
|
||||
repository := &ilk_mocks.MockDripFileIlkRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := ilk.DripFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -171,37 +137,20 @@ var _ = Describe("Drip file ilk transformer", func() {
|
||||
})
|
||||
|
||||
It("persists drip file model", func() {
|
||||
converter := &ilk_mocks.MockDripFileIlkConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileIlkLog})
|
||||
repository := &ilk_mocks.MockDripFileIlkRepository{}
|
||||
fakeHeader := core.Header{BlockNumber: 1, Id: 2}
|
||||
repository.SetMissingHeaders([]core.Header{fakeHeader})
|
||||
transformer := ilk.DripFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedHeaderID).To(Equal(fakeHeader.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]ilk.DripFileIlkModel{test_data.DripFileIlkModel}))
|
||||
Expect(repository.PassedHeaderID).To(Equal(headerOne.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]interface{}{test_data.DripFileIlkModel}))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for create", func() {
|
||||
converter := &ilk_mocks.MockDripFileIlkConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileIlkLog})
|
||||
repository := &ilk_mocks.MockDripFileIlkRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: 2}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetCreateError(fakes.FakeError)
|
||||
transformer := ilk.DripFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
|
26
pkg/transformers/drip_file/repo/config.go
Normal file
26
pkg/transformers/drip_file/repo/config.go
Normal file
@ -0,0 +1,26 @@
|
||||
// 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 repo
|
||||
|
||||
import "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
var DripFileRepoConfig = shared.SingleTransformerConfig{
|
||||
TransformerName: shared.DripFileRepoLabel,
|
||||
ContractAddresses: []string{shared.DripContractAddress},
|
||||
ContractAbi: shared.DripABI,
|
||||
Topic: shared.DripFileRepoSignature,
|
||||
StartingBlockNumber: 0,
|
||||
EndingBlockNumber: 10000000,
|
||||
}
|
@ -22,25 +22,23 @@ import (
|
||||
"math/big"
|
||||
)
|
||||
|
||||
type Converter interface {
|
||||
ToModels(ethLogs []types.Log) ([]DripFileRepoModel, error)
|
||||
}
|
||||
|
||||
type DripFileRepoConverter struct{}
|
||||
|
||||
func (DripFileRepoConverter) ToModels(ethLogs []types.Log) ([]DripFileRepoModel, error) {
|
||||
var models []DripFileRepoModel
|
||||
func (DripFileRepoConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
var models []interface{}
|
||||
for _, ethLog := range ethLogs {
|
||||
err := verifyLog(ethLog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
what := string(bytes.Trim(ethLog.Topics[2].Bytes(), "\x00"))
|
||||
data := big.NewInt(0).SetBytes(ethLog.Topics[3].Bytes()).String()
|
||||
raw, err := json.Marshal(ethLog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
model := DripFileRepoModel{
|
||||
What: what,
|
||||
Data: data,
|
||||
|
@ -44,6 +44,6 @@ var _ = Describe("Drip file repo converter", func() {
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(models)).To(Equal(1))
|
||||
Expect(models[0]).To(Equal(test_data.DripFileRepoModel))
|
||||
Expect(models[0].(repo.DripFileRepoModel)).To(Equal(test_data.DripFileRepoModel))
|
||||
})
|
||||
})
|
||||
|
@ -15,56 +15,58 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(headerID int64, models []DripFileRepoModel) error
|
||||
MarkHeaderChecked(headerID int64) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
}
|
||||
|
||||
type DripFileRepoRepository struct {
|
||||
db *postgres.DB
|
||||
}
|
||||
|
||||
func NewDripFileRepoRepository(db *postgres.DB) DripFileRepoRepository {
|
||||
return DripFileRepoRepository{db: db}
|
||||
}
|
||||
|
||||
func (repository DripFileRepoRepository) Create(headerID int64, models []DripFileRepoModel) error {
|
||||
func (repository DripFileRepoRepository) Create(headerID int64, models []interface{}) error {
|
||||
tx, err := repository.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, model := range models {
|
||||
repo, ok := model.(DripFileRepoModel)
|
||||
if !ok {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("model of type %T, not %T", model, DripFileRepoModel{})
|
||||
}
|
||||
|
||||
_, err = tx.Exec(
|
||||
`INSERT into maker.drip_file_repo (header_id, what, data, log_idx, tx_idx, raw_log)
|
||||
VALUES($1, $2, $3::NUMERIC, $4, $5, $6)`,
|
||||
headerID, model.What, model.Data, model.LogIndex, model.TransactionIndex, model.Raw,
|
||||
VALUES($1, $2, $3::NUMERIC, $4, $5, $6)`,
|
||||
headerID, repo.What, repo.Data, repo.LogIndex, repo.TransactionIndex, repo.Raw,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, drip_file_repo_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_repo_checked = $2`, headerID, true)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_repo_checked = $2`, headerID, true)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (repository DripFileRepoRepository) MarkHeaderChecked(headerID int64) error {
|
||||
_, err := repository.db.Exec(`INSERT INTO public.checked_headers (header_id, drip_file_repo_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_repo_checked = $2`, headerID, true)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_repo_checked = $2`, headerID, true)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -73,14 +75,18 @@ func (repository DripFileRepoRepository) MissingHeaders(startingBlockNumber, end
|
||||
err := repository.db.Select(
|
||||
&result,
|
||||
`SELECT headers.id, headers.block_number FROM headers
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
WHERE (header_id ISNULL OR drip_file_repo_checked IS FALSE)
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
WHERE (header_id ISNULL OR drip_file_repo_checked IS FALSE)
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
startingBlockNumber,
|
||||
endingBlockNumber,
|
||||
repository.db.Node.ID,
|
||||
)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (repository *DripFileRepoRepository) SetDB(db *postgres.DB) {
|
||||
repository.db = db
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package repo_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"math/rand"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@ -33,7 +34,7 @@ import (
|
||||
var _ = Describe("Drip file repo repository", func() {
|
||||
var (
|
||||
db *postgres.DB
|
||||
dripFileRepoRepository repo.Repository
|
||||
dripFileRepoRepository repo.DripFileRepoRepository
|
||||
err error
|
||||
headerRepository datastore.HeaderRepository
|
||||
)
|
||||
@ -42,7 +43,8 @@ var _ = Describe("Drip file repo repository", func() {
|
||||
db = test_config.NewTestDB(core.Node{})
|
||||
test_config.CleanTestDB(db)
|
||||
headerRepository = repositories.NewHeaderRepository(db)
|
||||
dripFileRepoRepository = repo.NewDripFileRepoRepository(db)
|
||||
dripFileRepoRepository = repo.DripFileRepoRepository{}
|
||||
dripFileRepoRepository.SetDB(db)
|
||||
})
|
||||
|
||||
Describe("Create", func() {
|
||||
@ -52,7 +54,7 @@ var _ = Describe("Drip file repo repository", func() {
|
||||
headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = dripFileRepoRepository.Create(headerID, []repo.DripFileRepoModel{test_data.DripFileRepoModel})
|
||||
err = dripFileRepoRepository.Create(headerID, []interface{}{test_data.DripFileRepoModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -75,7 +77,7 @@ var _ = Describe("Drip file repo repository", func() {
|
||||
})
|
||||
|
||||
It("does not duplicate drip file events", func() {
|
||||
err = dripFileRepoRepository.Create(headerID, []repo.DripFileRepoModel{test_data.DripFileRepoModel})
|
||||
err = dripFileRepoRepository.Create(headerID, []interface{}{test_data.DripFileRepoModel})
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
|
||||
@ -90,6 +92,12 @@ var _ = Describe("Drip file repo repository", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(sql.ErrNoRows))
|
||||
})
|
||||
|
||||
It("Returns an error if model is of wrong type", func() {
|
||||
err = dripFileRepoRepository.Create(headerID, []interface{}{test_data.WrongModel{}})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("model of type"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MarkHeaderChecked", func() {
|
||||
@ -130,7 +138,7 @@ var _ = Describe("Drip file repo repository", func() {
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
startingBlock = GinkgoRandomSeed()
|
||||
startingBlock = rand.Int63()
|
||||
dripFileBlock = startingBlock + 1
|
||||
endingBlock = startingBlock + 2
|
||||
|
||||
@ -176,7 +184,8 @@ var _ = Describe("Drip file repo repository", func() {
|
||||
_, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
dripFileRepoRepositoryTwo := repo.NewDripFileRepoRepository(dbTwo)
|
||||
dripFileRepoRepositoryTwo := repo.DripFileRepoRepository{}
|
||||
dripFileRepoRepositoryTwo.SetDB(dbTwo)
|
||||
err := dripFileRepoRepository.MarkHeaderChecked(headerIDs[0])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -1,79 +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 repo
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type DripFileRepoTransformer struct {
|
||||
Config shared.TransformerConfig
|
||||
Converter Converter
|
||||
Fetcher shared.LogFetcher
|
||||
Repository Repository
|
||||
}
|
||||
|
||||
type DripFileRepoTransformerInitializer struct {
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
func (initializer DripFileRepoTransformerInitializer) NewDripFileRepoTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
converter := DripFileRepoConverter{}
|
||||
fetcher := shared.NewFetcher(blockChain)
|
||||
repository := NewDripFileRepoRepository(db)
|
||||
return DripFileRepoTransformer{
|
||||
Config: initializer.Config,
|
||||
Converter: converter,
|
||||
Fetcher: fetcher,
|
||||
Repository: repository,
|
||||
}
|
||||
}
|
||||
|
||||
func (transformer DripFileRepoTransformer) Execute() error {
|
||||
missingHeaders, err := transformer.Repository.MissingHeaders(transformer.Config.StartingBlockNumber, transformer.Config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Fetching drip file repo event logs for %d headers \n", len(missingHeaders))
|
||||
for _, header := range missingHeaders {
|
||||
topics := [][]common.Hash{{common.HexToHash(shared.DripFileRepoSignature)}}
|
||||
matchingLogs, err := transformer.Fetcher.FetchLogs(drip_file.DripFileConfig.ContractAddresses, topics, header.BlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(matchingLogs) < 1 {
|
||||
err = transformer.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
model, err := transformer.Converter.ToModels(matchingLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = transformer.Repository.Create(header.Id, model)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -19,10 +19,11 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"math/rand"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/repo"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
@ -31,31 +32,45 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Drip file repo transformer", func() {
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
repository := &repo_mocks.MockDripFileRepoRepository{}
|
||||
transformer := repo.DripFileRepoTransformer{
|
||||
Config: drip_file.DripFileConfig,
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &repo_mocks.MockDripFileRepoConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
var (
|
||||
config = repo.DripFileRepoConfig
|
||||
fetcher mocks.MockLogFetcher
|
||||
converter repo_mocks.MockDripFileRepoConverter
|
||||
repository repo_mocks.MockDripFileRepoRepository
|
||||
transformer shared.Transformer
|
||||
headerOne core.Header
|
||||
headerTwo core.Header
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fetcher = mocks.MockLogFetcher{}
|
||||
converter = repo_mocks.MockDripFileRepoConverter{}
|
||||
repository = repo_mocks.MockDripFileRepoRepository{}
|
||||
transformer = factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}.NewTransformer(nil, nil)
|
||||
headerOne = core.Header{BlockNumber: rand.Int63(), Id: rand.Int63()}
|
||||
headerTwo = core.Header{BlockNumber: rand.Int63(), Id: rand.Int63()}
|
||||
})
|
||||
|
||||
It("sets the blockchain and database", func() {
|
||||
Expect(fetcher.SetBcCalled).To(BeTrue())
|
||||
Expect(repository.SetDbCalled).To(BeTrue())
|
||||
})
|
||||
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(drip_file.DripFileConfig.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(drip_file.DripFileConfig.EndingBlockNumber))
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(config.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(config.EndingBlockNumber))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for missing headers", func() {
|
||||
repository := &repo_mocks.MockDripFileRepoRepository{}
|
||||
repository.SetMissingHeadersErr(fakes.FakeError)
|
||||
transformer := repo.DripFileRepoTransformer{
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &repo_mocks.MockDripFileRepoConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
repository.SetMissingHeadersError(fakes.FakeError)
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
@ -63,33 +78,18 @@ var _ = Describe("Drip file repo transformer", func() {
|
||||
})
|
||||
|
||||
It("fetches logs for missing headers", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
repository := &repo_mocks.MockDripFileRepoRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}, {BlockNumber: 2}})
|
||||
transformer := repo.DripFileRepoTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &repo_mocks.MockDripFileRepoConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{1, 2}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{drip_file.DripFileConfig.ContractAddresses, drip_file.DripFileConfig.ContractAddresses}))
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{headerOne.BlockNumber, headerTwo.BlockNumber}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{config.ContractAddresses, config.ContractAddresses}))
|
||||
Expect(fetcher.FetchedTopics).To(Equal([][]common.Hash{{common.HexToHash(shared.DripFileRepoSignature)}}))
|
||||
})
|
||||
|
||||
It("returns error if fetcher returns error", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetcherError(fakes.FakeError)
|
||||
repository := &repo_mocks.MockDripFileRepoRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := repo.DripFileRepoTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &repo_mocks.MockDripFileRepoConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -98,34 +98,16 @@ var _ = Describe("Drip file repo transformer", func() {
|
||||
})
|
||||
|
||||
It("marks header checked if no logs returned", func() {
|
||||
mockConverter := &repo_mocks.MockDripFileRepoConverter{}
|
||||
mockRepository := &repo_mocks.MockDripFileRepoRepository{}
|
||||
headerID := int64(123)
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: headerID}})
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := repo.DripFileRepoTransformer{
|
||||
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 := &repo_mocks.MockDripFileRepoConverter{}
|
||||
mockRepository := &repo_mocks.MockDripFileRepoRepository{}
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: int64(123)}})
|
||||
mockRepository.SetMarkHeaderCheckedErr(fakes.FakeError)
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := repo.DripFileRepoTransformer{
|
||||
Converter: mockConverter,
|
||||
Fetcher: mockFetcher,
|
||||
Repository: mockRepository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetMarkHeaderCheckedError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -134,16 +116,8 @@ var _ = Describe("Drip file repo transformer", func() {
|
||||
})
|
||||
|
||||
It("converts matching logs", func() {
|
||||
converter := &repo_mocks.MockDripFileRepoConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileRepoLog})
|
||||
repository := &repo_mocks.MockDripFileRepoRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := repo.DripFileRepoTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -152,17 +126,9 @@ var _ = Describe("Drip file repo transformer", func() {
|
||||
})
|
||||
|
||||
It("returns error if converter returns error", func() {
|
||||
converter := &repo_mocks.MockDripFileRepoConverter{}
|
||||
converter.SetConverterError(fakes.FakeError)
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileRepoLog})
|
||||
repository := &repo_mocks.MockDripFileRepoRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := repo.DripFileRepoTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -171,37 +137,20 @@ var _ = Describe("Drip file repo transformer", func() {
|
||||
})
|
||||
|
||||
It("persists drip file model", func() {
|
||||
converter := &repo_mocks.MockDripFileRepoConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileRepoLog})
|
||||
repository := &repo_mocks.MockDripFileRepoRepository{}
|
||||
fakeHeader := core.Header{BlockNumber: 1, Id: 2}
|
||||
repository.SetMissingHeaders([]core.Header{fakeHeader})
|
||||
transformer := repo.DripFileRepoTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedHeaderID).To(Equal(fakeHeader.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]repo.DripFileRepoModel{test_data.DripFileRepoModel}))
|
||||
Expect(repository.PassedHeaderID).To(Equal(headerOne.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]interface{}{test_data.DripFileRepoModel}))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for create", func() {
|
||||
converter := &repo_mocks.MockDripFileRepoConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileRepoLog})
|
||||
repository := &repo_mocks.MockDripFileRepoRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: 2}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetCreateError(fakes.FakeError)
|
||||
transformer := repo.DripFileRepoTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
|
26
pkg/transformers/drip_file/vow/config.go
Normal file
26
pkg/transformers/drip_file/vow/config.go
Normal file
@ -0,0 +1,26 @@
|
||||
// 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 vow
|
||||
|
||||
import "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
var DripFileVowConfig = shared.SingleTransformerConfig{
|
||||
TransformerName: shared.DripFileVowLabel,
|
||||
ContractAddresses: []string{shared.DripContractAddress},
|
||||
ContractAbi: shared.DripABI,
|
||||
Topic: shared.DripFileVowSignature,
|
||||
StartingBlockNumber: 0,
|
||||
EndingBlockNumber: 10000000,
|
||||
}
|
@ -22,25 +22,23 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
type Converter interface {
|
||||
ToModels(ethLogs []types.Log) ([]DripFileVowModel, error)
|
||||
}
|
||||
|
||||
type DripFileVowConverter struct{}
|
||||
|
||||
func (DripFileVowConverter) ToModels(ethLogs []types.Log) ([]DripFileVowModel, error) {
|
||||
var models []DripFileVowModel
|
||||
func (DripFileVowConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
var models []interface{}
|
||||
for _, ethLog := range ethLogs {
|
||||
err := verifyLog(ethLog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
what := string(bytes.Trim(ethLog.Topics[2].Bytes(), "\x00"))
|
||||
data := common.BytesToAddress(ethLog.Topics[3].Bytes()).String()
|
||||
raw, err := json.Marshal(ethLog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
model := DripFileVowModel{
|
||||
What: what,
|
||||
Data: data,
|
||||
|
@ -44,6 +44,6 @@ var _ = Describe("Drip file repo converter", func() {
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(models)).To(Equal(1))
|
||||
Expect(models[0]).To(Equal(test_data.DripFileVowModel))
|
||||
Expect(models[0].(vow.DripFileVowModel)).To(Equal(test_data.DripFileVowModel))
|
||||
})
|
||||
})
|
||||
|
@ -15,56 +15,57 @@
|
||||
package vow
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(headerID int64, models []DripFileVowModel) error
|
||||
MarkHeaderChecked(headerID int64) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
}
|
||||
|
||||
type DripFileVowRepository struct {
|
||||
db *postgres.DB
|
||||
}
|
||||
|
||||
func NewDripFileVowRepository(db *postgres.DB) DripFileVowRepository {
|
||||
return DripFileVowRepository{db: db}
|
||||
}
|
||||
|
||||
func (repository DripFileVowRepository) Create(headerID int64, models []DripFileVowModel) error {
|
||||
func (repository DripFileVowRepository) Create(headerID int64, models []interface{}) error {
|
||||
tx, err := repository.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, model := range models {
|
||||
vow, ok := model.(DripFileVowModel)
|
||||
if !ok {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("model of type %T, not %T", model, DripFileVowModel{})
|
||||
}
|
||||
|
||||
_, err = tx.Exec(
|
||||
`INSERT into maker.drip_file_vow (header_id, what, data, log_idx, tx_idx, raw_log)
|
||||
VALUES($1, $2, $3, $4, $5, $6)`,
|
||||
headerID, model.What, model.Data, model.LogIndex, model.TransactionIndex, model.Raw,
|
||||
VALUES($1, $2, $3, $4, $5, $6)`,
|
||||
headerID, vow.What, vow.Data, vow.LogIndex, vow.TransactionIndex, vow.Raw,
|
||||
)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, drip_file_vow_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_vow_checked = $2`, headerID, true)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_vow_checked = $2`, headerID, true)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (repository DripFileVowRepository) MarkHeaderChecked(headerID int64) error {
|
||||
_, err := repository.db.Exec(`INSERT INTO public.checked_headers (header_id, drip_file_vow_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_vow_checked = $2`, headerID, true)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET drip_file_vow_checked = $2`, headerID, true)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -73,14 +74,18 @@ func (repository DripFileVowRepository) MissingHeaders(startingBlockNumber, endi
|
||||
err := repository.db.Select(
|
||||
&result,
|
||||
`SELECT headers.id, headers.block_number FROM headers
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
WHERE (header_id ISNULL OR drip_file_vow_checked IS FALSE)
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
WHERE (header_id ISNULL OR drip_file_vow_checked IS FALSE)
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
startingBlockNumber,
|
||||
endingBlockNumber,
|
||||
repository.db.Node.ID,
|
||||
)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (repository *DripFileVowRepository) SetDB(db *postgres.DB) {
|
||||
repository.db = db
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package vow_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"math/rand"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@ -33,7 +34,7 @@ import (
|
||||
var _ = Describe("Drip file vow repository", func() {
|
||||
var (
|
||||
db *postgres.DB
|
||||
dripFileVowRepository vow.Repository
|
||||
dripFileVowRepository vow.DripFileVowRepository
|
||||
err error
|
||||
headerRepository datastore.HeaderRepository
|
||||
)
|
||||
@ -42,7 +43,8 @@ var _ = Describe("Drip file vow repository", func() {
|
||||
db = test_config.NewTestDB(core.Node{})
|
||||
test_config.CleanTestDB(db)
|
||||
headerRepository = repositories.NewHeaderRepository(db)
|
||||
dripFileVowRepository = vow.NewDripFileVowRepository(db)
|
||||
dripFileVowRepository = vow.DripFileVowRepository{}
|
||||
dripFileVowRepository.SetDB(db)
|
||||
})
|
||||
|
||||
Describe("Create", func() {
|
||||
@ -52,7 +54,7 @@ var _ = Describe("Drip file vow repository", func() {
|
||||
headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = dripFileVowRepository.Create(headerID, []vow.DripFileVowModel{test_data.DripFileVowModel})
|
||||
err = dripFileVowRepository.Create(headerID, []interface{}{test_data.DripFileVowModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -75,7 +77,7 @@ var _ = Describe("Drip file vow repository", func() {
|
||||
})
|
||||
|
||||
It("does not duplicate drip file events", func() {
|
||||
err = dripFileVowRepository.Create(headerID, []vow.DripFileVowModel{test_data.DripFileVowModel})
|
||||
err = dripFileVowRepository.Create(headerID, []interface{}{test_data.DripFileVowModel})
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
|
||||
@ -90,6 +92,12 @@ var _ = Describe("Drip file vow repository", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(sql.ErrNoRows))
|
||||
})
|
||||
|
||||
It("Returns an error if model is of wrong type", func() {
|
||||
err = dripFileVowRepository.Create(headerID, []interface{}{test_data.WrongModel{}})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("model of type"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MarkHeaderChecked", func() {
|
||||
@ -130,7 +138,7 @@ var _ = Describe("Drip file vow repository", func() {
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
startingBlock = GinkgoRandomSeed()
|
||||
startingBlock = rand.Int63()
|
||||
dripFileBlock = startingBlock + 1
|
||||
endingBlock = startingBlock + 2
|
||||
|
||||
@ -176,7 +184,8 @@ var _ = Describe("Drip file vow repository", func() {
|
||||
_, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
dripFileVowRepositoryTwo := vow.NewDripFileVowRepository(dbTwo)
|
||||
dripFileVowRepositoryTwo := vow.DripFileVowRepository{}
|
||||
dripFileVowRepositoryTwo.SetDB(dbTwo)
|
||||
err := dripFileVowRepository.MarkHeaderChecked(headerIDs[0])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -1,79 +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 vow
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type DripFileVowTransformerInitializer struct {
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
func (initializer DripFileVowTransformerInitializer) NewDripFileVowTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
converter := DripFileVowConverter{}
|
||||
fetcher := shared.NewFetcher(blockChain)
|
||||
repository := NewDripFileVowRepository(db)
|
||||
return DripFileVowTransformer{
|
||||
Config: initializer.Config,
|
||||
Converter: converter,
|
||||
Fetcher: fetcher,
|
||||
Repository: repository,
|
||||
}
|
||||
}
|
||||
|
||||
type DripFileVowTransformer struct {
|
||||
Config shared.TransformerConfig
|
||||
Converter Converter
|
||||
Fetcher shared.LogFetcher
|
||||
Repository Repository
|
||||
}
|
||||
|
||||
func (transformer DripFileVowTransformer) Execute() error {
|
||||
missingHeaders, err := transformer.Repository.MissingHeaders(transformer.Config.StartingBlockNumber, transformer.Config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Fetching drip file vow event logs for %d headers \n", len(missingHeaders))
|
||||
for _, header := range missingHeaders {
|
||||
topics := [][]common.Hash{{common.HexToHash(shared.DripFileVowSignature)}}
|
||||
matchingLogs, err := transformer.Fetcher.FetchLogs(drip_file.DripFileConfig.ContractAddresses, topics, header.BlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(matchingLogs) < 1 {
|
||||
err = transformer.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
model, err := transformer.Converter.ToModels(matchingLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = transformer.Repository.Create(header.Id, model)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -19,10 +19,11 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"math/rand"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/vow"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
@ -31,31 +32,45 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Drip file vow transformer", func() {
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
repository := &vow_mocks.MockDripFileVowRepository{}
|
||||
transformer := vow.DripFileVowTransformer{
|
||||
Config: drip_file.DripFileConfig,
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &vow_mocks.MockDripFileVowConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
var (
|
||||
config = vow.DripFileVowConfig
|
||||
fetcher mocks.MockLogFetcher
|
||||
converter vow_mocks.MockDripFileVowConverter
|
||||
repository vow_mocks.MockDripFileVowRepository
|
||||
transformer shared.Transformer
|
||||
headerOne core.Header
|
||||
headerTwo core.Header
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fetcher = mocks.MockLogFetcher{}
|
||||
converter = vow_mocks.MockDripFileVowConverter{}
|
||||
repository = vow_mocks.MockDripFileVowRepository{}
|
||||
transformer = factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}.NewTransformer(nil, nil)
|
||||
headerOne = core.Header{BlockNumber: rand.Int63(), Id: rand.Int63()}
|
||||
headerTwo = core.Header{BlockNumber: rand.Int63(), Id: rand.Int63()}
|
||||
})
|
||||
|
||||
It("sets the blockchain and database", func() {
|
||||
Expect(fetcher.SetBcCalled).To(BeTrue())
|
||||
Expect(repository.SetDbCalled).To(BeTrue())
|
||||
})
|
||||
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(drip_file.DripFileConfig.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(drip_file.DripFileConfig.EndingBlockNumber))
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(config.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(config.EndingBlockNumber))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for missing headers", func() {
|
||||
repository := &vow_mocks.MockDripFileVowRepository{}
|
||||
repository.SetMissingHeadersErr(fakes.FakeError)
|
||||
transformer := vow.DripFileVowTransformer{
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &vow_mocks.MockDripFileVowConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
repository.SetMissingHeadersError(fakes.FakeError)
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
@ -63,33 +78,18 @@ var _ = Describe("Drip file vow transformer", func() {
|
||||
})
|
||||
|
||||
It("fetches logs for missing headers", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
repository := &vow_mocks.MockDripFileVowRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}, {BlockNumber: 2}})
|
||||
transformer := vow.DripFileVowTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &vow_mocks.MockDripFileVowConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{1, 2}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{drip_file.DripFileConfig.ContractAddresses, drip_file.DripFileConfig.ContractAddresses}))
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{headerOne.BlockNumber, headerTwo.BlockNumber}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{config.ContractAddresses, config.ContractAddresses}))
|
||||
Expect(fetcher.FetchedTopics).To(Equal([][]common.Hash{{common.HexToHash(shared.DripFileVowSignature)}}))
|
||||
})
|
||||
|
||||
It("returns error if fetcher returns error", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetcherError(fakes.FakeError)
|
||||
repository := &vow_mocks.MockDripFileVowRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := vow.DripFileVowTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &vow_mocks.MockDripFileVowConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -98,34 +98,16 @@ var _ = Describe("Drip file vow transformer", func() {
|
||||
})
|
||||
|
||||
It("marks header checked if no logs returned", func() {
|
||||
mockConverter := &vow_mocks.MockDripFileVowConverter{}
|
||||
mockRepository := &vow_mocks.MockDripFileVowRepository{}
|
||||
headerID := int64(123)
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: headerID}})
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := vow.DripFileVowTransformer{
|
||||
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 := &vow_mocks.MockDripFileVowConverter{}
|
||||
mockRepository := &vow_mocks.MockDripFileVowRepository{}
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: int64(123)}})
|
||||
mockRepository.SetMarkHeaderCheckedErr(fakes.FakeError)
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := vow.DripFileVowTransformer{
|
||||
Converter: mockConverter,
|
||||
Fetcher: mockFetcher,
|
||||
Repository: mockRepository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetMarkHeaderCheckedError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -134,16 +116,8 @@ var _ = Describe("Drip file vow transformer", func() {
|
||||
})
|
||||
|
||||
It("converts matching logs", func() {
|
||||
converter := &vow_mocks.MockDripFileVowConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileVowLog})
|
||||
repository := &vow_mocks.MockDripFileVowRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := vow.DripFileVowTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -152,17 +126,9 @@ var _ = Describe("Drip file vow transformer", func() {
|
||||
})
|
||||
|
||||
It("returns error if converter returns error", func() {
|
||||
converter := &vow_mocks.MockDripFileVowConverter{}
|
||||
converter.SetConverterError(fakes.FakeError)
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileVowLog})
|
||||
repository := &vow_mocks.MockDripFileVowRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := vow.DripFileVowTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -171,37 +137,20 @@ var _ = Describe("Drip file vow transformer", func() {
|
||||
})
|
||||
|
||||
It("persists drip file model", func() {
|
||||
converter := &vow_mocks.MockDripFileVowConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileVowLog})
|
||||
repository := &vow_mocks.MockDripFileVowRepository{}
|
||||
fakeHeader := core.Header{BlockNumber: 1, Id: 2}
|
||||
repository.SetMissingHeaders([]core.Header{fakeHeader})
|
||||
transformer := vow.DripFileVowTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedHeaderID).To(Equal(fakeHeader.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]vow.DripFileVowModel{test_data.DripFileVowModel}))
|
||||
Expect(repository.PassedHeaderID).To(Equal(headerOne.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]interface{}{test_data.DripFileVowModel}))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for create", func() {
|
||||
converter := &vow_mocks.MockDripFileVowConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthDripFileVowLog})
|
||||
repository := &vow_mocks.MockDripFileVowRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: 2}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetCreateError(fakes.FakeError)
|
||||
transformer := vow.DripFileVowTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
|
97
pkg/transformers/factories/transformer.go
Normal file
97
pkg/transformers/factories/transformer.go
Normal file
@ -0,0 +1,97 @@
|
||||
// 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 factories
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type Transformer struct {
|
||||
Config shared.SingleTransformerConfig
|
||||
Converter Converter
|
||||
Repository Repository
|
||||
Fetcher shared.SettableLogFetcher
|
||||
}
|
||||
|
||||
type Converter interface {
|
||||
ToModels(ethLog []types.Log) ([]interface{}, error)
|
||||
}
|
||||
|
||||
type Repository interface {
|
||||
Create(headerID int64, models []interface{}) error
|
||||
MarkHeaderChecked(headerID int64) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
SetDB(db *postgres.DB)
|
||||
}
|
||||
|
||||
func (transformer Transformer) NewTransformer(db *postgres.DB, bc core.BlockChain) shared.Transformer {
|
||||
transformer.Repository.SetDB(db)
|
||||
transformer.Fetcher.SetBC(bc)
|
||||
return transformer
|
||||
}
|
||||
|
||||
func (transformer Transformer) Execute() error {
|
||||
transformerName := transformer.Config.TransformerName
|
||||
missingHeaders, err := transformer.Repository.MissingHeaders(transformer.Config.StartingBlockNumber, transformer.Config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
log.Printf("Error fetching mising headers in %v transformer: %v \n", transformerName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Grab event signature from transformer config
|
||||
// (Double-array structure required for go-ethereum FilterQuery)
|
||||
var topic = [][]common.Hash{{common.HexToHash(transformer.Config.Topic)}}
|
||||
|
||||
log.Printf("Fetching %v event logs for %d headers \n", transformerName, len(missingHeaders))
|
||||
for _, header := range missingHeaders {
|
||||
// Fetch the missing logs for a given header
|
||||
matchingLogs, err := transformer.Fetcher.FetchLogs(transformer.Config.ContractAddresses, topic, header.BlockNumber)
|
||||
if err != nil {
|
||||
log.Printf("Error fetching matching logs in %v transformer: %v", transformerName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// No matching logs, mark the header as checked for this type of logs
|
||||
if len(matchingLogs) < 1 {
|
||||
err := transformer.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
log.Printf("Error marking header as checked in %v: %v", transformerName, err)
|
||||
return err
|
||||
}
|
||||
// Continue with the next header; nothing to persist
|
||||
continue
|
||||
}
|
||||
|
||||
models, err := transformer.Converter.ToModels(matchingLogs)
|
||||
if err != nil {
|
||||
log.Printf("Error converting logs in %v: %v", transformerName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = transformer.Repository.Create(header.Id, models)
|
||||
if err != nil {
|
||||
log.Printf("Error persisting %v record: %v", transformerName, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -17,8 +17,9 @@ package integration_tests
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/vow"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
@ -26,7 +27,7 @@ import (
|
||||
var _ = Describe("Drip File Vow Transformer", func() {
|
||||
It("transforms DripFileVow log events", func() {
|
||||
blockNumber := int64(8762197)
|
||||
config := drip_file.DripFileConfig
|
||||
config := vow.DripFileVowConfig
|
||||
config.StartingBlockNumber = blockNumber
|
||||
config.EndingBlockNumber = blockNumber
|
||||
|
||||
@ -41,8 +42,13 @@ var _ = Describe("Drip File Vow Transformer", func() {
|
||||
err = persistHeader(rpcClient, db, blockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
initializer := vow.DripFileVowTransformerInitializer{Config: config}
|
||||
transformer := initializer.NewDripFileVowTransformer(db, blockchain)
|
||||
initializer := factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &shared.Fetcher{},
|
||||
Converter: &vow.DripFileVowConverter{},
|
||||
Repository: &vow.DripFileVowRepository{},
|
||||
}
|
||||
transformer := initializer.NewTransformer(db, blockchain)
|
||||
err = transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -17,8 +17,9 @@ package integration_tests
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
@ -26,7 +27,7 @@ import (
|
||||
var _ = Describe("PitFileDebtCeiling Transformer", func() {
|
||||
It("fetches and transforms a PitFileDebtCeiling event from Kovan chain", func() {
|
||||
blockNumber := int64(8535578)
|
||||
config := pit_file.PitFileConfig
|
||||
config := debt_ceiling.DebtCeilingFileConfig
|
||||
config.StartingBlockNumber = blockNumber
|
||||
config.EndingBlockNumber = blockNumber
|
||||
|
||||
@ -41,8 +42,13 @@ var _ = Describe("PitFileDebtCeiling Transformer", func() {
|
||||
err = persistHeader(rpcClient, db, blockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
initializer := debt_ceiling.PitFileDebtCeilingTransformerInitializer{Config: config}
|
||||
transformer := initializer.NewPitFileDebtCeilingTransformer(db, blockchain)
|
||||
initializer := factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &shared.Fetcher{},
|
||||
Converter: &debt_ceiling.PitFileDebtCeilingConverter{},
|
||||
Repository: &debt_ceiling.PitFileDebtCeilingRepository{},
|
||||
}
|
||||
transformer := initializer.NewTransformer(db, blockchain)
|
||||
err = transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -17,8 +17,9 @@ package integration_tests
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/ilk"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
@ -26,7 +27,7 @@ import (
|
||||
var _ = Describe("PitFileIlk Transformer", func() {
|
||||
It("fetches and transforms a PitFileIlk event from Kovan chain", func() {
|
||||
blockNumber := int64(9103223)
|
||||
config := pit_file.PitFileConfig
|
||||
config := ilk.IlkFileConfig
|
||||
config.StartingBlockNumber = blockNumber
|
||||
config.EndingBlockNumber = blockNumber
|
||||
|
||||
@ -41,8 +42,13 @@ var _ = Describe("PitFileIlk Transformer", func() {
|
||||
err = persistHeader(rpcClient, db, blockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
initializer := ilk.PitFileIlkTransformerInitializer{Config: config}
|
||||
transformer := initializer.NewPitFileIlkTransformer(db, blockchain)
|
||||
initializer := factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &shared.Fetcher{},
|
||||
Converter: &ilk.PitFileIlkConverter{},
|
||||
Repository: &ilk.PitFileIlkRepository{},
|
||||
}
|
||||
transformer := initializer.NewTransformer(db, blockchain)
|
||||
err = transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -17,8 +17,9 @@ package integration_tests
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/stability_fee"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
@ -26,7 +27,7 @@ import (
|
||||
var _ = Describe("PitFileStabilityFee Transformer", func() {
|
||||
It("fetches and transforms a PitFileStabilityFee event from Kovan chain", func() {
|
||||
blockNumber := int64(8535544)
|
||||
config := pit_file.PitFileConfig
|
||||
config := stability_fee.StabilityFeeFileConfig
|
||||
config.StartingBlockNumber = blockNumber
|
||||
config.EndingBlockNumber = blockNumber
|
||||
|
||||
@ -41,8 +42,13 @@ var _ = Describe("PitFileStabilityFee Transformer", func() {
|
||||
err = persistHeader(rpcClient, db, blockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
initializer := stability_fee.PitFileStabilityFeeTransformerInitializer{Config: config}
|
||||
transformer := initializer.NewPitFileStabilityFeeTransformer(db, blockchain)
|
||||
initializer := factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &shared.Fetcher{},
|
||||
Converter: &stability_fee.PitFileStabilityFeeConverter{},
|
||||
Repository: &stability_fee.PitFileStabilityFeeRepository{},
|
||||
}
|
||||
transformer := initializer.NewTransformer(db, blockchain)
|
||||
err = transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -17,6 +17,8 @@ package integration_tests
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/tend"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
@ -40,8 +42,13 @@ var _ = Describe("Tend Transformer", func() {
|
||||
err = persistHeader(rpcClient, db, blockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
initializer := tend.TendTransformerInitializer{Config: config}
|
||||
transformer := initializer.NewTendTransformer(db, blockchain)
|
||||
initializer := factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &shared.Fetcher{},
|
||||
Converter: &tend.TendConverter{},
|
||||
Repository: &tend.TendRepository{},
|
||||
}
|
||||
transformer := initializer.NewTransformer(db, blockchain)
|
||||
err = transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
@ -74,8 +81,13 @@ var _ = Describe("Tend Transformer", func() {
|
||||
err = persistHeader(rpcClient, db, blockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
initializer := tend.TendTransformerInitializer{Config: config}
|
||||
transformer := initializer.NewTendTransformer(db, blockchain)
|
||||
initializer := factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &shared.Fetcher{},
|
||||
Converter: &tend.TendConverter{},
|
||||
Repository: &tend.TendRepository{},
|
||||
}
|
||||
transformer := initializer.NewTransformer(db, blockchain)
|
||||
err = transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -17,6 +17,8 @@ package integration_tests
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_init"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
@ -40,8 +42,13 @@ var _ = Describe("VatInit Transformer", func() {
|
||||
err = persistHeader(rpcClient, db, blockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
initializer := vat_init.VatInitTransformerInitializer{Config: config}
|
||||
transformer := initializer.NewVatInitTransformer(db, blockchain)
|
||||
initializer := factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &shared.Fetcher{},
|
||||
Converter: &vat_init.VatInitConverter{},
|
||||
Repository: &vat_init.VatInitRepository{},
|
||||
}
|
||||
transformer := initializer.NewTransformer(db, blockchain)
|
||||
err = transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -18,6 +18,8 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_move"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
@ -41,8 +43,13 @@ var _ = Describe("VatMove Transformer", func() {
|
||||
err = persistHeader(rpcClient, db, blockNumber)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
initializer := vat_move.VatMoveTransformerInitializer{Config: config}
|
||||
transformer := initializer.NewVatMoveTransformer(db, blockchain)
|
||||
initializer := factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &shared.Fetcher{},
|
||||
Converter: &vat_move.VatMoveConverter{},
|
||||
Repository: &vat_move.VatMoveRepository{},
|
||||
}
|
||||
transformer := initializer.NewTransformer(db, blockchain)
|
||||
err = transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -12,16 +12,17 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package pit_file
|
||||
package debt_ceiling
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
var PitFileConfig = shared.TransformerConfig{
|
||||
var DebtCeilingFileConfig = shared.SingleTransformerConfig{
|
||||
TransformerName: shared.PitFileDebtCeilingLabel,
|
||||
ContractAddresses: []string{shared.PitContractAddress},
|
||||
ContractAbi: shared.PitABI,
|
||||
Topics: []string{shared.PitFileIlkSignature, shared.PitFileDebtCeilingSignature, shared.PitFileStabilityFeeSignature},
|
||||
Topic: shared.PitFileDebtCeilingSignature,
|
||||
StartingBlockNumber: 0,
|
||||
EndingBlockNumber: 10000000,
|
||||
}
|
@ -24,14 +24,10 @@ import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type Converter interface {
|
||||
ToModels(ethLogs []types.Log) ([]PitFileDebtCeilingModel, error)
|
||||
}
|
||||
|
||||
type PitFileDebtCeilingConverter struct{}
|
||||
|
||||
func (PitFileDebtCeilingConverter) ToModels(ethLogs []types.Log) ([]PitFileDebtCeilingModel, error) {
|
||||
var models []PitFileDebtCeilingModel
|
||||
func (PitFileDebtCeilingConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
var models []interface{}
|
||||
for _, ethLog := range ethLogs {
|
||||
err := verifyLog(ethLog)
|
||||
if err != nil {
|
||||
|
@ -17,10 +17,10 @@ package debt_ceiling_test
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
)
|
||||
|
||||
@ -54,6 +54,6 @@ var _ = Describe("Pit file debt ceiling converter", func() {
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(models)).To(Equal(1))
|
||||
Expect(models[0]).To(Equal(test_data.PitFileDebtCeilingModel))
|
||||
Expect(models[0].(debt_ceiling.PitFileDebtCeilingModel)).To(Equal(test_data.PitFileDebtCeilingModel))
|
||||
})
|
||||
})
|
||||
|
@ -15,58 +15,58 @@
|
||||
package debt_ceiling
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(headerID int64, models []PitFileDebtCeilingModel) error
|
||||
MarkHeaderChecked(headerID int64) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
}
|
||||
|
||||
type PitFileDebtCeilingRepository struct {
|
||||
db *postgres.DB
|
||||
}
|
||||
|
||||
func NewPitFileDebtCeilingRepository(db *postgres.DB) PitFileDebtCeilingRepository {
|
||||
return PitFileDebtCeilingRepository{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (repository PitFileDebtCeilingRepository) Create(headerID int64, models []PitFileDebtCeilingModel) error {
|
||||
func (repository PitFileDebtCeilingRepository) Create(headerID int64, models []interface{}) error {
|
||||
tx, err := repository.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, model := range models {
|
||||
pitFileDC, ok := model.(PitFileDebtCeilingModel)
|
||||
if !ok {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("model of type %T, not %T", model, PitFileDebtCeilingModel{})
|
||||
}
|
||||
|
||||
_, err = tx.Exec(
|
||||
`INSERT into maker.pit_file_debt_ceiling (header_id, what, data, tx_idx, raw_log)
|
||||
VALUES($1, $2, $3::NUMERIC, $4, $5)`,
|
||||
headerID, model.What, model.Data, model.TransactionIndex, model.Raw,
|
||||
headerID, pitFileDC.What, pitFileDC.Data, pitFileDC.TransactionIndex, pitFileDC.Raw,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, pit_file_debt_ceiling_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET pit_file_debt_ceiling_checked = $2`, headerID, true)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET pit_file_debt_ceiling_checked = $2`, headerID, true)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (repository PitFileDebtCeilingRepository) MarkHeaderChecked(headerID int64) error {
|
||||
_, err := repository.db.Exec(`INSERT INTO public.checked_headers (header_id, pit_file_debt_ceiling_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET pit_file_debt_ceiling_checked = $2`, headerID, true)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET pit_file_debt_ceiling_checked = $2`, headerID, true)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -75,14 +75,18 @@ func (repository PitFileDebtCeilingRepository) MissingHeaders(startingBlockNumbe
|
||||
err := repository.db.Select(
|
||||
&result,
|
||||
`SELECT headers.id, headers.block_number FROM headers
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
WHERE (header_id ISNULL OR pit_file_debt_ceiling_checked IS FALSE)
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
startingBlockNumber,
|
||||
endingBlockNumber,
|
||||
repository.db.Node.ID,
|
||||
)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (repository *PitFileDebtCeilingRepository) SetDB(db *postgres.DB) {
|
||||
repository.db = db
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package debt_ceiling_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"math/rand"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@ -32,17 +33,18 @@ import (
|
||||
|
||||
var _ = Describe("Pit file debt ceiling repository", func() {
|
||||
var (
|
||||
db *postgres.DB
|
||||
pitFileRepository debt_ceiling.Repository
|
||||
err error
|
||||
headerRepository datastore.HeaderRepository
|
||||
db *postgres.DB
|
||||
pitFileDebtCeilingRepository debt_ceiling.PitFileDebtCeilingRepository
|
||||
err error
|
||||
headerRepository datastore.HeaderRepository
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
db = test_config.NewTestDB(core.Node{})
|
||||
test_config.CleanTestDB(db)
|
||||
headerRepository = repositories.NewHeaderRepository(db)
|
||||
pitFileRepository = debt_ceiling.NewPitFileDebtCeilingRepository(db)
|
||||
pitFileDebtCeilingRepository = debt_ceiling.PitFileDebtCeilingRepository{}
|
||||
pitFileDebtCeilingRepository.SetDB(db)
|
||||
})
|
||||
|
||||
Describe("Create", func() {
|
||||
@ -52,7 +54,7 @@ var _ = Describe("Pit file debt ceiling repository", func() {
|
||||
headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = pitFileRepository.Create(headerID, []debt_ceiling.PitFileDebtCeilingModel{test_data.PitFileDebtCeilingModel})
|
||||
err = pitFileDebtCeilingRepository.Create(headerID, []interface{}{test_data.PitFileDebtCeilingModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -74,7 +76,7 @@ var _ = Describe("Pit file debt ceiling repository", func() {
|
||||
})
|
||||
|
||||
It("does not duplicate pit file events", func() {
|
||||
err = pitFileRepository.Create(headerID, []debt_ceiling.PitFileDebtCeilingModel{test_data.PitFileDebtCeilingModel})
|
||||
err = pitFileDebtCeilingRepository.Create(headerID, []interface{}{test_data.PitFileDebtCeilingModel})
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
|
||||
@ -89,6 +91,12 @@ var _ = Describe("Pit file debt ceiling repository", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(sql.ErrNoRows))
|
||||
})
|
||||
|
||||
It("Returns an error if model is of wrong type", func() {
|
||||
err = pitFileDebtCeilingRepository.Create(headerID, []interface{}{test_data.WrongModel{}})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("model of type"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MarkHeaderChecked", func() {
|
||||
@ -100,7 +108,7 @@ var _ = Describe("Pit file debt ceiling repository", func() {
|
||||
})
|
||||
|
||||
It("creates a row for a new headerID", func() {
|
||||
err = pitFileRepository.MarkHeaderChecked(headerID)
|
||||
err = pitFileDebtCeilingRepository.MarkHeaderChecked(headerID)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var headerChecked bool
|
||||
@ -112,7 +120,7 @@ var _ = Describe("Pit file debt ceiling repository", func() {
|
||||
It("updates row when headerID already exists", func() {
|
||||
_, err = db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerID)
|
||||
|
||||
err = pitFileRepository.MarkHeaderChecked(headerID)
|
||||
err = pitFileDebtCeilingRepository.MarkHeaderChecked(headerID)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var headerChecked bool
|
||||
@ -129,7 +137,7 @@ var _ = Describe("Pit file debt ceiling repository", func() {
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
startingBlock = GinkgoRandomSeed()
|
||||
startingBlock = rand.Int63()
|
||||
pitFileBlock = startingBlock + 1
|
||||
endingBlock = startingBlock + 2
|
||||
|
||||
@ -144,10 +152,11 @@ var _ = Describe("Pit file debt ceiling repository", func() {
|
||||
})
|
||||
|
||||
It("returns headers that haven't been checked", func() {
|
||||
err := pitFileRepository.MarkHeaderChecked(headerIDs[1])
|
||||
|
||||
err := pitFileDebtCeilingRepository.MarkHeaderChecked(headerIDs[1])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
headers, err := pitFileRepository.MissingHeaders(startingBlock, endingBlock)
|
||||
headers, err := pitFileDebtCeilingRepository.MissingHeaders(startingBlock, endingBlock)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(headers)).To(Equal(2))
|
||||
@ -159,7 +168,7 @@ var _ = Describe("Pit file debt ceiling repository", func() {
|
||||
_, err := db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerIDs[1])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
headers, err := pitFileRepository.MissingHeaders(startingBlock, endingBlock)
|
||||
headers, err := pitFileDebtCeilingRepository.MissingHeaders(startingBlock, endingBlock)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(headers)).To(Equal(3))
|
||||
@ -175,16 +184,16 @@ var _ = Describe("Pit file debt ceiling repository", func() {
|
||||
_, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
pitFileRepository := debt_ceiling.NewPitFileDebtCeilingRepository(db)
|
||||
pitFileRepositoryTwo := debt_ceiling.NewPitFileDebtCeilingRepository(dbTwo)
|
||||
err := pitFileRepository.MarkHeaderChecked(headerIDs[0])
|
||||
pitFileDebtCeilingRepositoryTwo := debt_ceiling.PitFileDebtCeilingRepository{}
|
||||
pitFileDebtCeilingRepositoryTwo.SetDB(dbTwo)
|
||||
err := pitFileDebtCeilingRepository.MarkHeaderChecked(headerIDs[0])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
nodeOneMissingHeaders, err := pitFileRepository.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1])
|
||||
nodeOneMissingHeaders, err := pitFileDebtCeilingRepository.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(nodeOneMissingHeaders)).To(Equal(len(blockNumbers) - 1))
|
||||
|
||||
nodeTwoMissingHeaders, err := pitFileRepositoryTwo.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1])
|
||||
nodeTwoMissingHeaders, err := pitFileDebtCeilingRepositoryTwo.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(nodeTwoMissingHeaders)).To(Equal(len(blockNumbers)))
|
||||
})
|
||||
|
@ -1,79 +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 debt_ceiling
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type PitFileDebtCeilingTransformer struct {
|
||||
Config shared.TransformerConfig
|
||||
Converter Converter
|
||||
Fetcher shared.LogFetcher
|
||||
Repository Repository
|
||||
}
|
||||
|
||||
type PitFileDebtCeilingTransformerInitializer struct {
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
func (initializer PitFileDebtCeilingTransformerInitializer) NewPitFileDebtCeilingTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
converter := PitFileDebtCeilingConverter{}
|
||||
fetcher := shared.NewFetcher(blockChain)
|
||||
repository := NewPitFileDebtCeilingRepository(db)
|
||||
return PitFileDebtCeilingTransformer{
|
||||
Config: initializer.Config,
|
||||
Converter: converter,
|
||||
Fetcher: fetcher,
|
||||
Repository: repository,
|
||||
}
|
||||
}
|
||||
|
||||
func (transformer PitFileDebtCeilingTransformer) Execute() error {
|
||||
missingHeaders, err := transformer.Repository.MissingHeaders(transformer.Config.StartingBlockNumber, transformer.Config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Fetching pit file debt ceiling event logs for %d headers \n", len(missingHeaders))
|
||||
for _, header := range missingHeaders {
|
||||
topics := [][]common.Hash{{common.HexToHash(shared.PitFileDebtCeilingSignature)}}
|
||||
matchingLogs, err := transformer.Fetcher.FetchLogs(pit_file.PitFileConfig.ContractAddresses, topics, header.BlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(matchingLogs) < 1 {
|
||||
err = transformer.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
model, err := transformer.Converter.ToModels(matchingLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = transformer.Repository.Create(header.Id, model)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -19,10 +19,11 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"math/rand"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
@ -31,31 +32,45 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Pit file debt ceiling transformer", func() {
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
repository := &debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
transformer := debt_ceiling.PitFileDebtCeilingTransformer{
|
||||
Config: pit_file.PitFileConfig,
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &debt_ceiling_mocks.MockPitFileDebtCeilingConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
var (
|
||||
config = debt_ceiling.DebtCeilingFileConfig
|
||||
fetcher mocks.MockLogFetcher
|
||||
converter debt_ceiling_mocks.MockPitFileDebtCeilingConverter
|
||||
repository debt_ceiling_mocks.MockPitFileDebtCeilingRepository
|
||||
transformer shared.Transformer
|
||||
headerOne core.Header
|
||||
headerTwo core.Header
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fetcher = mocks.MockLogFetcher{}
|
||||
converter = debt_ceiling_mocks.MockPitFileDebtCeilingConverter{}
|
||||
repository = debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
headerOne = core.Header{Id: rand.Int63(), BlockNumber: rand.Int63()}
|
||||
headerTwo = core.Header{Id: rand.Int63(), BlockNumber: rand.Int63()}
|
||||
transformer = factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}.NewTransformer(nil, nil)
|
||||
})
|
||||
|
||||
It("sets the blockchain and database", func() {
|
||||
Expect(fetcher.SetBcCalled).To(BeTrue())
|
||||
Expect(repository.SetDbCalled).To(BeTrue())
|
||||
})
|
||||
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(pit_file.PitFileConfig.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(pit_file.PitFileConfig.EndingBlockNumber))
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(config.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(config.EndingBlockNumber))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for missing headers", func() {
|
||||
repository := &debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
repository.SetMissingHeadersErr(fakes.FakeError)
|
||||
transformer := debt_ceiling.PitFileDebtCeilingTransformer{
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &debt_ceiling_mocks.MockPitFileDebtCeilingConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
repository.SetMissingHeadersError(fakes.FakeError)
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
@ -63,34 +78,18 @@ var _ = Describe("Pit file debt ceiling transformer", func() {
|
||||
})
|
||||
|
||||
It("fetches logs for missing headers", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
repository := &debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}, {BlockNumber: 2}})
|
||||
transformer := debt_ceiling.PitFileDebtCeilingTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &debt_ceiling_mocks.MockPitFileDebtCeilingConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{1, 2}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{pit_file.PitFileConfig.ContractAddresses, pit_file.PitFileConfig.ContractAddresses}))
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{headerOne.BlockNumber, headerTwo.BlockNumber}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{config.ContractAddresses, config.ContractAddresses}))
|
||||
Expect(fetcher.FetchedTopics).To(Equal([][]common.Hash{{common.HexToHash(shared.PitFileDebtCeilingSignature)}}))
|
||||
})
|
||||
|
||||
It("returns error if fetcher returns error", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetcherError(fakes.FakeError)
|
||||
repository := &debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := debt_ceiling.PitFileDebtCeilingTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &debt_ceiling_mocks.MockPitFileDebtCeilingConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
@ -98,34 +97,17 @@ var _ = Describe("Pit file debt ceiling transformer", func() {
|
||||
})
|
||||
|
||||
It("marks header checked if no logs returned", func() {
|
||||
mockConverter := &debt_ceiling_mocks.MockPitFileDebtCeilingConverter{}
|
||||
mockRepository := &debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
headerID := int64(123)
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: headerID}})
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := debt_ceiling.PitFileDebtCeilingTransformer{
|
||||
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 := &debt_ceiling_mocks.MockPitFileDebtCeilingConverter{}
|
||||
mockRepository := &debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: int64(123)}})
|
||||
mockRepository.SetMarkHeaderCheckedErr(fakes.FakeError)
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := debt_ceiling.PitFileDebtCeilingTransformer{
|
||||
Converter: mockConverter,
|
||||
Fetcher: mockFetcher,
|
||||
Repository: mockRepository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetMarkHeaderCheckedError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -134,16 +116,8 @@ var _ = Describe("Pit file debt ceiling transformer", func() {
|
||||
})
|
||||
|
||||
It("converts matching logs", func() {
|
||||
converter := &debt_ceiling_mocks.MockPitFileDebtCeilingConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileDebtCeilingLog})
|
||||
repository := &debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := debt_ceiling.PitFileDebtCeilingTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -152,17 +126,9 @@ var _ = Describe("Pit file debt ceiling transformer", func() {
|
||||
})
|
||||
|
||||
It("returns error if converter returns error", func() {
|
||||
converter := &debt_ceiling_mocks.MockPitFileDebtCeilingConverter{}
|
||||
converter.SetConverterError(fakes.FakeError)
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileDebtCeilingLog})
|
||||
repository := &debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := debt_ceiling.PitFileDebtCeilingTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -171,37 +137,20 @@ var _ = Describe("Pit file debt ceiling transformer", func() {
|
||||
})
|
||||
|
||||
It("persists pit file model", func() {
|
||||
converter := &debt_ceiling_mocks.MockPitFileDebtCeilingConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileDebtCeilingLog})
|
||||
repository := &debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
fakeHeader := core.Header{BlockNumber: 1, Id: 2}
|
||||
repository.SetMissingHeaders([]core.Header{fakeHeader})
|
||||
transformer := debt_ceiling.PitFileDebtCeilingTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedHeaderID).To(Equal(fakeHeader.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]debt_ceiling.PitFileDebtCeilingModel{test_data.PitFileDebtCeilingModel}))
|
||||
Expect(repository.PassedHeaderID).To(Equal(headerOne.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]interface{}{test_data.PitFileDebtCeilingModel}))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for create", func() {
|
||||
converter := &debt_ceiling_mocks.MockPitFileDebtCeilingConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileDebtCeilingLog})
|
||||
repository := &debt_ceiling_mocks.MockPitFileDebtCeilingRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: 2}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetCreateError(fakes.FakeError)
|
||||
transformer := debt_ceiling.PitFileDebtCeilingTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
|
28
pkg/transformers/pit_file/ilk/config.go
Normal file
28
pkg/transformers/pit_file/ilk/config.go
Normal file
@ -0,0 +1,28 @@
|
||||
// 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 ilk
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
var IlkFileConfig = shared.SingleTransformerConfig{
|
||||
TransformerName: shared.PitFileIlkLabel,
|
||||
ContractAddresses: []string{shared.PitContractAddress},
|
||||
ContractAbi: shared.PitABI,
|
||||
Topic: shared.PitFileIlkSignature,
|
||||
StartingBlockNumber: 0,
|
||||
EndingBlockNumber: 10000000,
|
||||
}
|
@ -24,14 +24,10 @@ import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type Converter interface {
|
||||
ToModels(ethLogs []types.Log) ([]PitFileIlkModel, error)
|
||||
}
|
||||
|
||||
type PitFileIlkConverter struct{}
|
||||
|
||||
func (PitFileIlkConverter) ToModels(ethLogs []types.Log) ([]PitFileIlkModel, error) {
|
||||
var models []PitFileIlkModel
|
||||
func (PitFileIlkConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
var models []interface{}
|
||||
for _, ethLog := range ethLogs {
|
||||
err := verifyLog(ethLog)
|
||||
if err != nil {
|
||||
|
@ -54,6 +54,6 @@ var _ = Describe("Pit file ilk converter", func() {
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(models)).To(Equal(1))
|
||||
Expect(models[0]).To(Equal(test_data.PitFileIlkModel))
|
||||
Expect(models[0].(ilk.PitFileIlkModel)).To(Equal(test_data.PitFileIlkModel))
|
||||
})
|
||||
})
|
||||
|
@ -15,36 +15,32 @@
|
||||
package ilk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(headerID int64, models []PitFileIlkModel) error
|
||||
MarkHeaderChecked(headerID int64) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
}
|
||||
|
||||
type PitFileIlkRepository struct {
|
||||
db *postgres.DB
|
||||
}
|
||||
|
||||
func NewPitFileIlkRepository(db *postgres.DB) PitFileIlkRepository {
|
||||
return PitFileIlkRepository{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (repository PitFileIlkRepository) Create(headerID int64, models []PitFileIlkModel) error {
|
||||
func (repository PitFileIlkRepository) Create(headerID int64, models []interface{}) error {
|
||||
tx, err := repository.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, model := range models {
|
||||
pitFileIlk, ok := model.(PitFileIlkModel)
|
||||
if !ok {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("model of type %T, not %T", model, PitFileIlkModel{})
|
||||
}
|
||||
|
||||
_, err = tx.Exec(
|
||||
`INSERT into maker.pit_file_ilk (header_id, ilk, what, data, tx_idx, raw_log)
|
||||
VALUES($1, $2, $3, $4::NUMERIC, $5, $6)`,
|
||||
headerID, model.Ilk, model.What, model.Data, model.TransactionIndex, model.Raw,
|
||||
headerID, pitFileIlk.Ilk, pitFileIlk.What, pitFileIlk.Data, pitFileIlk.TransactionIndex, pitFileIlk.Raw,
|
||||
)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
@ -75,14 +71,18 @@ func (repository PitFileIlkRepository) MissingHeaders(startingBlockNumber, endin
|
||||
err := repository.db.Select(
|
||||
&result,
|
||||
`SELECT headers.id, headers.block_number FROM headers
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
WHERE (header_id ISNULL OR pit_file_ilk_checked IS FALSE)
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
startingBlockNumber,
|
||||
endingBlockNumber,
|
||||
repository.db.Node.ID,
|
||||
)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (repository *PitFileIlkRepository) SetDB(db *postgres.DB) {
|
||||
repository.db = db
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package ilk_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"math/rand"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@ -33,7 +34,7 @@ import (
|
||||
var _ = Describe("Pit file ilk repository", func() {
|
||||
var (
|
||||
db *postgres.DB
|
||||
pitFileRepository ilk.Repository
|
||||
pitFileRepository ilk.PitFileIlkRepository
|
||||
err error
|
||||
headerRepository datastore.HeaderRepository
|
||||
)
|
||||
@ -42,7 +43,8 @@ var _ = Describe("Pit file ilk repository", func() {
|
||||
db = test_config.NewTestDB(core.Node{})
|
||||
test_config.CleanTestDB(db)
|
||||
headerRepository = repositories.NewHeaderRepository(db)
|
||||
pitFileRepository = ilk.NewPitFileIlkRepository(db)
|
||||
pitFileRepository = ilk.PitFileIlkRepository{}
|
||||
pitFileRepository.SetDB(db)
|
||||
})
|
||||
|
||||
Describe("Create", func() {
|
||||
@ -52,7 +54,7 @@ var _ = Describe("Pit file ilk repository", func() {
|
||||
headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = pitFileRepository.Create(headerID, []ilk.PitFileIlkModel{test_data.PitFileIlkModel})
|
||||
err = pitFileRepository.Create(headerID, []interface{}{test_data.PitFileIlkModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -75,7 +77,7 @@ var _ = Describe("Pit file ilk repository", func() {
|
||||
})
|
||||
|
||||
It("does not duplicate pit file ilk events", func() {
|
||||
err = pitFileRepository.Create(headerID, []ilk.PitFileIlkModel{test_data.PitFileIlkModel})
|
||||
err = pitFileRepository.Create(headerID, []interface{}{test_data.PitFileIlkModel})
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
|
||||
@ -90,6 +92,12 @@ var _ = Describe("Pit file ilk repository", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(sql.ErrNoRows))
|
||||
})
|
||||
|
||||
It("Returns an error if model is of wrong type", func() {
|
||||
err = pitFileRepository.Create(headerID, []interface{}{test_data.WrongModel{}})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("model of type"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MarkHeaderChecked", func() {
|
||||
@ -130,7 +138,7 @@ var _ = Describe("Pit file ilk repository", func() {
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
startingBlock = GinkgoRandomSeed()
|
||||
startingBlock = rand.Int63()
|
||||
pitFileBlock = startingBlock + 1
|
||||
endingBlock = startingBlock + 2
|
||||
|
||||
@ -176,7 +184,9 @@ var _ = Describe("Pit file ilk repository", func() {
|
||||
_, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
pitFileRepositoryTwo := ilk.NewPitFileIlkRepository(dbTwo)
|
||||
|
||||
pitFileRepositoryTwo := ilk.PitFileIlkRepository{}
|
||||
pitFileRepositoryTwo.SetDB(dbTwo)
|
||||
err := pitFileRepository.MarkHeaderChecked(headerIDs[0])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -1,79 +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 ilk
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type PitFileIlkTransformer struct {
|
||||
Config shared.TransformerConfig
|
||||
Converter Converter
|
||||
Fetcher shared.LogFetcher
|
||||
Repository Repository
|
||||
}
|
||||
|
||||
type PitFileIlkTransformerInitializer struct {
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
func (initializer PitFileIlkTransformerInitializer) NewPitFileIlkTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
converter := PitFileIlkConverter{}
|
||||
fetcher := shared.NewFetcher(blockChain)
|
||||
repository := NewPitFileIlkRepository(db)
|
||||
return PitFileIlkTransformer{
|
||||
Config: initializer.Config,
|
||||
Converter: converter,
|
||||
Fetcher: fetcher,
|
||||
Repository: repository,
|
||||
}
|
||||
}
|
||||
|
||||
func (transformer PitFileIlkTransformer) Execute() error {
|
||||
missingHeaders, err := transformer.Repository.MissingHeaders(transformer.Config.StartingBlockNumber, transformer.Config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Fetching pit file ilk event logs for %d headers \n", len(missingHeaders))
|
||||
for _, header := range missingHeaders {
|
||||
topics := [][]common.Hash{{common.HexToHash(shared.PitFileIlkSignature)}}
|
||||
matchingLogs, err := transformer.Fetcher.FetchLogs(pit_file.PitFileConfig.ContractAddresses, topics, header.BlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(matchingLogs) < 1 {
|
||||
err = transformer.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
models, err := transformer.Converter.ToModels(matchingLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = transformer.Repository.Create(header.Id, models)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -19,42 +19,58 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"math/rand"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/ilk"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks"
|
||||
pit_file_ilk_mocks "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks/pit_file/ilk"
|
||||
ilk_mocks "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks/pit_file/ilk"
|
||||
)
|
||||
|
||||
var _ = Describe("Pit file ilk transformer", func() {
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
repository := &pit_file_ilk_mocks.MockPitFileIlkRepository{}
|
||||
transformer := ilk.PitFileIlkTransformer{
|
||||
Config: pit_file.PitFileConfig,
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &pit_file_ilk_mocks.MockPitFileIlkConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
var (
|
||||
config = ilk.IlkFileConfig
|
||||
fetcher mocks.MockLogFetcher
|
||||
converter ilk_mocks.MockPitFileIlkConverter
|
||||
repository ilk_mocks.MockPitFileIlkRepository
|
||||
transformer shared.Transformer
|
||||
headerOne core.Header
|
||||
headerTwo core.Header
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fetcher = mocks.MockLogFetcher{}
|
||||
converter = ilk_mocks.MockPitFileIlkConverter{}
|
||||
repository = ilk_mocks.MockPitFileIlkRepository{}
|
||||
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,
|
||||
Repository: &repository,
|
||||
Fetcher: &fetcher,
|
||||
}.NewTransformer(nil, nil)
|
||||
})
|
||||
|
||||
It("sets the blockchain and database", func() {
|
||||
Expect(fetcher.SetBcCalled).To(BeTrue())
|
||||
Expect(repository.SetDbCalled).To(BeTrue())
|
||||
})
|
||||
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(pit_file.PitFileConfig.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(pit_file.PitFileConfig.EndingBlockNumber))
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(config.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(config.EndingBlockNumber))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for missing headers", func() {
|
||||
repository := &pit_file_ilk_mocks.MockPitFileIlkRepository{}
|
||||
repository.SetMissingHeadersErr(fakes.FakeError)
|
||||
transformer := ilk.PitFileIlkTransformer{
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &pit_file_ilk_mocks.MockPitFileIlkConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeadersError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -63,33 +79,19 @@ var _ = Describe("Pit file ilk transformer", func() {
|
||||
})
|
||||
|
||||
It("fetches logs for missing headers", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
repository := &pit_file_ilk_mocks.MockPitFileIlkRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}, {BlockNumber: 2}})
|
||||
transformer := ilk.PitFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &pit_file_ilk_mocks.MockPitFileIlkConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{1, 2}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{pit_file.PitFileConfig.ContractAddresses, pit_file.PitFileConfig.ContractAddresses}))
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{headerOne.BlockNumber, headerTwo.BlockNumber}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{config.ContractAddresses, config.ContractAddresses}))
|
||||
Expect(fetcher.FetchedTopics).To(Equal([][]common.Hash{{common.HexToHash(shared.PitFileIlkSignature)}}))
|
||||
})
|
||||
|
||||
It("returns error if fetcher returns error", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetcherError(fakes.FakeError)
|
||||
repository := &pit_file_ilk_mocks.MockPitFileIlkRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := ilk.PitFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &pit_file_ilk_mocks.MockPitFileIlkConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -98,34 +100,17 @@ var _ = Describe("Pit file ilk transformer", func() {
|
||||
})
|
||||
|
||||
It("marks header checked if no logs returned", func() {
|
||||
mockConverter := &pit_file_ilk_mocks.MockPitFileIlkConverter{}
|
||||
mockRepository := &pit_file_ilk_mocks.MockPitFileIlkRepository{}
|
||||
headerID := int64(123)
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: headerID}})
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := ilk.PitFileIlkTransformer{
|
||||
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 := &pit_file_ilk_mocks.MockPitFileIlkConverter{}
|
||||
mockRepository := &pit_file_ilk_mocks.MockPitFileIlkRepository{}
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: int64(123)}})
|
||||
mockRepository.SetMarkHeaderCheckedErr(fakes.FakeError)
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := ilk.PitFileIlkTransformer{
|
||||
Converter: mockConverter,
|
||||
Fetcher: mockFetcher,
|
||||
Repository: mockRepository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetMarkHeaderCheckedError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -134,16 +119,8 @@ var _ = Describe("Pit file ilk transformer", func() {
|
||||
})
|
||||
|
||||
It("converts matching logs", func() {
|
||||
converter := &pit_file_ilk_mocks.MockPitFileIlkConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileIlkLog})
|
||||
repository := &pit_file_ilk_mocks.MockPitFileIlkRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := ilk.PitFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -152,17 +129,9 @@ var _ = Describe("Pit file ilk transformer", func() {
|
||||
})
|
||||
|
||||
It("returns error if converter returns error", func() {
|
||||
converter := &pit_file_ilk_mocks.MockPitFileIlkConverter{}
|
||||
converter.SetConverterError(fakes.FakeError)
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileIlkLog})
|
||||
repository := &pit_file_ilk_mocks.MockPitFileIlkRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := ilk.PitFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -171,37 +140,20 @@ var _ = Describe("Pit file ilk transformer", func() {
|
||||
})
|
||||
|
||||
It("persists pit file model", func() {
|
||||
converter := &pit_file_ilk_mocks.MockPitFileIlkConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileIlkLog})
|
||||
repository := &pit_file_ilk_mocks.MockPitFileIlkRepository{}
|
||||
fakeHeader := core.Header{BlockNumber: 1, Id: 2}
|
||||
repository.SetMissingHeaders([]core.Header{fakeHeader})
|
||||
transformer := ilk.PitFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedHeaderID).To(Equal(fakeHeader.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]ilk.PitFileIlkModel{test_data.PitFileIlkModel}))
|
||||
Expect(repository.PassedHeaderID).To(Equal(headerOne.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]interface{}{test_data.PitFileIlkModel}))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for create", func() {
|
||||
converter := &pit_file_ilk_mocks.MockPitFileIlkConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileIlkLog})
|
||||
repository := &pit_file_ilk_mocks.MockPitFileIlkRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: 2}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetCreateError(fakes.FakeError)
|
||||
transformer := ilk.PitFileIlkTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
|
28
pkg/transformers/pit_file/stability_fee/config.go
Normal file
28
pkg/transformers/pit_file/stability_fee/config.go
Normal file
@ -0,0 +1,28 @@
|
||||
// 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 stability_fee
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
var StabilityFeeFileConfig = shared.SingleTransformerConfig{
|
||||
TransformerName: shared.PitFileStabilityFeeLabel,
|
||||
ContractAddresses: []string{shared.PitContractAddress},
|
||||
ContractAbi: shared.PitABI,
|
||||
Topic: shared.PitFileStabilityFeeSignature,
|
||||
StartingBlockNumber: 0,
|
||||
EndingBlockNumber: 10000000,
|
||||
}
|
@ -23,14 +23,10 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
type Converter interface {
|
||||
ToModels(ethLogs []types.Log) ([]PitFileStabilityFeeModel, error)
|
||||
}
|
||||
|
||||
type PitFileStabilityFeeConverter struct{}
|
||||
|
||||
func (PitFileStabilityFeeConverter) ToModels(ethLogs []types.Log) ([]PitFileStabilityFeeModel, error) {
|
||||
var models []PitFileStabilityFeeModel
|
||||
func (PitFileStabilityFeeConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
var models []interface{}
|
||||
for _, ethLog := range ethLogs {
|
||||
err := verifyLog(ethLog)
|
||||
if err != nil {
|
||||
|
@ -15,50 +15,50 @@
|
||||
package stability_fee
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(headerID int64, models []PitFileStabilityFeeModel) error
|
||||
MarkHeaderChecked(headerID int64) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
}
|
||||
|
||||
type PitFileStabilityFeeRepository struct {
|
||||
db *postgres.DB
|
||||
}
|
||||
|
||||
func NewPitFileStabilityFeeRepository(db *postgres.DB) PitFileStabilityFeeRepository {
|
||||
return PitFileStabilityFeeRepository{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (repository PitFileStabilityFeeRepository) Create(headerID int64, models []PitFileStabilityFeeModel) error {
|
||||
func (repository PitFileStabilityFeeRepository) Create(headerID int64, models []interface{}) error {
|
||||
tx, err := repository.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, model := range models {
|
||||
pitFileSF, ok := model.(PitFileStabilityFeeModel)
|
||||
if !ok {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("model of type %T, not %T", model, PitFileStabilityFeeModel{})
|
||||
}
|
||||
|
||||
_, err = tx.Exec(
|
||||
`INSERT into maker.pit_file_stability_fee (header_id, what, data, tx_idx, raw_log)
|
||||
VALUES($1, $2, $3, $4, $5)`,
|
||||
headerID, model.What, model.Data, model.TransactionIndex, model.Raw,
|
||||
headerID, pitFileSF.What, pitFileSF.Data, pitFileSF.TransactionIndex, pitFileSF.Raw,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, pit_file_stability_fee_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET pit_file_stability_fee_checked = $2`, headerID, true)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
@ -86,3 +86,7 @@ func (repository PitFileStabilityFeeRepository) MissingHeaders(startingBlockNumb
|
||||
)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (repository *PitFileStabilityFeeRepository) SetDB(db *postgres.DB) {
|
||||
repository.db = db
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package stability_fee_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"math/rand"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@ -32,17 +33,18 @@ import (
|
||||
|
||||
var _ = Describe("Pit file stability fee repository", func() {
|
||||
var (
|
||||
db *postgres.DB
|
||||
pitFileRepository stability_fee.Repository
|
||||
err error
|
||||
headerRepository datastore.HeaderRepository
|
||||
db *postgres.DB
|
||||
pitFileStabilityFeeRepository stability_fee.PitFileStabilityFeeRepository
|
||||
err error
|
||||
headerRepository datastore.HeaderRepository
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
db = test_config.NewTestDB(core.Node{})
|
||||
test_config.CleanTestDB(db)
|
||||
headerRepository = repositories.NewHeaderRepository(db)
|
||||
pitFileRepository = stability_fee.NewPitFileStabilityFeeRepository(db)
|
||||
pitFileStabilityFeeRepository = stability_fee.PitFileStabilityFeeRepository{}
|
||||
pitFileStabilityFeeRepository.SetDB(db)
|
||||
})
|
||||
|
||||
Describe("Create", func() {
|
||||
@ -52,7 +54,7 @@ var _ = Describe("Pit file stability fee repository", func() {
|
||||
headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = pitFileRepository.Create(headerID, []stability_fee.PitFileStabilityFeeModel{test_data.PitFileStabilityFeeModel})
|
||||
err = pitFileStabilityFeeRepository.Create(headerID, []interface{}{test_data.PitFileStabilityFeeModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -74,7 +76,7 @@ var _ = Describe("Pit file stability fee repository", func() {
|
||||
})
|
||||
|
||||
It("does not duplicate pit file events", func() {
|
||||
err = pitFileRepository.Create(headerID, []stability_fee.PitFileStabilityFeeModel{test_data.PitFileStabilityFeeModel})
|
||||
err = pitFileStabilityFeeRepository.Create(headerID, []interface{}{test_data.PitFileStabilityFeeModel})
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
|
||||
@ -89,6 +91,12 @@ var _ = Describe("Pit file stability fee repository", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(sql.ErrNoRows))
|
||||
})
|
||||
|
||||
It("Returns an error if model is of wrong type", func() {
|
||||
err = pitFileStabilityFeeRepository.Create(headerID, []interface{}{test_data.WrongModel{}})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("model of type"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MarkHeaderChecked", func() {
|
||||
@ -100,7 +108,7 @@ var _ = Describe("Pit file stability fee repository", func() {
|
||||
})
|
||||
|
||||
It("creates a row for a new headerID", func() {
|
||||
err = pitFileRepository.MarkHeaderChecked(headerID)
|
||||
err = pitFileStabilityFeeRepository.MarkHeaderChecked(headerID)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var headerChecked bool
|
||||
@ -112,7 +120,7 @@ var _ = Describe("Pit file stability fee repository", func() {
|
||||
It("updates row when headerID already exists", func() {
|
||||
_, err = db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerID)
|
||||
|
||||
err = pitFileRepository.MarkHeaderChecked(headerID)
|
||||
err = pitFileStabilityFeeRepository.MarkHeaderChecked(headerID)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var headerChecked bool
|
||||
@ -129,7 +137,7 @@ var _ = Describe("Pit file stability fee repository", func() {
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
startingBlock = GinkgoRandomSeed()
|
||||
startingBlock = rand.Int63()
|
||||
pitFileBlock = startingBlock + 1
|
||||
endingBlock = startingBlock + 2
|
||||
|
||||
@ -144,10 +152,10 @@ var _ = Describe("Pit file stability fee repository", func() {
|
||||
})
|
||||
|
||||
It("returns headers that haven't been checked", func() {
|
||||
err := pitFileRepository.MarkHeaderChecked(headerIDs[1])
|
||||
err = pitFileStabilityFeeRepository.MarkHeaderChecked(headerIDs[1])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
headers, err := pitFileRepository.MissingHeaders(startingBlock, endingBlock)
|
||||
headers, err := pitFileStabilityFeeRepository.MissingHeaders(startingBlock, endingBlock)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(headers)).To(Equal(2))
|
||||
@ -156,10 +164,10 @@ var _ = Describe("Pit file stability fee repository", func() {
|
||||
})
|
||||
|
||||
It("only treats headers as checked if pit file stability fee logs have been checked", func() {
|
||||
_, err := db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerIDs[1])
|
||||
_, err = db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerIDs[1])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
headers, err := pitFileRepository.MissingHeaders(startingBlock, endingBlock)
|
||||
headers, err := pitFileStabilityFeeRepository.MissingHeaders(startingBlock, endingBlock)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(headers)).To(Equal(3))
|
||||
@ -175,11 +183,13 @@ var _ = Describe("Pit file stability fee repository", func() {
|
||||
_, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
pitFileRepositoryTwo := stability_fee.NewPitFileStabilityFeeRepository(dbTwo)
|
||||
err := pitFileRepository.MarkHeaderChecked(headerIDs[0])
|
||||
|
||||
pitFileRepositoryTwo := stability_fee.PitFileStabilityFeeRepository{}
|
||||
pitFileRepositoryTwo.SetDB(dbTwo)
|
||||
err = pitFileStabilityFeeRepository.MarkHeaderChecked(headerIDs[0])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
nodeOneMissingHeaders, err := pitFileRepository.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1])
|
||||
nodeOneMissingHeaders, err := pitFileStabilityFeeRepository.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(nodeOneMissingHeaders)).To(Equal(len(blockNumbers) - 1))
|
||||
|
||||
|
@ -1,79 +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 stability_fee
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type PitFileStabilityFeeTransformer struct {
|
||||
Config shared.TransformerConfig
|
||||
Converter Converter
|
||||
Fetcher shared.LogFetcher
|
||||
Repository Repository
|
||||
}
|
||||
|
||||
type PitFileStabilityFeeTransformerInitializer struct {
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
func (initializer PitFileStabilityFeeTransformerInitializer) NewPitFileStabilityFeeTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
converter := PitFileStabilityFeeConverter{}
|
||||
fetcher := shared.NewFetcher(blockChain)
|
||||
repository := NewPitFileStabilityFeeRepository(db)
|
||||
return PitFileStabilityFeeTransformer{
|
||||
Config: initializer.Config,
|
||||
Converter: converter,
|
||||
Fetcher: fetcher,
|
||||
Repository: repository,
|
||||
}
|
||||
}
|
||||
|
||||
func (transformer PitFileStabilityFeeTransformer) Execute() error {
|
||||
missingHeaders, err := transformer.Repository.MissingHeaders(transformer.Config.StartingBlockNumber, transformer.Config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Fetching pit file stability fee event logs for %d headers \n", len(missingHeaders))
|
||||
for _, header := range missingHeaders {
|
||||
topics := [][]common.Hash{{common.HexToHash(shared.PitFileStabilityFeeSignature)}}
|
||||
matchingLogs, err := transformer.Fetcher.FetchLogs(pit_file.PitFileConfig.ContractAddresses, topics, header.BlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(matchingLogs) < 1 {
|
||||
err = transformer.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
models, err := transformer.Converter.ToModels(matchingLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = transformer.Repository.Create(header.Id, models)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -19,11 +19,12 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/stability_fee"
|
||||
"math/rand"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/stability_fee"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks"
|
||||
@ -31,31 +32,45 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Pit file stability fee transformer", func() {
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
repository := &stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
transformer := stability_fee.PitFileStabilityFeeTransformer{
|
||||
Config: pit_file.PitFileConfig,
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &stability_fee_mocks.MockPitFileStabilityFeeConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
var (
|
||||
config = stability_fee.StabilityFeeFileConfig
|
||||
fetcher mocks.MockLogFetcher
|
||||
converter stability_fee_mocks.MockPitFileStabilityFeeConverter
|
||||
repository stability_fee_mocks.MockPitFileStabilityFeeRepository
|
||||
transformer shared.Transformer
|
||||
headerOne core.Header
|
||||
headerTwo core.Header
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fetcher = mocks.MockLogFetcher{}
|
||||
converter = stability_fee_mocks.MockPitFileStabilityFeeConverter{}
|
||||
repository = stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
transformer = factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}.NewTransformer(nil, nil)
|
||||
headerOne = core.Header{Id: rand.Int63(), BlockNumber: rand.Int63()}
|
||||
headerTwo = core.Header{Id: rand.Int63(), BlockNumber: rand.Int63()}
|
||||
})
|
||||
|
||||
It("sets the blockchain and database", func() {
|
||||
Expect(fetcher.SetBcCalled).To(BeTrue())
|
||||
Expect(repository.SetDbCalled).To(BeTrue())
|
||||
})
|
||||
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(pit_file.PitFileConfig.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(pit_file.PitFileConfig.EndingBlockNumber))
|
||||
Expect(repository.PassedStartingBlockNumber).To(Equal(config.StartingBlockNumber))
|
||||
Expect(repository.PassedEndingBlockNumber).To(Equal(config.EndingBlockNumber))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for missing headers", func() {
|
||||
repository := &stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
repository.SetMissingHeadersErr(fakes.FakeError)
|
||||
transformer := stability_fee.PitFileStabilityFeeTransformer{
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &stability_fee_mocks.MockPitFileStabilityFeeConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
@ -63,33 +78,19 @@ var _ = Describe("Pit file stability fee transformer", func() {
|
||||
})
|
||||
|
||||
It("fetches logs for missing headers", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
repository := &stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}, {BlockNumber: 2}})
|
||||
transformer := stability_fee.PitFileStabilityFeeTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &stability_fee_mocks.MockPitFileStabilityFeeConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{1, 2}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{pit_file.PitFileConfig.ContractAddresses, pit_file.PitFileConfig.ContractAddresses}))
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{headerOne.BlockNumber, headerTwo.BlockNumber}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{
|
||||
config.ContractAddresses, config.ContractAddresses}))
|
||||
Expect(fetcher.FetchedTopics).To(Equal([][]common.Hash{{common.HexToHash(shared.PitFileStabilityFeeSignature)}}))
|
||||
})
|
||||
|
||||
It("returns error if fetcher returns error", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetcherError(fakes.FakeError)
|
||||
repository := &stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := stability_fee.PitFileStabilityFeeTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &stability_fee_mocks.MockPitFileStabilityFeeConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -98,34 +99,17 @@ var _ = Describe("Pit file stability fee transformer", func() {
|
||||
})
|
||||
|
||||
It("marks header checked if no logs returned", func() {
|
||||
mockConverter := &stability_fee_mocks.MockPitFileStabilityFeeConverter{}
|
||||
mockRepository := &stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
headerID := int64(123)
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: headerID}})
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := stability_fee.PitFileStabilityFeeTransformer{
|
||||
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 := &stability_fee_mocks.MockPitFileStabilityFeeConverter{}
|
||||
mockRepository := &stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: int64(123)}})
|
||||
mockRepository.SetMarkHeaderCheckedErr(fakes.FakeError)
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := stability_fee.PitFileStabilityFeeTransformer{
|
||||
Converter: mockConverter,
|
||||
Fetcher: mockFetcher,
|
||||
Repository: mockRepository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetMarkHeaderCheckedErr(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -134,16 +118,8 @@ var _ = Describe("Pit file stability fee transformer", func() {
|
||||
})
|
||||
|
||||
It("converts matching logs", func() {
|
||||
converter := &stability_fee_mocks.MockPitFileStabilityFeeConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileStabilityFeeLog})
|
||||
repository := &stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := stability_fee.PitFileStabilityFeeTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -152,17 +128,9 @@ var _ = Describe("Pit file stability fee transformer", func() {
|
||||
})
|
||||
|
||||
It("returns error if converter returns error", func() {
|
||||
converter := &stability_fee_mocks.MockPitFileStabilityFeeConverter{}
|
||||
converter.SetConverterError(fakes.FakeError)
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileStabilityFeeLog})
|
||||
repository := &stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := stability_fee.PitFileStabilityFeeTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -171,37 +139,20 @@ var _ = Describe("Pit file stability fee transformer", func() {
|
||||
})
|
||||
|
||||
It("persists pit file model", func() {
|
||||
converter := &stability_fee_mocks.MockPitFileStabilityFeeConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileStabilityFeeLog})
|
||||
repository := &stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
fakeHeader := core.Header{BlockNumber: 1, Id: 2}
|
||||
repository.SetMissingHeaders([]core.Header{fakeHeader})
|
||||
transformer := stability_fee.PitFileStabilityFeeTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedHeaderID).To(Equal(fakeHeader.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]stability_fee.PitFileStabilityFeeModel{test_data.PitFileStabilityFeeModel}))
|
||||
Expect(repository.PassedHeaderID).To(Equal(headerOne.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]interface{}{test_data.PitFileStabilityFeeModel}))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for create", func() {
|
||||
converter := &stability_fee_mocks.MockPitFileStabilityFeeConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthPitFileStabilityFeeLog})
|
||||
repository := &stability_fee_mocks.MockPitFileStabilityFeeRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: 2}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetCreateError(fakes.FakeError)
|
||||
transformer := stability_fee.PitFileStabilityFeeTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
|
@ -102,4 +102,32 @@ var (
|
||||
VatTollSignature = GetLogNoteSignature(vatTollMethod)
|
||||
VatTuneSignature = GetLogNoteSignature(vatTuneMethod)
|
||||
VatFluxSignature = GetLogNoteSignature(vatFluxMethod)
|
||||
|
||||
BiteLabel = "bite"
|
||||
DealLabel = "deal"
|
||||
CatFileChopLumpLabel = "catFileChopLump"
|
||||
CatFileFlipLabel = "catFileFlip"
|
||||
CatFilePitVowLabel = "catFilePitVow"
|
||||
DentLabel = "dent"
|
||||
DripDripLabel = "dripDrip"
|
||||
DripFileIlkLabel = "dripFileIlk"
|
||||
DripFileRepoLabel = "dripFileRepo"
|
||||
DripFileVowLabel = "dripFileVow"
|
||||
FlipKickLabel = "flipKick"
|
||||
FlopKickLabel = "flopKick"
|
||||
FrobLabel = "frob"
|
||||
PitFileDebtCeilingLabel = "pitFileDebtCeiling"
|
||||
PitFileIlkLabel = "pitFileIlk"
|
||||
PitFileStabilityFeeLabel = "pitFileStabilityFee"
|
||||
PriceFeedLabel = "priceFeed"
|
||||
TendLabel = "tend"
|
||||
VatHealLabel = "vatHeal"
|
||||
VatGrabLabel = "vatGrab"
|
||||
VatInitLabel = "vatInit"
|
||||
VatMoveLabel = "vatMove"
|
||||
VatFoldLabel = "vatFold"
|
||||
VatSlipLabel = "vatSlip"
|
||||
VatTollLabel = "vatToll"
|
||||
VatTuneLabel = "vatTune"
|
||||
VatFluxLabel = "vatFlux"
|
||||
)
|
||||
|
@ -28,10 +28,19 @@ type LogFetcher interface {
|
||||
FetchLogs(contractAddresses []string, topics [][]common.Hash, blockNumber int64) ([]types.Log, error)
|
||||
}
|
||||
|
||||
type SettableLogFetcher interface {
|
||||
LogFetcher
|
||||
SetBC(bc core.BlockChain)
|
||||
}
|
||||
|
||||
type Fetcher struct {
|
||||
blockChain core.BlockChain
|
||||
}
|
||||
|
||||
func (fetcher *Fetcher) SetBC(bc core.BlockChain) {
|
||||
fetcher.blockChain = bc
|
||||
}
|
||||
|
||||
func NewFetcher(blockchain core.BlockChain) Fetcher {
|
||||
return Fetcher{
|
||||
blockChain: blockchain,
|
||||
|
@ -28,9 +28,19 @@ type Transformer interface {
|
||||
type TransformerInitializer func(db *postgres.DB, blockChain core.BlockChain) Transformer
|
||||
|
||||
type TransformerConfig struct {
|
||||
TransformerName string
|
||||
ContractAddresses []string
|
||||
ContractAbi string
|
||||
Topics []string
|
||||
Topics []string // TODO Change this to single topic
|
||||
StartingBlockNumber int64
|
||||
EndingBlockNumber int64
|
||||
}
|
||||
|
||||
type SingleTransformerConfig struct {
|
||||
TransformerName string
|
||||
ContractAddresses []string
|
||||
ContractAbi string
|
||||
Topic string
|
||||
StartingBlockNumber int64
|
||||
EndingBlockNumber int64
|
||||
}
|
||||
|
@ -16,10 +16,11 @@ package tend
|
||||
|
||||
import "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
|
||||
var TendConfig = shared.TransformerConfig{
|
||||
var TendConfig = shared.SingleTransformerConfig{
|
||||
TransformerName: shared.TendLabel,
|
||||
ContractAddresses: []string{shared.FlipperContractAddress},
|
||||
ContractAbi: shared.FlipperABI,
|
||||
Topics: []string{shared.TendFunctionSignature},
|
||||
Topic: shared.TendFunctionSignature,
|
||||
StartingBlockNumber: 0,
|
||||
EndingBlockNumber: 10000000,
|
||||
}
|
||||
|
@ -23,17 +23,9 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
type Converter interface {
|
||||
ToModels(ethLogs []types.Log) ([]TendModel, error)
|
||||
}
|
||||
|
||||
type TendConverter struct{}
|
||||
|
||||
func NewTendConverter() TendConverter {
|
||||
return TendConverter{}
|
||||
}
|
||||
|
||||
func (c TendConverter) ToModels(ethLogs []types.Log) (results []TendModel, err error) {
|
||||
func (TendConverter) ToModels(ethLogs []types.Log) (results []interface{}, err error) {
|
||||
for _, ethLog := range ethLogs {
|
||||
err := validateLog(ethLog)
|
||||
if err != nil {
|
||||
|
@ -28,7 +28,7 @@ var _ = Describe("Tend TendConverter", func() {
|
||||
var converter tend.TendConverter
|
||||
|
||||
BeforeEach(func() {
|
||||
converter = tend.NewTendConverter()
|
||||
converter = tend.TendConverter{}
|
||||
})
|
||||
|
||||
Describe("ToModels", func() {
|
||||
|
@ -15,35 +15,34 @@
|
||||
package tend
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(headerId int64, tends []TendModel) error
|
||||
MarkHeaderChecked(headerId int64) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
}
|
||||
|
||||
type TendRepository struct {
|
||||
DB *postgres.DB
|
||||
db *postgres.DB
|
||||
}
|
||||
|
||||
func NewTendRepository(db *postgres.DB) TendRepository {
|
||||
return TendRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r TendRepository) Create(headerId int64, tends []TendModel) error {
|
||||
tx, err := r.DB.Begin()
|
||||
func (repository TendRepository) Create(headerId int64, models []interface{}) error {
|
||||
tx, err := repository.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, tend := range tends {
|
||||
|
||||
for _, model := range models {
|
||||
tend, ok := model.(TendModel)
|
||||
if !ok {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("model of type %T, not %T", model, TendModel{})
|
||||
}
|
||||
|
||||
_, err = tx.Exec(
|
||||
`INSERT into maker.tend (header_id, bid_id, lot, bid, guy, tic, tx_idx, raw_log)
|
||||
VALUES($1, $2, $3, $4, $5, $6, $7, $8)`,
|
||||
VALUES($1, $2, $3, $4, $5, $6, $7, $8)`,
|
||||
headerId, tend.BidId, tend.Lot, tend.Bid, tend.Guy, tend.Tic, tend.TransactionIndex, tend.Raw,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
@ -53,6 +52,7 @@ func (r TendRepository) Create(headerId int64, tends []TendModel) error {
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET tend_checked = $2`, headerId, true)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
@ -60,28 +60,32 @@ func (r TendRepository) Create(headerId int64, tends []TendModel) error {
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (r TendRepository) MarkHeaderChecked(headerId int64) error {
|
||||
_, err := r.DB.Exec(`INSERT INTO public.checked_headers (header_id, tend_checked)
|
||||
func (repository TendRepository) MarkHeaderChecked(headerId int64) error {
|
||||
_, err := repository.db.Exec(`INSERT INTO public.checked_headers (header_id, tend_checked)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
UPDATE SET tend_checked = $2`, headerId, true)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r TendRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
func (repository TendRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
var result []core.Header
|
||||
err := r.DB.Select(
|
||||
err := repository.db.Select(
|
||||
&result,
|
||||
`SELECT headers.id, headers.block_number FROM headers
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
LEFT JOIN checked_headers on headers.id = header_id
|
||||
WHERE (header_id ISNULL OR tend_checked IS FALSE)
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
AND headers.block_number >= $1
|
||||
AND headers.block_number <= $2
|
||||
AND headers.eth_node_fingerprint = $3`,
|
||||
startingBlockNumber,
|
||||
endingBlockNumber,
|
||||
r.DB.Node.ID,
|
||||
repository.db.Node.ID,
|
||||
)
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (repository *TendRepository) SetDB(db *postgres.DB) {
|
||||
repository.db = db
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package tend_test
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"math/rand"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
@ -32,6 +33,7 @@ var _ = Describe("TendRepository", func() {
|
||||
db *postgres.DB
|
||||
tendRepository tend.TendRepository
|
||||
headerRepository repositories.HeaderRepository
|
||||
headerId int64
|
||||
err error
|
||||
)
|
||||
|
||||
@ -40,17 +42,16 @@ var _ = Describe("TendRepository", func() {
|
||||
db = test_config.NewTestDB(node)
|
||||
test_config.CleanTestDB(db)
|
||||
headerRepository = repositories.NewHeaderRepository(db)
|
||||
tendRepository = tend.NewTendRepository(db)
|
||||
tendRepository = tend.TendRepository{}
|
||||
tendRepository.SetDB(db)
|
||||
})
|
||||
|
||||
Describe("Create", func() {
|
||||
var headerId int64
|
||||
|
||||
BeforeEach(func() {
|
||||
headerId, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err := tendRepository.Create(headerId, []tend.TendModel{test_data.TendModel})
|
||||
err = tendRepository.Create(headerId, []interface{}{test_data.TendModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -81,8 +82,7 @@ var _ = Describe("TendRepository", func() {
|
||||
})
|
||||
|
||||
It("returns an error if inserting a tend record fails", func() {
|
||||
err = tendRepository.Create(headerId, []tend.TendModel{test_data.TendModel})
|
||||
|
||||
err = tendRepository.Create(headerId, []interface{}{test_data.TendModel})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
|
||||
})
|
||||
@ -100,11 +100,15 @@ var _ = Describe("TendRepository", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(count).To(Equal(0))
|
||||
})
|
||||
|
||||
It("Returns an error if model is of wrong type", func() {
|
||||
err = tendRepository.Create(headerId, []interface{}{test_data.WrongModel{}})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("model of type"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MarkHeaderChecked", func() {
|
||||
var headerId int64
|
||||
|
||||
BeforeEach(func() {
|
||||
headerId, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@ -140,7 +144,7 @@ var _ = Describe("TendRepository", func() {
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
tendBlock = GinkgoRandomSeed()
|
||||
tendBlock = rand.Int63()
|
||||
startingBlock = tendBlock - 1
|
||||
endingBlock = tendBlock + 1
|
||||
outOfRangeBlock = tendBlock + 2
|
||||
@ -182,7 +186,8 @@ var _ = Describe("TendRepository", func() {
|
||||
node2 := core.Node{}
|
||||
db2 := test_config.NewTestDB(node2)
|
||||
headerRepository2 := repositories.NewHeaderRepository(db2)
|
||||
tendRepository2 := tend.NewTendRepository(db2)
|
||||
tendRepository2 := tend.TendRepository{}
|
||||
tendRepository2.SetDB(db2)
|
||||
|
||||
for _, number := range []int64{startingBlock, tendBlock, endingBlock} {
|
||||
headerRepository2.CreateOrUpdateHeader(fakes.GetFakeHeader(number))
|
||||
|
@ -1,88 +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 tend
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type TendTransformer struct {
|
||||
Repository Repository
|
||||
Fetcher shared.LogFetcher
|
||||
Converter Converter
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
type TendTransformerInitializer struct {
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
func (i TendTransformerInitializer) NewTendTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
converter := NewTendConverter()
|
||||
fetcher := shared.NewFetcher(blockChain)
|
||||
repository := NewTendRepository(db)
|
||||
return TendTransformer{
|
||||
Fetcher: fetcher,
|
||||
Repository: repository,
|
||||
Converter: converter,
|
||||
Config: i.Config,
|
||||
}
|
||||
}
|
||||
|
||||
func (t TendTransformer) Execute() error {
|
||||
config := t.Config
|
||||
topics := [][]common.Hash{{common.HexToHash(shared.TendFunctionSignature)}}
|
||||
|
||||
missingHeaders, err := t.Repository.MissingHeaders(config.StartingBlockNumber, config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
log.Println("Error fetching missing headers:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Fetching tend event logs for %d headers \n", len(missingHeaders))
|
||||
for _, header := range missingHeaders {
|
||||
ethLogs, err := t.Fetcher.FetchLogs(config.ContractAddresses, topics, header.BlockNumber)
|
||||
if err != nil {
|
||||
log.Println("Error fetching matching logs:", err)
|
||||
return err
|
||||
}
|
||||
if len(ethLogs) < 1 {
|
||||
err := t.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
models, err := t.Converter.ToModels(ethLogs)
|
||||
if err != nil {
|
||||
log.Println("Error converting logs:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = t.Repository.Create(header.Id, models)
|
||||
if err != nil {
|
||||
log.Println("Error persisting tend record:", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
package tend_test
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"math/rand"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@ -32,24 +33,33 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Tend Transformer", func() {
|
||||
var repository tend_mocks.MockTendRepository
|
||||
var fetcher mocks.MockLogFetcher
|
||||
var converter tend_mocks.MockTendConverter
|
||||
var transformer tend.TendTransformer
|
||||
var blockNumber1 = rand.Int63()
|
||||
var blockNumber2 = rand.Int63()
|
||||
var (
|
||||
config = tend.TendConfig
|
||||
converter tend_mocks.MockTendConverter
|
||||
repository tend_mocks.MockTendRepository
|
||||
fetcher mocks.MockLogFetcher
|
||||
transformer shared.Transformer
|
||||
headerOne core.Header
|
||||
headerTwo core.Header
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
converter = tend_mocks.MockTendConverter{}
|
||||
repository = tend_mocks.MockTendRepository{}
|
||||
fetcher = mocks.MockLogFetcher{}
|
||||
converter = tend_mocks.MockTendConverter{}
|
||||
|
||||
transformer = tend.TendTransformer{
|
||||
Repository: &repository,
|
||||
headerOne = core.Header{Id: rand.Int63(), BlockNumber: rand.Int63()}
|
||||
headerTwo = core.Header{Id: rand.Int63(), BlockNumber: rand.Int63()}
|
||||
transformer = factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Config: tend.TendConfig,
|
||||
}
|
||||
Repository: &repository,
|
||||
}.NewTransformer(nil, nil)
|
||||
})
|
||||
|
||||
It("sets the blockchain and database", func() {
|
||||
Expect(fetcher.SetBcCalled).To(BeTrue())
|
||||
Expect(repository.SetDbCalled).To(BeTrue())
|
||||
})
|
||||
|
||||
It("gets missing headers for blocks in the configured range", func() {
|
||||
@ -68,12 +78,12 @@ var _ = Describe("Tend Transformer", func() {
|
||||
})
|
||||
|
||||
It("fetches eth logs for each missing header", func() {
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: blockNumber1}, {BlockNumber: blockNumber2}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
expectedTopics := [][]common.Hash{{common.HexToHash(shared.TendFunctionSignature)}}
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{blockNumber1, blockNumber2}))
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{headerOne.BlockNumber, headerTwo.BlockNumber}))
|
||||
Expect(fetcher.FetchedTopics).To(Equal(expectedTopics))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{tend.TendConfig.ContractAddresses, tend.TendConfig.ContractAddresses}))
|
||||
})
|
||||
@ -88,34 +98,17 @@ var _ = Describe("Tend Transformer", func() {
|
||||
})
|
||||
|
||||
It("marks header checked if no logs returned", func() {
|
||||
mockConverter := &tend_mocks.MockTendConverter{}
|
||||
mockRepository := &tend_mocks.MockTendRepository{}
|
||||
headerID := int64(123)
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: headerID}})
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := tend.TendTransformer{
|
||||
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 := &tend_mocks.MockTendConverter{}
|
||||
mockRepository := &tend_mocks.MockTendRepository{}
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: int64(123)}})
|
||||
mockRepository.SetMarkHeaderCheckedErr(fakes.FakeError)
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := tend.TendTransformer{
|
||||
Converter: mockConverter,
|
||||
Fetcher: mockFetcher,
|
||||
Repository: mockRepository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetMarkHeaderCheckedErr(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -124,37 +117,37 @@ var _ = Describe("Tend Transformer", func() {
|
||||
})
|
||||
|
||||
It("converts an eth log to a Model", func() {
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.TendLogNote})
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(converter.LogsToConvert).To(Equal([]types.Log{test_data.TendLogNote}))
|
||||
Expect(converter.PassedLogs).To(Equal([]types.Log{test_data.TendLogNote}))
|
||||
})
|
||||
|
||||
It("returns an error if converter fails", func() {
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.TendLogNote})
|
||||
converter.SetConverterError(fakes.FakeError)
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(fakes.FakeError))
|
||||
})
|
||||
|
||||
It("persists the tend record", func() {
|
||||
headerId := int64(1)
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: blockNumber1, Id: headerId}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.TendLogNote})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedHeaderID).To(Equal(headerId))
|
||||
Expect(repository.PassedHeaderID).To(Equal(headerOne.Id))
|
||||
Expect(repository.PassedTendModel).To(Equal(test_data.TendModel))
|
||||
})
|
||||
|
||||
It("returns error if persisting tend record fails", func() {
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: blockNumber1}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.TendLogNote})
|
||||
repository.SetCreateError(fakes.FakeError)
|
||||
err := transformer.Execute()
|
||||
|
@ -16,20 +16,19 @@ package ilk
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/ilk"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
)
|
||||
|
||||
type MockDripFileIlkConverter struct {
|
||||
converterErr error
|
||||
PassedLogs []types.Log
|
||||
converterError error
|
||||
PassedLogs []types.Log
|
||||
}
|
||||
|
||||
func (converter *MockDripFileIlkConverter) ToModels(ethLogs []types.Log) ([]ilk.DripFileIlkModel, error) {
|
||||
func (converter *MockDripFileIlkConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
converter.PassedLogs = ethLogs
|
||||
return []ilk.DripFileIlkModel{test_data.DripFileIlkModel}, converter.converterErr
|
||||
return []interface{}{test_data.DripFileIlkModel}, converter.converterError
|
||||
}
|
||||
|
||||
func (converter *MockDripFileIlkConverter) SetConverterError(e error) {
|
||||
converter.converterErr = e
|
||||
converter.converterError = e
|
||||
}
|
||||
|
@ -16,46 +16,47 @@ package ilk
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/ilk"
|
||||
)
|
||||
|
||||
type MockDripFileIlkRepository struct {
|
||||
createErr error
|
||||
markHeaderCheckedErr error
|
||||
createError error
|
||||
markHeaderCheckedError error
|
||||
markHeaderCheckedPassedHeaderID int64
|
||||
missingHeaders []core.Header
|
||||
missingHeadersErr error
|
||||
missingHeadersError error
|
||||
PassedStartingBlockNumber int64
|
||||
PassedEndingBlockNumber int64
|
||||
PassedHeaderID int64
|
||||
PassedModels []ilk.DripFileIlkModel
|
||||
PassedModels []interface{}
|
||||
SetDbCalled bool
|
||||
}
|
||||
|
||||
func (repository *MockDripFileIlkRepository) Create(headerID int64, models []ilk.DripFileIlkModel) error {
|
||||
func (repository *MockDripFileIlkRepository) Create(headerID int64, models []interface{}) error {
|
||||
repository.PassedHeaderID = headerID
|
||||
repository.PassedModels = models
|
||||
return repository.createErr
|
||||
return repository.createError
|
||||
}
|
||||
|
||||
func (repository *MockDripFileIlkRepository) MarkHeaderChecked(headerID int64) error {
|
||||
repository.markHeaderCheckedPassedHeaderID = headerID
|
||||
return repository.markHeaderCheckedErr
|
||||
return repository.markHeaderCheckedError
|
||||
}
|
||||
|
||||
func (repository *MockDripFileIlkRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
repository.PassedStartingBlockNumber = startingBlockNumber
|
||||
repository.PassedEndingBlockNumber = endingBlockNumber
|
||||
return repository.missingHeaders, repository.missingHeadersErr
|
||||
return repository.missingHeaders, repository.missingHeadersError
|
||||
}
|
||||
|
||||
func (repository *MockDripFileIlkRepository) SetMarkHeaderCheckedErr(e error) {
|
||||
repository.markHeaderCheckedErr = e
|
||||
func (repository *MockDripFileIlkRepository) SetMarkHeaderCheckedError(e error) {
|
||||
repository.markHeaderCheckedError = e
|
||||
}
|
||||
|
||||
func (repository *MockDripFileIlkRepository) SetMissingHeadersErr(e error) {
|
||||
repository.missingHeadersErr = e
|
||||
func (repository *MockDripFileIlkRepository) SetMissingHeadersError(e error) {
|
||||
repository.missingHeadersError = e
|
||||
}
|
||||
|
||||
func (repository *MockDripFileIlkRepository) SetMissingHeaders(headers []core.Header) {
|
||||
@ -63,8 +64,12 @@ func (repository *MockDripFileIlkRepository) SetMissingHeaders(headers []core.He
|
||||
}
|
||||
|
||||
func (repository *MockDripFileIlkRepository) SetCreateError(e error) {
|
||||
repository.createErr = e
|
||||
repository.createError = e
|
||||
}
|
||||
func (repository *MockDripFileIlkRepository) AssertMarkHeaderCheckedCalledWith(i int64) {
|
||||
Expect(repository.markHeaderCheckedPassedHeaderID).To(Equal(i))
|
||||
}
|
||||
|
||||
func (repository *MockDripFileIlkRepository) SetDB(db *postgres.DB) {
|
||||
repository.SetDbCalled = true
|
||||
}
|
||||
|
@ -16,20 +16,19 @@ package repo
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/repo"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
)
|
||||
|
||||
type MockDripFileRepoConverter struct {
|
||||
converterErr error
|
||||
PassedLogs []types.Log
|
||||
converterError error
|
||||
PassedLogs []types.Log
|
||||
}
|
||||
|
||||
func (converter *MockDripFileRepoConverter) ToModels(ethLogs []types.Log) ([]repo.DripFileRepoModel, error) {
|
||||
func (converter *MockDripFileRepoConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
converter.PassedLogs = ethLogs
|
||||
return []repo.DripFileRepoModel{test_data.DripFileRepoModel}, converter.converterErr
|
||||
return []interface{}{test_data.DripFileRepoModel}, converter.converterError
|
||||
}
|
||||
|
||||
func (converter *MockDripFileRepoConverter) SetConverterError(e error) {
|
||||
converter.converterErr = e
|
||||
converter.converterError = e
|
||||
}
|
||||
|
@ -16,46 +16,47 @@ package repo
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/repo"
|
||||
)
|
||||
|
||||
type MockDripFileRepoRepository struct {
|
||||
createErr error
|
||||
markHeaderCheckedErr error
|
||||
createError error
|
||||
markHeaderCheckedError error
|
||||
markHeaderCheckedPassedHeaderID int64
|
||||
missingHeaders []core.Header
|
||||
missingHeadersErr error
|
||||
missingHeadersError error
|
||||
PassedStartingBlockNumber int64
|
||||
PassedEndingBlockNumber int64
|
||||
PassedHeaderID int64
|
||||
PassedModels []repo.DripFileRepoModel
|
||||
PassedModels []interface{}
|
||||
SetDbCalled bool
|
||||
}
|
||||
|
||||
func (repository *MockDripFileRepoRepository) Create(headerID int64, models []repo.DripFileRepoModel) error {
|
||||
func (repository *MockDripFileRepoRepository) Create(headerID int64, models []interface{}) error {
|
||||
repository.PassedHeaderID = headerID
|
||||
repository.PassedModels = models
|
||||
return repository.createErr
|
||||
return repository.createError
|
||||
}
|
||||
|
||||
func (repository *MockDripFileRepoRepository) MarkHeaderChecked(headerID int64) error {
|
||||
repository.markHeaderCheckedPassedHeaderID = headerID
|
||||
return repository.markHeaderCheckedErr
|
||||
return repository.markHeaderCheckedError
|
||||
}
|
||||
|
||||
func (repository *MockDripFileRepoRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
repository.PassedStartingBlockNumber = startingBlockNumber
|
||||
repository.PassedEndingBlockNumber = endingBlockNumber
|
||||
return repository.missingHeaders, repository.missingHeadersErr
|
||||
return repository.missingHeaders, repository.missingHeadersError
|
||||
}
|
||||
|
||||
func (repository *MockDripFileRepoRepository) SetMarkHeaderCheckedErr(e error) {
|
||||
repository.markHeaderCheckedErr = e
|
||||
func (repository *MockDripFileRepoRepository) SetMarkHeaderCheckedError(e error) {
|
||||
repository.markHeaderCheckedError = e
|
||||
}
|
||||
|
||||
func (repository *MockDripFileRepoRepository) SetMissingHeadersErr(e error) {
|
||||
repository.missingHeadersErr = e
|
||||
func (repository *MockDripFileRepoRepository) SetMissingHeadersError(e error) {
|
||||
repository.missingHeadersError = e
|
||||
}
|
||||
|
||||
func (repository *MockDripFileRepoRepository) SetMissingHeaders(headers []core.Header) {
|
||||
@ -63,8 +64,13 @@ func (repository *MockDripFileRepoRepository) SetMissingHeaders(headers []core.H
|
||||
}
|
||||
|
||||
func (repository *MockDripFileRepoRepository) SetCreateError(e error) {
|
||||
repository.createErr = e
|
||||
repository.createError = e
|
||||
}
|
||||
|
||||
func (repository *MockDripFileRepoRepository) AssertMarkHeaderCheckedCalledWith(i int64) {
|
||||
Expect(repository.markHeaderCheckedPassedHeaderID).To(Equal(i))
|
||||
}
|
||||
|
||||
func (repository *MockDripFileRepoRepository) SetDB(db *postgres.DB) {
|
||||
repository.SetDbCalled = true
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ package vow
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/vow"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
)
|
||||
|
||||
@ -25,9 +24,9 @@ type MockDripFileVowConverter struct {
|
||||
PassedLogs []types.Log
|
||||
}
|
||||
|
||||
func (converter *MockDripFileVowConverter) ToModels(ethLogs []types.Log) ([]vow.DripFileVowModel, error) {
|
||||
func (converter *MockDripFileVowConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
converter.PassedLogs = ethLogs
|
||||
return []vow.DripFileVowModel{test_data.DripFileVowModel}, converter.converterErr
|
||||
return []interface{}{test_data.DripFileVowModel}, converter.converterErr
|
||||
}
|
||||
|
||||
func (converter *MockDripFileVowConverter) SetConverterError(e error) {
|
||||
|
@ -16,46 +16,47 @@ package vow
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/vow"
|
||||
)
|
||||
|
||||
type MockDripFileVowRepository struct {
|
||||
createErr error
|
||||
markHeaderCheckedErr error
|
||||
createError error
|
||||
markHeaderCheckedError error
|
||||
markHeaderCheckedPassedHeaderID int64
|
||||
missingHeaders []core.Header
|
||||
missingHeadersErr error
|
||||
missingHeadersError error
|
||||
PassedStartingBlockNumber int64
|
||||
PassedEndingBlockNumber int64
|
||||
PassedHeaderID int64
|
||||
PassedModels []vow.DripFileVowModel
|
||||
PassedModels []interface{}
|
||||
SetDbCalled bool
|
||||
}
|
||||
|
||||
func (repository *MockDripFileVowRepository) Create(headerID int64, models []vow.DripFileVowModel) error {
|
||||
func (repository *MockDripFileVowRepository) Create(headerID int64, models []interface{}) error {
|
||||
repository.PassedHeaderID = headerID
|
||||
repository.PassedModels = models
|
||||
return repository.createErr
|
||||
return repository.createError
|
||||
}
|
||||
|
||||
func (repository *MockDripFileVowRepository) MarkHeaderChecked(headerID int64) error {
|
||||
repository.markHeaderCheckedPassedHeaderID = headerID
|
||||
return repository.markHeaderCheckedErr
|
||||
return repository.markHeaderCheckedError
|
||||
}
|
||||
|
||||
func (repository *MockDripFileVowRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
repository.PassedStartingBlockNumber = startingBlockNumber
|
||||
repository.PassedEndingBlockNumber = endingBlockNumber
|
||||
return repository.missingHeaders, repository.missingHeadersErr
|
||||
return repository.missingHeaders, repository.missingHeadersError
|
||||
}
|
||||
|
||||
func (repository *MockDripFileVowRepository) SetMarkHeaderCheckedErr(e error) {
|
||||
repository.markHeaderCheckedErr = e
|
||||
func (repository *MockDripFileVowRepository) SetMarkHeaderCheckedError(e error) {
|
||||
repository.markHeaderCheckedError = e
|
||||
}
|
||||
|
||||
func (repository *MockDripFileVowRepository) SetMissingHeadersErr(e error) {
|
||||
repository.missingHeadersErr = e
|
||||
func (repository *MockDripFileVowRepository) SetMissingHeadersError(e error) {
|
||||
repository.missingHeadersError = e
|
||||
}
|
||||
|
||||
func (repository *MockDripFileVowRepository) SetMissingHeaders(headers []core.Header) {
|
||||
@ -63,8 +64,12 @@ func (repository *MockDripFileVowRepository) SetMissingHeaders(headers []core.He
|
||||
}
|
||||
|
||||
func (repository *MockDripFileVowRepository) SetCreateError(e error) {
|
||||
repository.createErr = e
|
||||
repository.createError = e
|
||||
}
|
||||
func (repository *MockDripFileVowRepository) AssertMarkHeaderCheckedCalledWith(i int64) {
|
||||
Expect(repository.markHeaderCheckedPassedHeaderID).To(Equal(i))
|
||||
}
|
||||
|
||||
func (repository *MockDripFileVowRepository) SetDB(db *postgres.DB) {
|
||||
repository.SetDbCalled = true
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package mocks
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
type MockLogFetcher struct {
|
||||
@ -25,6 +26,7 @@ type MockLogFetcher struct {
|
||||
FetchedBlocks []int64
|
||||
fetcherError error
|
||||
FetchedLogs []types.Log
|
||||
SetBcCalled bool
|
||||
}
|
||||
|
||||
func (mlf *MockLogFetcher) FetchLogs(contractAddresses []string, topics [][]common.Hash, blockNumber int64) ([]types.Log, error) {
|
||||
@ -35,6 +37,10 @@ func (mlf *MockLogFetcher) FetchLogs(contractAddresses []string, topics [][]comm
|
||||
return mlf.FetchedLogs, mlf.fetcherError
|
||||
}
|
||||
|
||||
func (mlf *MockLogFetcher) SetBC(bc core.BlockChain) {
|
||||
mlf.SetBcCalled = true
|
||||
}
|
||||
|
||||
func (mlf *MockLogFetcher) SetFetcherError(err error) {
|
||||
mlf.fetcherError = err
|
||||
}
|
||||
|
@ -17,20 +17,19 @@ package debt_ceiling
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
)
|
||||
|
||||
type MockPitFileDebtCeilingConverter struct {
|
||||
converterErr error
|
||||
PassedLogs []types.Log
|
||||
converterError error
|
||||
PassedLogs []types.Log
|
||||
}
|
||||
|
||||
func (converter *MockPitFileDebtCeilingConverter) ToModels(ethLogs []types.Log) ([]debt_ceiling.PitFileDebtCeilingModel, error) {
|
||||
func (converter *MockPitFileDebtCeilingConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
converter.PassedLogs = ethLogs
|
||||
return []debt_ceiling.PitFileDebtCeilingModel{test_data.PitFileDebtCeilingModel}, converter.converterErr
|
||||
return []interface{}{test_data.PitFileDebtCeilingModel}, converter.converterError
|
||||
}
|
||||
|
||||
func (converter *MockPitFileDebtCeilingConverter) SetConverterError(e error) {
|
||||
converter.converterErr = e
|
||||
converter.converterError = e
|
||||
}
|
||||
|
@ -16,46 +16,47 @@ package debt_ceiling
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling"
|
||||
)
|
||||
|
||||
type MockPitFileDebtCeilingRepository struct {
|
||||
createErr error
|
||||
markHeaderCheckedErr error
|
||||
createError error
|
||||
markHeaderCheckedError error
|
||||
markHeaderCheckedPassedHeaderID int64
|
||||
missingHeaders []core.Header
|
||||
missingHeadersErr error
|
||||
missingHeadersError error
|
||||
PassedStartingBlockNumber int64
|
||||
PassedEndingBlockNumber int64
|
||||
PassedHeaderID int64
|
||||
PassedModels []debt_ceiling.PitFileDebtCeilingModel
|
||||
PassedModels []interface{}
|
||||
SetDbCalled bool
|
||||
}
|
||||
|
||||
func (repository *MockPitFileDebtCeilingRepository) MarkHeaderChecked(headerID int64) error {
|
||||
repository.markHeaderCheckedPassedHeaderID = headerID
|
||||
return repository.markHeaderCheckedErr
|
||||
return repository.markHeaderCheckedError
|
||||
}
|
||||
|
||||
func (repository *MockPitFileDebtCeilingRepository) Create(headerID int64, models []debt_ceiling.PitFileDebtCeilingModel) error {
|
||||
func (repository *MockPitFileDebtCeilingRepository) Create(headerID int64, models []interface{}) error {
|
||||
repository.PassedHeaderID = headerID
|
||||
repository.PassedModels = models
|
||||
return repository.createErr
|
||||
return repository.createError
|
||||
}
|
||||
|
||||
func (repository *MockPitFileDebtCeilingRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
repository.PassedStartingBlockNumber = startingBlockNumber
|
||||
repository.PassedEndingBlockNumber = endingBlockNumber
|
||||
return repository.missingHeaders, repository.missingHeadersErr
|
||||
return repository.missingHeaders, repository.missingHeadersError
|
||||
}
|
||||
|
||||
func (repository *MockPitFileDebtCeilingRepository) SetMarkHeaderCheckedErr(e error) {
|
||||
repository.markHeaderCheckedErr = e
|
||||
func (repository *MockPitFileDebtCeilingRepository) SetMarkHeaderCheckedError(e error) {
|
||||
repository.markHeaderCheckedError = e
|
||||
}
|
||||
|
||||
func (repository *MockPitFileDebtCeilingRepository) SetMissingHeadersErr(e error) {
|
||||
repository.missingHeadersErr = e
|
||||
func (repository *MockPitFileDebtCeilingRepository) SetMissingHeadersError(e error) {
|
||||
repository.missingHeadersError = e
|
||||
}
|
||||
|
||||
func (repository *MockPitFileDebtCeilingRepository) SetMissingHeaders(headers []core.Header) {
|
||||
@ -63,9 +64,13 @@ func (repository *MockPitFileDebtCeilingRepository) SetMissingHeaders(headers []
|
||||
}
|
||||
|
||||
func (repository *MockPitFileDebtCeilingRepository) SetCreateError(e error) {
|
||||
repository.createErr = e
|
||||
repository.createError = e
|
||||
}
|
||||
|
||||
func (repository *MockPitFileDebtCeilingRepository) AssertMarkHeaderCheckedCalledWith(i int64) {
|
||||
Expect(repository.markHeaderCheckedPassedHeaderID).To(Equal(i))
|
||||
}
|
||||
|
||||
func (repository *MockPitFileDebtCeilingRepository) SetDB(db *postgres.DB) {
|
||||
repository.SetDbCalled = true
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ package ilk
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/ilk"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
)
|
||||
|
||||
@ -30,7 +29,7 @@ func (converter *MockPitFileIlkConverter) SetConverterError(err error) {
|
||||
converter.converterError = err
|
||||
}
|
||||
|
||||
func (converter *MockPitFileIlkConverter) ToModels(ethLogs []types.Log) ([]ilk.PitFileIlkModel, error) {
|
||||
func (converter *MockPitFileIlkConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
converter.PassedLogs = ethLogs
|
||||
return []ilk.PitFileIlkModel{test_data.PitFileIlkModel}, converter.converterError
|
||||
return []interface{}{test_data.PitFileIlkModel}, converter.converterError
|
||||
}
|
||||
|
@ -16,40 +16,41 @@ package ilk
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/ilk"
|
||||
)
|
||||
|
||||
type MockPitFileIlkRepository struct {
|
||||
createError error
|
||||
PassedEndingBlockNumber int64
|
||||
PassedModels []ilk.PitFileIlkModel
|
||||
PassedModels []interface{}
|
||||
PassedHeaderID int64
|
||||
PassedStartingBlockNumber int64
|
||||
markHeaderCheckedErr error
|
||||
markHeaderCheckedError error
|
||||
markHeaderCheckedPassedHeaderID int64
|
||||
missingHeaders []core.Header
|
||||
missingHeadersErr error
|
||||
missingHeadersError error
|
||||
SetDbCalled bool
|
||||
}
|
||||
|
||||
func (repository *MockPitFileIlkRepository) SetCreateError(err error) {
|
||||
repository.createError = err
|
||||
}
|
||||
|
||||
func (repository *MockPitFileIlkRepository) SetMarkHeaderCheckedErr(e error) {
|
||||
repository.markHeaderCheckedErr = e
|
||||
func (repository *MockPitFileIlkRepository) SetMarkHeaderCheckedError(e error) {
|
||||
repository.markHeaderCheckedError = e
|
||||
}
|
||||
|
||||
func (repository *MockPitFileIlkRepository) SetMissingHeadersErr(err error) {
|
||||
repository.missingHeadersErr = err
|
||||
func (repository *MockPitFileIlkRepository) SetMissingHeadersError(err error) {
|
||||
repository.missingHeadersError = err
|
||||
}
|
||||
|
||||
func (repository *MockPitFileIlkRepository) SetMissingHeaders(headers []core.Header) {
|
||||
repository.missingHeaders = headers
|
||||
}
|
||||
|
||||
func (repository *MockPitFileIlkRepository) Create(headerID int64, models []ilk.PitFileIlkModel) error {
|
||||
func (repository *MockPitFileIlkRepository) Create(headerID int64, models []interface{}) error {
|
||||
repository.PassedHeaderID = headerID
|
||||
repository.PassedModels = models
|
||||
return repository.createError
|
||||
@ -57,15 +58,19 @@ func (repository *MockPitFileIlkRepository) Create(headerID int64, models []ilk.
|
||||
|
||||
func (repository *MockPitFileIlkRepository) MarkHeaderChecked(headerID int64) error {
|
||||
repository.markHeaderCheckedPassedHeaderID = headerID
|
||||
return repository.markHeaderCheckedErr
|
||||
return repository.markHeaderCheckedError
|
||||
}
|
||||
|
||||
func (repository *MockPitFileIlkRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
repository.PassedStartingBlockNumber = startingBlockNumber
|
||||
repository.PassedEndingBlockNumber = endingBlockNumber
|
||||
return repository.missingHeaders, repository.missingHeadersErr
|
||||
return repository.missingHeaders, repository.missingHeadersError
|
||||
}
|
||||
|
||||
func (repository *MockPitFileIlkRepository) AssertMarkHeaderCheckedCalledWith(i int64) {
|
||||
Expect(repository.markHeaderCheckedPassedHeaderID).To(Equal(i))
|
||||
}
|
||||
|
||||
func (repository *MockPitFileIlkRepository) SetDB(db *postgres.DB) {
|
||||
repository.SetDbCalled = true
|
||||
}
|
||||
|
@ -17,20 +17,19 @@ package stability_fee
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/stability_fee"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
)
|
||||
|
||||
type MockPitFileStabilityFeeConverter struct {
|
||||
converterErr error
|
||||
PassedLogs []types.Log
|
||||
converterError error
|
||||
PassedLogs []types.Log
|
||||
}
|
||||
|
||||
func (converter *MockPitFileStabilityFeeConverter) ToModels(ethLogs []types.Log) ([]stability_fee.PitFileStabilityFeeModel, error) {
|
||||
func (converter *MockPitFileStabilityFeeConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
converter.PassedLogs = ethLogs
|
||||
return []stability_fee.PitFileStabilityFeeModel{test_data.PitFileStabilityFeeModel}, converter.converterErr
|
||||
return []interface{}{test_data.PitFileStabilityFeeModel}, converter.converterError
|
||||
}
|
||||
|
||||
func (converter *MockPitFileStabilityFeeConverter) SetConverterError(e error) {
|
||||
converter.converterErr = e
|
||||
converter.converterError = e
|
||||
}
|
||||
|
@ -16,46 +16,47 @@ package stability_fee
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/stability_fee"
|
||||
)
|
||||
|
||||
type MockPitFileStabilityFeeRepository struct {
|
||||
createErr error
|
||||
markHeaderCheckedErr error
|
||||
createError error
|
||||
markHeaderCheckedError error
|
||||
markHeaderCheckedPassedHeaderID int64
|
||||
missingHeaders []core.Header
|
||||
missingHeadersErr error
|
||||
missingHeadersError error
|
||||
PassedStartingBlockNumber int64
|
||||
PassedEndingBlockNumber int64
|
||||
PassedHeaderID int64
|
||||
PassedModels []stability_fee.PitFileStabilityFeeModel
|
||||
PassedModels []interface{}
|
||||
SetDbCalled bool
|
||||
}
|
||||
|
||||
func (repository *MockPitFileStabilityFeeRepository) Create(headerID int64, models []stability_fee.PitFileStabilityFeeModel) error {
|
||||
func (repository *MockPitFileStabilityFeeRepository) Create(headerID int64, models []interface{}) error {
|
||||
repository.PassedModels = models
|
||||
repository.PassedHeaderID = headerID
|
||||
return repository.createErr
|
||||
return repository.createError
|
||||
}
|
||||
|
||||
func (repository *MockPitFileStabilityFeeRepository) MarkHeaderChecked(headerID int64) error {
|
||||
repository.markHeaderCheckedPassedHeaderID = headerID
|
||||
return repository.markHeaderCheckedErr
|
||||
return repository.markHeaderCheckedError
|
||||
}
|
||||
|
||||
func (repository *MockPitFileStabilityFeeRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
repository.PassedStartingBlockNumber = startingBlockNumber
|
||||
repository.PassedEndingBlockNumber = endingBlockNumber
|
||||
return repository.missingHeaders, repository.missingHeadersErr
|
||||
return repository.missingHeaders, repository.missingHeadersError
|
||||
}
|
||||
|
||||
func (repository *MockPitFileStabilityFeeRepository) SetMarkHeaderCheckedErr(e error) {
|
||||
repository.markHeaderCheckedErr = e
|
||||
repository.markHeaderCheckedError = e
|
||||
}
|
||||
|
||||
func (repository *MockPitFileStabilityFeeRepository) SetMissingHeadersErr(e error) {
|
||||
repository.missingHeadersErr = e
|
||||
repository.missingHeadersError = e
|
||||
}
|
||||
|
||||
func (repository *MockPitFileStabilityFeeRepository) SetMissingHeaders(headers []core.Header) {
|
||||
@ -63,9 +64,13 @@ func (repository *MockPitFileStabilityFeeRepository) SetMissingHeaders(headers [
|
||||
}
|
||||
|
||||
func (repository *MockPitFileStabilityFeeRepository) SetCreateError(e error) {
|
||||
repository.createErr = e
|
||||
repository.createError = e
|
||||
}
|
||||
|
||||
func (repository *MockPitFileStabilityFeeRepository) AssertMarkHeaderCheckedCalledWith(i int64) {
|
||||
Expect(repository.markHeaderCheckedPassedHeaderID).To(Equal(i))
|
||||
}
|
||||
|
||||
func (repository *MockPitFileStabilityFeeRepository) SetDB(db *postgres.DB) {
|
||||
repository.SetDbCalled = true
|
||||
}
|
||||
|
@ -17,20 +17,19 @@ package tend
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/tend"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
)
|
||||
|
||||
type MockTendConverter struct {
|
||||
LogsToConvert []types.Log
|
||||
PassedLogs []types.Log
|
||||
ConverterError error
|
||||
}
|
||||
|
||||
func (c *MockTendConverter) ToModels(ethLogs []types.Log) ([]tend.TendModel, error) {
|
||||
c.LogsToConvert = append(c.LogsToConvert, ethLogs...)
|
||||
return []tend.TendModel{test_data.TendModel}, c.ConverterError
|
||||
func (converter *MockTendConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
converter.PassedLogs = ethLogs
|
||||
return []interface{}{test_data.TendModel}, converter.ConverterError
|
||||
}
|
||||
|
||||
func (c *MockTendConverter) SetConverterError(err error) {
|
||||
c.ConverterError = err
|
||||
func (converter *MockTendConverter) SetConverterError(err error) {
|
||||
converter.ConverterError = err
|
||||
}
|
||||
|
@ -16,9 +16,9 @@ package tend
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/tend"
|
||||
)
|
||||
|
||||
type MockTendRepository struct {
|
||||
@ -26,14 +26,15 @@ type MockTendRepository struct {
|
||||
PassedEndingBlockNumber int64
|
||||
PassedHeaderID int64
|
||||
PassedStartingBlockNumber int64
|
||||
PassedTendModel tend.TendModel
|
||||
markHeaderCheckedErr error
|
||||
PassedTendModel interface{}
|
||||
markHeaderCheckedError error
|
||||
markHeaderCheckedPassedHeaderId int64
|
||||
missingHeaders []core.Header
|
||||
missingHeadersErr error
|
||||
missingHeadersError error
|
||||
SetDbCalled bool
|
||||
}
|
||||
|
||||
func (repository *MockTendRepository) Create(headerId int64, tend []tend.TendModel) error {
|
||||
func (repository *MockTendRepository) Create(headerId int64, tend []interface{}) error {
|
||||
repository.PassedHeaderID = headerId
|
||||
repository.PassedTendModel = tend[0]
|
||||
return repository.createError
|
||||
@ -44,11 +45,11 @@ func (repository *MockTendRepository) SetCreateError(err error) {
|
||||
}
|
||||
|
||||
func (repository *MockTendRepository) SetMarkHeaderCheckedErr(err error) {
|
||||
repository.markHeaderCheckedErr = err
|
||||
repository.markHeaderCheckedError = err
|
||||
}
|
||||
|
||||
func (repository *MockTendRepository) SetMissingHeadersErr(err error) {
|
||||
repository.missingHeadersErr = err
|
||||
repository.missingHeadersError = err
|
||||
}
|
||||
|
||||
func (repository *MockTendRepository) SetMissingHeaders(headers []core.Header) {
|
||||
@ -57,15 +58,19 @@ func (repository *MockTendRepository) SetMissingHeaders(headers []core.Header) {
|
||||
|
||||
func (repository *MockTendRepository) MarkHeaderChecked(headerId int64) error {
|
||||
repository.markHeaderCheckedPassedHeaderId = headerId
|
||||
return repository.markHeaderCheckedErr
|
||||
return repository.markHeaderCheckedError
|
||||
}
|
||||
|
||||
func (repository *MockTendRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
repository.PassedStartingBlockNumber = startingBlockNumber
|
||||
repository.PassedEndingBlockNumber = endingBlockNumber
|
||||
return repository.missingHeaders, repository.missingHeadersErr
|
||||
return repository.missingHeaders, repository.missingHeadersError
|
||||
}
|
||||
|
||||
func (repository *MockTendRepository) AssertMarkHeaderCheckedCalledWith(headerId int64) {
|
||||
Expect(repository.markHeaderCheckedPassedHeaderId).To(Equal(headerId))
|
||||
}
|
||||
|
||||
func (repository *MockTendRepository) SetDB(db *postgres.DB) {
|
||||
repository.SetDbCalled = true
|
||||
}
|
||||
|
@ -18,19 +18,18 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_init"
|
||||
)
|
||||
|
||||
type MockVatInitConverter struct {
|
||||
converterErr error
|
||||
PassedLogs []types.Log
|
||||
converterError error
|
||||
PassedLogs []types.Log
|
||||
}
|
||||
|
||||
func (converter *MockVatInitConverter) ToModels(ethLogs []types.Log) ([]vat_init.VatInitModel, error) {
|
||||
func (converter *MockVatInitConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
converter.PassedLogs = ethLogs
|
||||
return []vat_init.VatInitModel{test_data.VatInitModel}, converter.converterErr
|
||||
return []interface{}{test_data.VatInitModel}, converter.converterError
|
||||
}
|
||||
|
||||
func (converter *MockVatInitConverter) SetConverterError(e error) {
|
||||
converter.converterErr = e
|
||||
converter.converterError = e
|
||||
}
|
||||
|
@ -16,46 +16,47 @@ package vat_init
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_init"
|
||||
)
|
||||
|
||||
type MockVatInitRepository struct {
|
||||
createErr error
|
||||
markHeaderCheckedErr error
|
||||
createError error
|
||||
markHeaderCheckedError error
|
||||
markHeaderCheckedPassedHeaderID int64
|
||||
missingHeaders []core.Header
|
||||
missingHeadersErr error
|
||||
missingHeadersError error
|
||||
PassedStartingBlockNumber int64
|
||||
PassedEndingBlockNumber int64
|
||||
PassedHeaderID int64
|
||||
PassedModels []vat_init.VatInitModel
|
||||
PassedModels []interface{}
|
||||
SetDbCalled bool
|
||||
}
|
||||
|
||||
func (repository *MockVatInitRepository) Create(headerID int64, models []vat_init.VatInitModel) error {
|
||||
func (repository *MockVatInitRepository) Create(headerID int64, models []interface{}) error {
|
||||
repository.PassedHeaderID = headerID
|
||||
repository.PassedModels = models
|
||||
return repository.createErr
|
||||
return repository.createError
|
||||
}
|
||||
|
||||
func (repository *MockVatInitRepository) MarkHeaderChecked(headerID int64) error {
|
||||
repository.markHeaderCheckedPassedHeaderID = headerID
|
||||
return repository.markHeaderCheckedErr
|
||||
return repository.markHeaderCheckedError
|
||||
}
|
||||
|
||||
func (repository *MockVatInitRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
|
||||
repository.PassedStartingBlockNumber = startingBlockNumber
|
||||
repository.PassedEndingBlockNumber = endingBlockNumber
|
||||
return repository.missingHeaders, repository.missingHeadersErr
|
||||
return repository.missingHeaders, repository.missingHeadersError
|
||||
}
|
||||
|
||||
func (repository *MockVatInitRepository) SetMarkHeaderCheckedErr(e error) {
|
||||
repository.markHeaderCheckedErr = e
|
||||
func (repository *MockVatInitRepository) SetMarkHeaderCheckedError(e error) {
|
||||
repository.markHeaderCheckedError = e
|
||||
}
|
||||
|
||||
func (repository *MockVatInitRepository) SetMissingHeadersErr(e error) {
|
||||
repository.missingHeadersErr = e
|
||||
func (repository *MockVatInitRepository) SetMissingHeadersError(e error) {
|
||||
repository.missingHeadersError = e
|
||||
}
|
||||
|
||||
func (repository *MockVatInitRepository) SetMissingHeaders(headers []core.Header) {
|
||||
@ -63,9 +64,13 @@ func (repository *MockVatInitRepository) SetMissingHeaders(headers []core.Header
|
||||
}
|
||||
|
||||
func (repository *MockVatInitRepository) SetCreateError(e error) {
|
||||
repository.createErr = e
|
||||
repository.createError = e
|
||||
}
|
||||
|
||||
func (repository *MockVatInitRepository) AssertMarkHeaderCheckedCalledWith(i int64) {
|
||||
Expect(repository.markHeaderCheckedPassedHeaderID).To(Equal(i))
|
||||
}
|
||||
|
||||
func (repository *MockVatInitRepository) SetDB(db *postgres.DB) {
|
||||
repository.SetDbCalled = true
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ package vat_move
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_move"
|
||||
)
|
||||
|
||||
type MockVatMoveConverter struct {
|
||||
@ -25,9 +24,9 @@ type MockVatMoveConverter struct {
|
||||
PassedLogs []types.Log
|
||||
}
|
||||
|
||||
func (converter *MockVatMoveConverter) ToModels(ethLogs []types.Log) ([]vat_move.VatMoveModel, error) {
|
||||
func (converter *MockVatMoveConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
converter.PassedLogs = ethLogs
|
||||
return []vat_move.VatMoveModel{test_data.VatMoveModel}, converter.converterError
|
||||
return []interface{}{test_data.VatMoveModel}, converter.converterError
|
||||
}
|
||||
|
||||
func (converter *MockVatMoveConverter) SetConverterError(e error) {
|
||||
|
@ -16,7 +16,7 @@ package vat_move
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_move"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type MockVatMoveRepository struct {
|
||||
@ -26,12 +26,13 @@ type MockVatMoveRepository struct {
|
||||
PassedStartingBlockNumber int64
|
||||
PassedEndingBlockNumber int64
|
||||
PassedHeaderID int64
|
||||
PassedModels []vat_move.VatMoveModel
|
||||
PassedModels []interface{}
|
||||
CheckedHeaderIDs []int64
|
||||
CheckedHeaderError error
|
||||
SetDbCalled bool
|
||||
}
|
||||
|
||||
func (repository *MockVatMoveRepository) Create(headerID int64, models []vat_move.VatMoveModel) error {
|
||||
func (repository *MockVatMoveRepository) Create(headerID int64, models []interface{}) error {
|
||||
repository.PassedHeaderID = headerID
|
||||
repository.PassedModels = models
|
||||
return repository.createError
|
||||
@ -63,3 +64,7 @@ func (repository *MockVatMoveRepository) MarkHeaderChecked(headerId int64) error
|
||||
func (repository *MockVatMoveRepository) SetCheckedHeaderError(e error) {
|
||||
repository.CheckedHeaderError = e
|
||||
}
|
||||
|
||||
func (repository *MockVatMoveRepository) SetDB(db *postgres.DB) {
|
||||
repository.SetDbCalled = true
|
||||
}
|
||||
|
17
pkg/transformers/test_data/wrong_model.go
Normal file
17
pkg/transformers/test_data/wrong_model.go
Normal file
@ -0,0 +1,17 @@
|
||||
// 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 test_data
|
||||
|
||||
type WrongModel struct{}
|
@ -23,14 +23,13 @@ import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/deal"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/dent"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_drip"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file"
|
||||
ilk2 "github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/ilk"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/repo"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/vow"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/flop_kick"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/frob"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/ilk"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/stability_fee"
|
||||
@ -49,36 +48,86 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
BiteTransformerInitializer = bite.BiteTransformerInitializer{Config: bite.BiteConfig}.NewBiteTransformer
|
||||
catFileConfig = cat_file.CatFileConfig
|
||||
CatFileChopLumpTransformerInitializer = chop_lump.CatFileChopLumpTransformerInitializer{Config: catFileConfig}.NewCatFileChopLumpTransformer
|
||||
CatFileFlipTransformerInitializer = flip.CatFileFlipTransformerInitializer{Config: catFileConfig}.NewCatFileFlipTransformer
|
||||
CatFilePitVowTransformerInitializer = pit_vow.CatFilePitVowTransformerInitializer{Config: catFileConfig}.NewCatFilePitVowTransformer
|
||||
DealTransformerInitializer = deal.DealTransformerInitializer{Config: deal.Config}.NewDealTransformer
|
||||
DentTransformerInitializer = dent.DentTransformerInitializer{Config: dent.DentConfig}.NewDentTransformer
|
||||
DripDripTransformerInitializer = drip_drip.DripDripTransformerInitializer{Config: drip_drip.DripDripConfig}.NewDripDripTransformer
|
||||
dripFileConfig = drip_file.DripFileConfig
|
||||
DripFileIlkTransformerInitializer = ilk2.DripFileIlkTransformerInitializer{Config: dripFileConfig}.NewDripFileIlkTransformer
|
||||
DripFileRepoTransformerInitializer = repo.DripFileRepoTransformerInitializer{Config: dripFileConfig}.NewDripFileRepoTransformer
|
||||
DripFileVowTransfromerInitializer = vow.DripFileVowTransformerInitializer{Config: dripFileConfig}.NewDripFileVowTransformer
|
||||
FlipKickTransformerInitializer = flip_kick.FlipKickTransformerInitializer{Config: flip_kick.FlipKickConfig}.NewFlipKickTransformer
|
||||
FlopKickTransformerInitializer = flop_kick.FlopKickTransformerInitializer{Config: flop_kick.Config}.NewFlopKickTransformer
|
||||
FrobTransformerInitializer = frob.FrobTransformerInitializer{Config: frob.FrobConfig}.NewFrobTransformer
|
||||
pitFileConfig = pit_file.PitFileConfig
|
||||
PitFileDebtCeilingTransformerInitializer = debt_ceiling.PitFileDebtCeilingTransformerInitializer{Config: pitFileConfig}.NewPitFileDebtCeilingTransformer
|
||||
PitFileIlkTransformerInitializer = ilk.PitFileIlkTransformerInitializer{Config: pitFileConfig}.NewPitFileIlkTransformer
|
||||
PitFileStabilityFeeTransformerInitializer = stability_fee.PitFileStabilityFeeTransformerInitializer{Config: pitFileConfig}.NewPitFileStabilityFeeTransformer
|
||||
PriceFeedTransformerInitializer = price_feeds.PriceFeedTransformerInitializer{Config: price_feeds.PriceFeedConfig}.NewPriceFeedTransformer
|
||||
TendTransformerInitializer = tend.TendTransformerInitializer{Config: tend.TendConfig}.NewTendTransformer
|
||||
VatGrabTransformerInitializer = vat_grab.VatGrabTransformerInitializer{Config: vat_grab.VatGrabConfig}.NewVatGrabTransformer
|
||||
VatInitTransformerInitializer = vat_init.VatInitTransformerInitializer{Config: vat_init.VatInitConfig}.NewVatInitTransformer
|
||||
VatMoveTransformerInitializer = vat_move.VatMoveTransformerInitializer{Config: vat_move.VatMoveConfig}.NewVatMoveTransformer
|
||||
VatHealTransformerInitializer = vat_heal.VatHealTransformerInitializer{Config: vat_heal.VatHealConfig}.NewVatHealTransformer
|
||||
VatFoldTransformerInitializer = vat_fold.VatFoldTransformerInitializer{Config: vat_fold.VatFoldConfig}.NewVatFoldTransformer
|
||||
VatSlipTransformerInitializer = vat_slip.VatSlipTransformerInitializer{Config: vat_slip.VatSlipConfig}.NewVatSlipTransformer
|
||||
VatTollTransformerInitializer = vat_toll.VatTollTransformerInitializer{Config: vat_toll.VatTollConfig}.NewVatTollTransformer
|
||||
VatTuneTransformerInitializer = vat_tune.VatTuneTransformerInitializer{Config: vat_tune.VatTuneConfig}.NewVatTuneTransformer
|
||||
VatFluxTransformerInitializer = vat_flux.VatFluxTransformerInitializer{Config: vat_flux.VatFluxConfig}.NewVatFluxTransformer
|
||||
BiteTransformerInitializer = bite.BiteTransformerInitializer{Config: bite.BiteConfig}.NewBiteTransformer
|
||||
catFileConfig = cat_file.CatFileConfig
|
||||
CatFileChopLumpTransformerInitializer = chop_lump.CatFileChopLumpTransformerInitializer{Config: catFileConfig}.NewCatFileChopLumpTransformer
|
||||
CatFileFlipTransformerInitializer = flip.CatFileFlipTransformerInitializer{Config: catFileConfig}.NewCatFileFlipTransformer
|
||||
CatFilePitVowTransformerInitializer = pit_vow.CatFilePitVowTransformerInitializer{Config: catFileConfig}.NewCatFilePitVowTransformer
|
||||
DealTransformerInitializer = deal.DealTransformerInitializer{Config: deal.Config}.NewDealTransformer
|
||||
DentTransformerInitializer = dent.DentTransformerInitializer{Config: dent.DentConfig}.NewDentTransformer
|
||||
DripDripTransformerInitializer = drip_drip.DripDripTransformerInitializer{Config: drip_drip.DripDripConfig}.NewDripDripTransformer
|
||||
DripFileIlkTransformerInitializer = factories.Transformer{
|
||||
Config: ilk2.DripFileIlkConfig,
|
||||
Converter: &ilk2.DripFileIlkConverter{},
|
||||
Repository: &ilk2.DripFileIlkRepository{},
|
||||
Fetcher: &shared.Fetcher{},
|
||||
}.NewTransformer
|
||||
|
||||
DripFileRepoTransformerInitializer = factories.Transformer{
|
||||
Config: repo.DripFileRepoConfig,
|
||||
Converter: &repo.DripFileRepoConverter{},
|
||||
Repository: &repo.DripFileRepoRepository{},
|
||||
Fetcher: &shared.Fetcher{},
|
||||
}.NewTransformer
|
||||
|
||||
DripFileVowTransfromerInitializer = factories.Transformer{
|
||||
Config: vow.DripFileVowConfig,
|
||||
Converter: &vow.DripFileVowConverter{},
|
||||
Repository: &vow.DripFileVowRepository{},
|
||||
Fetcher: &shared.Fetcher{},
|
||||
}.NewTransformer
|
||||
|
||||
FlipKickTransformerInitializer = flip_kick.FlipKickTransformerInitializer{Config: flip_kick.FlipKickConfig}.NewFlipKickTransformer
|
||||
FlopKickTransformerInitializer = flop_kick.FlopKickTransformerInitializer{Config: flop_kick.Config}.NewFlopKickTransformer
|
||||
FrobTransformerInitializer = frob.FrobTransformerInitializer{Config: frob.FrobConfig}.NewFrobTransformer
|
||||
PitFileDebtCeilingTransformerInitializer = factories.Transformer{
|
||||
Config: debt_ceiling.DebtCeilingFileConfig,
|
||||
Converter: &debt_ceiling.PitFileDebtCeilingConverter{},
|
||||
Repository: &debt_ceiling.PitFileDebtCeilingRepository{},
|
||||
Fetcher: &shared.Fetcher{},
|
||||
}.NewTransformer
|
||||
|
||||
PitFileIlkTransformerInitializer = factories.Transformer{
|
||||
Config: ilk.IlkFileConfig,
|
||||
Converter: &ilk.PitFileIlkConverter{},
|
||||
Repository: &ilk.PitFileIlkRepository{},
|
||||
Fetcher: &shared.Fetcher{},
|
||||
}.NewTransformer
|
||||
|
||||
PitFileStabilityFeeTransformerInitializer = factories.Transformer{
|
||||
Config: stability_fee.StabilityFeeFileConfig,
|
||||
Converter: &stability_fee.PitFileStabilityFeeConverter{},
|
||||
Repository: &stability_fee.PitFileStabilityFeeRepository{},
|
||||
Fetcher: &shared.Fetcher{},
|
||||
}.NewTransformer
|
||||
|
||||
PriceFeedTransformerInitializer = price_feeds.PriceFeedTransformerInitializer{Config: price_feeds.PriceFeedConfig}.NewPriceFeedTransformer
|
||||
TendTransformerInitializer = factories.Transformer{
|
||||
Config: tend.TendConfig,
|
||||
Converter: &tend.TendConverter{},
|
||||
Repository: &tend.TendRepository{},
|
||||
Fetcher: &shared.Fetcher{},
|
||||
}.NewTransformer
|
||||
|
||||
VatInitTransformerInitializer = factories.Transformer{
|
||||
Config: vat_init.VatInitConfig,
|
||||
Converter: &vat_init.VatInitConverter{},
|
||||
Repository: &vat_init.VatInitRepository{},
|
||||
Fetcher: &shared.Fetcher{},
|
||||
}.NewTransformer
|
||||
VatGrabTransformerInitializer = vat_grab.VatGrabTransformerInitializer{Config: vat_grab.VatGrabConfig}.NewVatGrabTransformer
|
||||
VatHealTransformerInitializer = vat_heal.VatHealTransformerInitializer{Config: vat_heal.VatHealConfig}.NewVatHealTransformer
|
||||
VatFoldTransformerInitializer = vat_fold.VatFoldTransformerInitializer{Config: vat_fold.VatFoldConfig}.NewVatFoldTransformer
|
||||
VatMoveTransformerInitializer = factories.Transformer{
|
||||
Config: vat_move.VatMoveConfig,
|
||||
Converter: &vat_move.VatMoveConverter{},
|
||||
Repository: &vat_move.VatMoveRepository{},
|
||||
Fetcher: &shared.Fetcher{},
|
||||
}.NewTransformer
|
||||
VatSlipTransformerInitializer = vat_slip.VatSlipTransformerInitializer{Config: vat_slip.VatSlipConfig}.NewVatSlipTransformer
|
||||
VatTollTransformerInitializer = vat_toll.VatTollTransformerInitializer{Config: vat_toll.VatTollConfig}.NewVatTollTransformer
|
||||
VatTuneTransformerInitializer = vat_tune.VatTuneTransformerInitializer{Config: vat_tune.VatTuneConfig}.NewVatTuneTransformer
|
||||
VatFluxTransformerInitializer = vat_flux.VatFluxTransformerInitializer{Config: vat_flux.VatFluxConfig}.NewVatFluxTransformer
|
||||
)
|
||||
|
||||
func TransformerInitializers() []shared.TransformerInitializer {
|
||||
|
@ -18,10 +18,11 @@ import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
var VatInitConfig = shared.TransformerConfig{
|
||||
var VatInitConfig = shared.SingleTransformerConfig{
|
||||
TransformerName: shared.VatInitLabel,
|
||||
ContractAddresses: []string{shared.VatContractAddress},
|
||||
ContractAbi: shared.VatABI,
|
||||
Topics: []string{shared.VatInitSignature},
|
||||
Topic: shared.VatInitSignature,
|
||||
StartingBlockNumber: 0,
|
||||
EndingBlockNumber: 10000000,
|
||||
}
|
||||
|
@ -18,18 +18,13 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
type Converter interface {
|
||||
ToModels(ethLogs []types.Log) ([]VatInitModel, error)
|
||||
}
|
||||
|
||||
type VatInitConverter struct{}
|
||||
|
||||
func (VatInitConverter) ToModels(ethLogs []types.Log) ([]VatInitModel, error) {
|
||||
var models []VatInitModel
|
||||
func (VatInitConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
var models []interface{}
|
||||
for _, ethLog := range ethLogs {
|
||||
err := verifyLog(ethLog)
|
||||
if err != nil {
|
||||
|
@ -24,18 +24,20 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Vat init converter", func() {
|
||||
It("returns err if log missing topics", func() {
|
||||
converter := vat_init.VatInitConverter{}
|
||||
badLog := types.Log{}
|
||||
var converter vat_init.VatInitConverter
|
||||
|
||||
BeforeEach(func() {
|
||||
converter = vat_init.VatInitConverter{}
|
||||
})
|
||||
|
||||
It("returns err if log missing topics", func() {
|
||||
badLog := types.Log{}
|
||||
_, err := converter.ToModels([]types.Log{badLog})
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("converts a log to an model", func() {
|
||||
converter := vat_init.VatInitConverter{}
|
||||
|
||||
models, err := converter.ToModels([]types.Log{test_data.EthVatInitLog})
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -15,42 +15,42 @@
|
||||
package vat_init
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(headerID int64, models []VatInitModel) error
|
||||
MarkHeaderChecked(headerID int64) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
}
|
||||
|
||||
type VatInitRepository struct {
|
||||
db *postgres.DB
|
||||
}
|
||||
|
||||
func NewVatInitRepository(db *postgres.DB) VatInitRepository {
|
||||
return VatInitRepository{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (repository VatInitRepository) Create(headerID int64, models []VatInitModel) error {
|
||||
func (repository VatInitRepository) Create(headerID int64, models []interface{}) error {
|
||||
tx, err := repository.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, model := range models {
|
||||
vatInit, ok := model.(VatInitModel)
|
||||
if !ok {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("model of type %T, not %T", model, VatInitModel{})
|
||||
}
|
||||
|
||||
log.Printf("VatInit model: %v", vatInit)
|
||||
_, err = tx.Exec(
|
||||
`INSERT into maker.vat_init (header_id, ilk, tx_idx, raw_log)
|
||||
VALUES($1, $2, $3, $4)`,
|
||||
headerID, model.Ilk, model.TransactionIndex, model.Raw,
|
||||
`INSERT INTO maker.vat_init (header_id, ilk, tx_idx, raw_log)
|
||||
VALUES($1, $2, $3, $4)`,
|
||||
headerID, vatInit.Ilk, vatInit.TransactionIndex, vatInit.Raw,
|
||||
)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
log.Printf("Error: %v \n", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, vat_init_checked)
|
||||
VALUES($1, $2)
|
||||
ON CONFLICT (header_id) DO
|
||||
@ -87,3 +87,7 @@ func (repository VatInitRepository) MissingHeaders(startingBlockNumber, endingBl
|
||||
)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (repository *VatInitRepository) SetDB(db *postgres.DB) {
|
||||
repository.db = db
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package vat_init_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"math/rand"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@ -32,7 +33,7 @@ import (
|
||||
var _ = Describe("Vat init repository", func() {
|
||||
var (
|
||||
db *postgres.DB
|
||||
vatInitRepository vat_init.Repository
|
||||
vatInitRepository vat_init.VatInitRepository
|
||||
headerRepository repositories.HeaderRepository
|
||||
err error
|
||||
)
|
||||
@ -40,7 +41,8 @@ var _ = Describe("Vat init repository", func() {
|
||||
BeforeEach(func() {
|
||||
db = test_config.NewTestDB(core.Node{})
|
||||
test_config.CleanTestDB(db)
|
||||
vatInitRepository = vat_init.NewVatInitRepository(db)
|
||||
vatInitRepository = vat_init.VatInitRepository{}
|
||||
vatInitRepository.SetDB(db)
|
||||
headerRepository = repositories.NewHeaderRepository(db)
|
||||
})
|
||||
|
||||
@ -51,13 +53,13 @@ var _ = Describe("Vat init repository", func() {
|
||||
headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = vatInitRepository.Create(headerID, []vat_init.VatInitModel{test_data.VatInitModel})
|
||||
err = vatInitRepository.Create(headerID, []interface{}{test_data.VatInitModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("adds a vat event", func() {
|
||||
var dbVatInit vat_init.VatInitModel
|
||||
err = db.Get(&dbVatInit, `SELECT ilk,tx_idx, raw_log FROM maker.vat_init WHERE header_id = $1`, headerID)
|
||||
err = db.Get(&dbVatInit, `SELECT ilk, tx_idx, raw_log FROM maker.vat_init WHERE header_id = $1`, headerID)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(dbVatInit.Ilk).To(Equal(test_data.VatInitModel.Ilk))
|
||||
Expect(dbVatInit.TransactionIndex).To(Equal(test_data.VatInitModel.TransactionIndex))
|
||||
@ -65,7 +67,7 @@ var _ = Describe("Vat init repository", func() {
|
||||
})
|
||||
|
||||
It("does not duplicate vat events", func() {
|
||||
err = vatInitRepository.Create(headerID, []vat_init.VatInitModel{test_data.VatInitModel})
|
||||
err = vatInitRepository.Create(headerID, []interface{}{test_data.VatInitModel})
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
|
||||
@ -87,6 +89,12 @@ var _ = Describe("Vat init repository", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(headerChecked).To(BeTrue())
|
||||
})
|
||||
|
||||
It("Returns an error if model is of wrong type", func() {
|
||||
err = vatInitRepository.Create(headerID, []interface{}{test_data.WrongModel{}})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("model of type"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MarkHeaderChecked", func() {
|
||||
@ -95,7 +103,6 @@ var _ = Describe("Vat init repository", func() {
|
||||
BeforeEach(func() {
|
||||
headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
})
|
||||
|
||||
It("creates a row for a new headerID", func() {
|
||||
@ -128,7 +135,7 @@ var _ = Describe("Vat init repository", func() {
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
startingBlock = GinkgoRandomSeed()
|
||||
startingBlock = rand.Int63()
|
||||
vatInitBlock = startingBlock + 1
|
||||
endingBlock = startingBlock + 2
|
||||
|
||||
@ -174,8 +181,10 @@ var _ = Describe("Vat init repository", func() {
|
||||
_, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
vatInitRepositoryTwo := vat_init.NewVatInitRepository(dbTwo)
|
||||
err := vatInitRepository.MarkHeaderChecked(headerIDs[0])
|
||||
|
||||
vatInitRepositoryTwo := vat_init.VatInitRepository{}
|
||||
vatInitRepositoryTwo.SetDB(dbTwo)
|
||||
err = vatInitRepository.MarkHeaderChecked(headerIDs[0])
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
nodeOneMissingHeaders, err := vatInitRepository.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1])
|
||||
|
@ -1,78 +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 vat_init
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type VatInitTransformerInitializer struct {
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
func (initializer VatInitTransformerInitializer) NewVatInitTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
converter := VatInitConverter{}
|
||||
fetcher := shared.NewFetcher(blockChain)
|
||||
repository := NewVatInitRepository(db)
|
||||
return VatInitTransformer{
|
||||
Config: initializer.Config,
|
||||
Converter: converter,
|
||||
Fetcher: fetcher,
|
||||
Repository: repository,
|
||||
}
|
||||
}
|
||||
|
||||
type VatInitTransformer struct {
|
||||
Config shared.TransformerConfig
|
||||
Converter Converter
|
||||
Fetcher shared.LogFetcher
|
||||
Repository Repository
|
||||
}
|
||||
|
||||
func (transformer VatInitTransformer) Execute() error {
|
||||
missingHeaders, err := transformer.Repository.MissingHeaders(transformer.Config.StartingBlockNumber, transformer.Config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Fetching vat init event logs for %d headers \n", len(missingHeaders))
|
||||
for _, header := range missingHeaders {
|
||||
topics := [][]common.Hash{{common.HexToHash(shared.VatInitSignature)}}
|
||||
matchingLogs, err := transformer.Fetcher.FetchLogs(VatInitConfig.ContractAddresses, topics, header.BlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(matchingLogs) < 1 {
|
||||
err = transformer.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
models, err := transformer.Converter.ToModels(matchingLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = transformer.Repository.Create(header.Id, models)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -19,6 +19,8 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
|
||||
"math/rand"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
@ -30,15 +32,36 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Vat init transformer", func() {
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
repository := &vat_init_mocks.MockVatInitRepository{}
|
||||
transformer := vat_init.VatInitTransformer{
|
||||
Config: vat_init.VatInitConfig,
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &vat_init_mocks.MockVatInitConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
var (
|
||||
config = vat_init.VatInitConfig
|
||||
converter vat_init_mocks.MockVatInitConverter
|
||||
repository vat_init_mocks.MockVatInitRepository
|
||||
fetcher mocks.MockLogFetcher
|
||||
transformer shared.Transformer
|
||||
headerOne core.Header
|
||||
headerTwo core.Header
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
converter = vat_init_mocks.MockVatInitConverter{}
|
||||
repository = vat_init_mocks.MockVatInitRepository{}
|
||||
fetcher = mocks.MockLogFetcher{}
|
||||
headerOne = core.Header{Id: rand.Int63(), BlockNumber: rand.Int63()}
|
||||
headerTwo = core.Header{Id: rand.Int63(), BlockNumber: rand.Int63()}
|
||||
transformer = factories.Transformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}.NewTransformer(nil, nil)
|
||||
})
|
||||
|
||||
It("sets the blockchain and database", func() {
|
||||
Expect(fetcher.SetBcCalled).To(BeTrue())
|
||||
Expect(repository.SetDbCalled).To(BeTrue())
|
||||
})
|
||||
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@ -47,13 +70,7 @@ var _ = Describe("Vat init transformer", func() {
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for missing headers", func() {
|
||||
repository := &vat_init_mocks.MockVatInitRepository{}
|
||||
repository.SetMissingHeadersErr(fakes.FakeError)
|
||||
transformer := vat_init.VatInitTransformer{
|
||||
Fetcher: &mocks.MockLogFetcher{},
|
||||
Converter: &vat_init_mocks.MockVatInitConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeadersError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -62,33 +79,20 @@ var _ = Describe("Vat init transformer", func() {
|
||||
})
|
||||
|
||||
It("fetches logs for missing headers", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
repository := &vat_init_mocks.MockVatInitRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}, {BlockNumber: 2}})
|
||||
transformer := vat_init.VatInitTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &vat_init_mocks.MockVatInitConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{1, 2}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal([][]string{vat_init.VatInitConfig.ContractAddresses, vat_init.VatInitConfig.ContractAddresses}))
|
||||
Expect(fetcher.FetchedBlocks).To(Equal([]int64{headerOne.BlockNumber, headerTwo.BlockNumber}))
|
||||
Expect(fetcher.FetchedContractAddresses).To(Equal(
|
||||
[][]string{config.ContractAddresses, config.ContractAddresses}))
|
||||
Expect(fetcher.FetchedTopics).To(Equal([][]common.Hash{{common.HexToHash(shared.VatInitSignature)}}))
|
||||
})
|
||||
|
||||
It("returns error if fetcher returns error", func() {
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetcherError(fakes.FakeError)
|
||||
repository := &vat_init_mocks.MockVatInitRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := vat_init.VatInitTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: &vat_init_mocks.MockVatInitConverter{},
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -97,34 +101,17 @@ var _ = Describe("Vat init transformer", func() {
|
||||
})
|
||||
|
||||
It("marks header checked if no logs returned", func() {
|
||||
mockConverter := &vat_init_mocks.MockVatInitConverter{}
|
||||
mockRepository := &vat_init_mocks.MockVatInitRepository{}
|
||||
headerID := int64(123)
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: headerID}})
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := vat_init.VatInitTransformer{
|
||||
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 := &vat_init_mocks.MockVatInitConverter{}
|
||||
mockRepository := &vat_init_mocks.MockVatInitRepository{}
|
||||
mockRepository.SetMissingHeaders([]core.Header{{Id: int64(123)}})
|
||||
mockRepository.SetMarkHeaderCheckedErr(fakes.FakeError)
|
||||
mockFetcher := &mocks.MockLogFetcher{}
|
||||
transformer := vat_init.VatInitTransformer{
|
||||
Converter: mockConverter,
|
||||
Fetcher: mockFetcher,
|
||||
Repository: mockRepository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetMarkHeaderCheckedError(fakes.FakeError)
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -133,16 +120,8 @@ var _ = Describe("Vat init transformer", func() {
|
||||
})
|
||||
|
||||
It("converts matching logs", func() {
|
||||
converter := &vat_init_mocks.MockVatInitConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthVatInitLog})
|
||||
repository := &vat_init_mocks.MockVatInitRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := vat_init.VatInitTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -151,17 +130,9 @@ var _ = Describe("Vat init transformer", func() {
|
||||
})
|
||||
|
||||
It("returns error if converter returns error", func() {
|
||||
converter := &vat_init_mocks.MockVatInitConverter{}
|
||||
converter.SetConverterError(fakes.FakeError)
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthVatInitLog})
|
||||
repository := &vat_init_mocks.MockVatInitRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1}})
|
||||
transformer := vat_init.VatInitTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -170,37 +141,20 @@ var _ = Describe("Vat init transformer", func() {
|
||||
})
|
||||
|
||||
It("persists vat init model", func() {
|
||||
converter := &vat_init_mocks.MockVatInitConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthVatInitLog})
|
||||
repository := &vat_init_mocks.MockVatInitRepository{}
|
||||
fakeHeader := core.Header{BlockNumber: 1, Id: 2}
|
||||
repository.SetMissingHeaders([]core.Header{fakeHeader})
|
||||
transformer := vat_init.VatInitTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedHeaderID).To(Equal(fakeHeader.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]vat_init.VatInitModel{test_data.VatInitModel}))
|
||||
Expect(repository.PassedHeaderID).To(Equal(headerOne.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]interface{}{test_data.VatInitModel}))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for create", func() {
|
||||
converter := &vat_init_mocks.MockVatInitConverter{}
|
||||
fetcher := &mocks.MockLogFetcher{}
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthVatInitLog})
|
||||
repository := &vat_init_mocks.MockVatInitRepository{}
|
||||
repository.SetMissingHeaders([]core.Header{{BlockNumber: 1, Id: 2}})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetCreateError(fakes.FakeError)
|
||||
transformer := vat_init.VatInitTransformer{
|
||||
Fetcher: fetcher,
|
||||
Converter: converter,
|
||||
Repository: repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
|
@ -18,10 +18,11 @@ import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
var VatMoveConfig = shared.TransformerConfig{
|
||||
var VatMoveConfig = shared.SingleTransformerConfig{
|
||||
TransformerName: shared.VatMoveLabel,
|
||||
ContractAddresses: []string{shared.VatContractAddress},
|
||||
ContractAbi: shared.VatABI,
|
||||
Topics: []string{shared.VatMoveSignature},
|
||||
Topic: shared.VatMoveSignature,
|
||||
StartingBlockNumber: 0,
|
||||
EndingBlockNumber: 10000000,
|
||||
}
|
||||
|
@ -21,18 +21,14 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
type Converter interface {
|
||||
ToModels(ethLog []types.Log) ([]VatMoveModel, error)
|
||||
}
|
||||
|
||||
type VatMoveConverter struct{}
|
||||
|
||||
func (VatMoveConverter) ToModels(ethLogs []types.Log) ([]VatMoveModel, error) {
|
||||
var models []VatMoveModel
|
||||
func (VatMoveConverter) ToModels(ethLogs []types.Log) ([]interface{}, error) {
|
||||
var models []interface{}
|
||||
for _, ethLog := range ethLogs {
|
||||
err := verifyLog(ethLog)
|
||||
if err != nil {
|
||||
return []VatMoveModel{}, err
|
||||
return []interface{}{}, err
|
||||
}
|
||||
|
||||
src := common.BytesToAddress(ethLog.Topics[1].Bytes())
|
||||
@ -40,7 +36,7 @@ func (VatMoveConverter) ToModels(ethLogs []types.Log) ([]VatMoveModel, error) {
|
||||
rad := ethLog.Topics[3].Big()
|
||||
raw, err := json.Marshal(ethLog)
|
||||
if err != nil {
|
||||
return []VatMoveModel{}, err
|
||||
return []interface{}{}, err
|
||||
}
|
||||
|
||||
models = append(models, VatMoveModel{
|
||||
|
@ -24,18 +24,20 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Vat move converter", func() {
|
||||
It("returns err if logs are missing topics", func() {
|
||||
converter := vat_move.VatMoveConverter{}
|
||||
badLog := types.Log{}
|
||||
var converter vat_move.VatMoveConverter
|
||||
|
||||
BeforeEach(func() {
|
||||
converter = vat_move.VatMoveConverter{}
|
||||
})
|
||||
|
||||
It("returns err if logs are missing topics", func() {
|
||||
badLog := types.Log{}
|
||||
_, err := converter.ToModels([]types.Log{badLog})
|
||||
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("converts a log to a model", func() {
|
||||
converter := vat_move.VatMoveConverter{}
|
||||
|
||||
models, err := converter.ToModels([]types.Log{test_data.EthVatMoveLog})
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -15,33 +15,28 @@
|
||||
package vat_move
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
Create(headerID int64, models []VatMoveModel) error
|
||||
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
|
||||
MarkHeaderChecked(headerID int64) error
|
||||
}
|
||||
|
||||
type VatMoveRepository struct {
|
||||
db *postgres.DB
|
||||
}
|
||||
|
||||
func NewVatMoveRepository(db *postgres.DB) VatMoveRepository {
|
||||
return VatMoveRepository{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (repository VatMoveRepository) Create(headerID int64, models []VatMoveModel) error {
|
||||
func (repository VatMoveRepository) Create(headerID int64, models []interface{}) error {
|
||||
tx, err := repository.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, vatMove := range models {
|
||||
for _, model := range models {
|
||||
vatMove, ok := model.(VatMoveModel)
|
||||
if !ok {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("model of type %T, not %T", model, VatMoveModel{})
|
||||
}
|
||||
|
||||
_, err = tx.Exec(
|
||||
`INSERT INTO maker.vat_move (header_id, src, dst, rad, tx_idx, raw_log)
|
||||
VALUES ($1, $2, $3, $4::NUMERIC, $5, $6)`,
|
||||
@ -94,3 +89,7 @@ func (repository VatMoveRepository) MarkHeaderChecked(headerID int64) error {
|
||||
UPDATE SET vat_move_checked = $2`, headerID, true)
|
||||
return err
|
||||
}
|
||||
|
||||
func (repository *VatMoveRepository) SetDB(db *postgres.DB) {
|
||||
repository.db = db
|
||||
}
|
||||
|
@ -16,9 +16,9 @@ package vat_move_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"math/rand"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
@ -38,7 +38,8 @@ var _ = Describe("Vat Move", func() {
|
||||
db = test_config.NewTestDB(core.Node{})
|
||||
test_config.CleanTestDB(db)
|
||||
headerRepository = repositories.NewHeaderRepository(db)
|
||||
vatMoveRepository = vat_move.NewVatMoveRepository(db)
|
||||
vatMoveRepository = vat_move.VatMoveRepository{}
|
||||
vatMoveRepository.SetDB(db)
|
||||
})
|
||||
|
||||
Describe("Create", func() {
|
||||
@ -48,7 +49,7 @@ var _ = Describe("Vat Move", func() {
|
||||
BeforeEach(func() {
|
||||
headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = vatMoveRepository.Create(headerID, []vat_move.VatMoveModel{test_data.VatMoveModel})
|
||||
err = vatMoveRepository.Create(headerID, []interface{}{test_data.VatMoveModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
@ -71,7 +72,7 @@ var _ = Describe("Vat Move", func() {
|
||||
})
|
||||
|
||||
It("returns an error if insertion fails", func() {
|
||||
err = vatMoveRepository.Create(headerID, []vat_move.VatMoveModel{test_data.VatMoveModel})
|
||||
err = vatMoveRepository.Create(headerID, []interface{}{test_data.VatMoveModel})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
|
||||
})
|
||||
@ -85,10 +86,16 @@ var _ = Describe("Vat Move", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(MatchError(sql.ErrNoRows))
|
||||
})
|
||||
|
||||
It("Returns an error if model is of wrong type", func() {
|
||||
err = vatMoveRepository.Create(headerID, []interface{}{test_data.WrongModel{}})
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("model of type"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MissingHeaders", func() {
|
||||
var eventBlockNumber = GinkgoRandomSeed()
|
||||
var eventBlockNumber = rand.Int63()
|
||||
var startingBlockNumber = eventBlockNumber - 1
|
||||
var endingBlockNumber = eventBlockNumber + 1
|
||||
var outOfRangeBlockNumber = eventBlockNumber + 2
|
||||
@ -145,8 +152,9 @@ var _ = Describe("Vat Move", func() {
|
||||
_, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
vatMoveRepositoryTwo := vat_move.NewVatMoveRepository(dbTwo)
|
||||
err := vatMoveRepository.Create(headerIDs[0], []vat_move.VatMoveModel{test_data.VatMoveModel})
|
||||
vatMoveRepositoryTwo := vat_move.VatMoveRepository{}
|
||||
vatMoveRepositoryTwo.SetDB(dbTwo)
|
||||
err := vatMoveRepository.Create(headerIDs[0], []interface{}{test_data.VatMoveModel})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
nodeOneMissingHeaders, err := vatMoveRepository.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1])
|
||||
@ -157,7 +165,6 @@ var _ = Describe("Vat Move", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(nodeTwoMissingHeaders)).To(Equal(len(blockNumbers)))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
Describe("MarkHeaderChecked", func() {
|
||||
|
@ -1,83 +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 vat_move
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
|
||||
)
|
||||
|
||||
type VatMoveTransformerInitializer struct {
|
||||
Config shared.TransformerConfig
|
||||
}
|
||||
|
||||
func (initializer VatMoveTransformerInitializer) NewVatMoveTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
converter := VatMoveConverter{}
|
||||
fetcher := shared.NewFetcher(blockChain)
|
||||
repository := NewVatMoveRepository(db)
|
||||
return VatMoveTransformer{
|
||||
Config: initializer.Config,
|
||||
Converter: converter,
|
||||
Fetcher: fetcher,
|
||||
Repository: repository,
|
||||
}
|
||||
}
|
||||
|
||||
type VatMoveTransformer struct {
|
||||
Config shared.TransformerConfig
|
||||
Converter Converter
|
||||
Fetcher shared.LogFetcher
|
||||
Repository Repository
|
||||
}
|
||||
|
||||
func (transformer VatMoveTransformer) Execute() error {
|
||||
missingHeaders, err := transformer.Repository.MissingHeaders(transformer.Config.StartingBlockNumber, transformer.Config.EndingBlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Fetching vat move event logs for %d headers \n", len(missingHeaders))
|
||||
for _, header := range missingHeaders {
|
||||
topics := [][]common.Hash{{common.HexToHash(shared.VatMoveSignature)}}
|
||||
matchingLogs, err := transformer.Fetcher.FetchLogs(VatMoveConfig.ContractAddresses, topics, header.BlockNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(matchingLogs) < 1 {
|
||||
err := transformer.Repository.MarkHeaderChecked(header.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
models, err := transformer.Converter.ToModels(matchingLogs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = transformer.Repository.Create(header.Id, models)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -21,18 +21,21 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
"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/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks"
|
||||
vat_move_mocks "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks/vat_move"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_move"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
var _ = Describe("Vat move transformer", func() {
|
||||
var config = vat_move.VatMoveConfig
|
||||
var fetcher mocks.MockLogFetcher
|
||||
var converter vat_move_mocks.MockVatMoveConverter
|
||||
var repository vat_move_mocks.MockVatMoveRepository
|
||||
var config = vat_move.VatMoveConfig
|
||||
var transformer shared.Transformer
|
||||
var headerOne core.Header
|
||||
var headerTwo core.Header
|
||||
|
||||
@ -40,18 +43,22 @@ var _ = Describe("Vat move transformer", func() {
|
||||
fetcher = mocks.MockLogFetcher{}
|
||||
converter = vat_move_mocks.MockVatMoveConverter{}
|
||||
repository = vat_move_mocks.MockVatMoveRepository{}
|
||||
headerOne = core.Header{Id: GinkgoRandomSeed(), BlockNumber: GinkgoRandomSeed()}
|
||||
headerTwo = core.Header{Id: GinkgoRandomSeed(), BlockNumber: GinkgoRandomSeed()}
|
||||
})
|
||||
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
transformer := vat_move.VatMoveTransformer{
|
||||
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 database", func() {
|
||||
Expect(fetcher.SetBcCalled).To(BeTrue())
|
||||
Expect(repository.SetDbCalled).To(BeTrue())
|
||||
})
|
||||
|
||||
It("gets missing headers for block numbers specified in config", func() {
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@ -61,12 +68,6 @@ var _ = Describe("Vat move transformer", func() {
|
||||
|
||||
It("returns error if repository returns error for missing headers", func() {
|
||||
repository.SetMissingHeadersError(fakes.FakeError)
|
||||
transformer := vat_move.VatMoveTransformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -76,12 +77,6 @@ var _ = Describe("Vat move transformer", func() {
|
||||
|
||||
It("fetches logs for missing headers", func() {
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
transformer := vat_move.VatMoveTransformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &vat_move_mocks.MockVatMoveConverter{},
|
||||
Repository: &repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -97,12 +92,6 @@ var _ = Describe("Vat move transformer", func() {
|
||||
It("returns error if fetcher returns error", func() {
|
||||
fetcher.SetFetcherError(fakes.FakeError)
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
transformer := vat_move.VatMoveTransformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -113,12 +102,6 @@ var _ = Describe("Vat move transformer", func() {
|
||||
It("converts matching logs", func() {
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthVatMoveLog})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
transformer := vat_move.VatMoveTransformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -130,12 +113,6 @@ var _ = Describe("Vat move transformer", func() {
|
||||
converter.SetConverterError(fakes.FakeError)
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthVatMoveLog})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
transformer := vat_move.VatMoveTransformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -146,12 +123,6 @@ var _ = Describe("Vat move transformer", func() {
|
||||
It("marks header as checked even if no logs were returned", func() {
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
fetcher.SetFetchedLogs([]types.Log{})
|
||||
transformer := vat_move.VatMoveTransformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@ -163,12 +134,6 @@ var _ = Describe("Vat move transformer", func() {
|
||||
repository.SetMissingHeaders([]core.Header{headerOne, headerTwo})
|
||||
repository.SetCheckedHeaderError(fakes.FakeError)
|
||||
fetcher.SetFetchedLogs([]types.Log{})
|
||||
transformer := vat_move.VatMoveTransformer{
|
||||
Config: config,
|
||||
Converter: &converter,
|
||||
Fetcher: &fetcher,
|
||||
Repository: &repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
@ -179,30 +144,18 @@ var _ = Describe("Vat move transformer", func() {
|
||||
It("persists vat move model", func() {
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthVatMoveLog})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
transformer := vat_move.VatMoveTransformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(repository.PassedHeaderID).To(Equal(headerOne.Id))
|
||||
Expect(repository.PassedModels).To(Equal([]vat_move.VatMoveModel{test_data.VatMoveModel}))
|
||||
Expect(repository.PassedModels).To(Equal([]interface{}{test_data.VatMoveModel}))
|
||||
})
|
||||
|
||||
It("returns error if repository returns error for create", func() {
|
||||
fetcher.SetFetchedLogs([]types.Log{test_data.EthVatMoveLog})
|
||||
repository.SetMissingHeaders([]core.Header{headerOne})
|
||||
repository.SetCreateError(fakes.FakeError)
|
||||
transformer := vat_move.VatMoveTransformer{
|
||||
Config: config,
|
||||
Fetcher: &fetcher,
|
||||
Converter: &converter,
|
||||
Repository: &repository,
|
||||
}
|
||||
|
||||
err := transformer.Execute()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user