Verify pit file logs

- assure required topics + data available before parsing
This commit is contained in:
Rob Mulholand 2018-09-11 16:23:47 -05:00
parent dc9bda7d68
commit 4b6ef1e58b
16 changed files with 127 additions and 46 deletions

View File

@ -18,20 +18,25 @@ import (
"encoding/json" "encoding/json"
"math/big" "math/big"
"errors"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
) )
type Converter interface { type Converter interface {
ToModel(contractAddress string, contractAbi string, ethLog types.Log) (PitFileDebtCeilingModel, error) ToModel(ethLog types.Log) (PitFileDebtCeilingModel, error)
} }
type PitFileDebtCeilingConverter struct{} type PitFileDebtCeilingConverter struct{}
func (PitFileDebtCeilingConverter) ToModel(contractAddress string, contractAbi string, ethLog types.Log) (PitFileDebtCeilingModel, error) { func (PitFileDebtCeilingConverter) ToModel(ethLog types.Log) (PitFileDebtCeilingModel, error) {
err := verifyLog(ethLog)
if err != nil {
return PitFileDebtCeilingModel{}, err
}
what := common.HexToAddress(ethLog.Topics[1].String()).String() what := common.HexToAddress(ethLog.Topics[1].String()).String()
itemByteLength := 32 riskBytes := ethLog.Data[len(ethLog.Data)-shared.DataItemLength:]
riskBytes := ethLog.Data[len(ethLog.Data)-itemByteLength:]
data := big.NewInt(0).SetBytes(riskBytes).String() data := big.NewInt(0).SetBytes(riskBytes).String()
raw, err := json.Marshal(ethLog) raw, err := json.Marshal(ethLog)
@ -42,3 +47,13 @@ func (PitFileDebtCeilingConverter) ToModel(contractAddress string, contractAbi s
Raw: raw, Raw: raw,
}, err }, err
} }
func verifyLog(log types.Log) error {
if len(log.Topics) < 2 {
return errors.New("log missing topics")
}
if len(log.Data) < shared.DataItemLength {
return errors.New("log missing data")
}
return nil
}

View File

@ -18,16 +18,39 @@ import (
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"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/pit_file/debt_ceiling"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data" "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
) )
var _ = Describe("", func() { var _ = Describe("", func() {
It("returns err if log is missing topics", func() {
converter := debt_ceiling.PitFileDebtCeilingConverter{}
badLog := types.Log{
Data: []byte{1, 1, 1, 1, 1},
}
_, err := converter.ToModel(badLog)
Expect(err).To(HaveOccurred())
})
It("returns err if log is missing data", func() {
converter := debt_ceiling.PitFileDebtCeilingConverter{}
badLog := types.Log{
Topics: []common.Hash{{}, {}, {}, {}},
}
_, err := converter.ToModel(badLog)
Expect(err).To(HaveOccurred())
})
It("converts a log to an model", func() { It("converts a log to an model", func() {
converter := debt_ceiling.PitFileDebtCeilingConverter{} converter := debt_ceiling.PitFileDebtCeilingConverter{}
model, err := converter.ToModel(shared.PitContractAddress, shared.PitABI, test_data.EthPitFileDebtCeilingLog) model, err := converter.ToModel(test_data.EthPitFileDebtCeilingLog)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(model).To(Equal(test_data.PitFileDebtCeilingModel)) Expect(model).To(Equal(test_data.PitFileDebtCeilingModel))

View File

@ -58,7 +58,7 @@ func (transformer PitFileDebtCeilingTransformer) Execute() error {
return err return err
} }
for _, log := range matchingLogs { for _, log := range matchingLogs {
model, err := transformer.Converter.ToModel(pit_file.PitFileConfig.ContractAddress, shared.PitABI, log) model, err := transformer.Converter.ToModel(log)
if err != nil { if err != nil {
return err return err
} }

View File

@ -112,8 +112,6 @@ var _ = Describe("", func() {
err := transformer.Execute() err := transformer.Execute()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(converter.PassedContractAddress).To(Equal(pit_file.PitFileConfig.ContractAddress))
Expect(converter.PassedContractABI).To(Equal(pit_file.PitFileConfig.ContractAbi))
Expect(converter.PassedLog).To(Equal(test_data.EthPitFileDebtCeilingLog)) Expect(converter.PassedLog).To(Equal(test_data.EthPitFileDebtCeilingLog))
}) })

View File

@ -19,20 +19,25 @@ import (
"encoding/json" "encoding/json"
"math/big" "math/big"
"errors"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
) )
type Converter interface { type Converter interface {
ToModel(contractAddress string, contractAbi string, ethLog types.Log) (PitFileIlkModel, error) ToModel(ethLog types.Log) (PitFileIlkModel, error)
} }
type PitFileIlkConverter struct{} type PitFileIlkConverter struct{}
func (PitFileIlkConverter) ToModel(contractAddress string, contractAbi string, ethLog types.Log) (entity PitFileIlkModel, err error) { func (PitFileIlkConverter) ToModel(ethLog types.Log) (PitFileIlkModel, error) {
err := verifyLog(ethLog)
if err != nil {
return PitFileIlkModel{}, err
}
ilk := string(bytes.Trim(ethLog.Topics[2].Bytes(), "\x00")) ilk := string(bytes.Trim(ethLog.Topics[2].Bytes(), "\x00"))
what := string(bytes.Trim(ethLog.Topics[3].Bytes(), "\x00")) what := string(bytes.Trim(ethLog.Topics[3].Bytes(), "\x00"))
itemByteLength := 32 riskBytes := ethLog.Data[len(ethLog.Data)-shared.DataItemLength:]
riskBytes := ethLog.Data[len(ethLog.Data)-itemByteLength:]
risk := big.NewInt(0).SetBytes(riskBytes).String() risk := big.NewInt(0).SetBytes(riskBytes).String()
raw, err := json.Marshal(ethLog) raw, err := json.Marshal(ethLog)
@ -44,3 +49,13 @@ func (PitFileIlkConverter) ToModel(contractAddress string, contractAbi string, e
Raw: raw, Raw: raw,
}, err }, err
} }
func verifyLog(log types.Log) error {
if len(log.Topics) < 4 {
return errors.New("log missing topics")
}
if len(log.Data) < shared.DataItemLength {
return errors.New("log missing data")
}
return nil
}

View File

@ -18,16 +18,39 @@ import (
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/ilk" "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"
) )
var _ = Describe("Pit file ilk converter", func() { var _ = Describe("Pit file ilk converter", func() {
It("returns err if log is missing topics", func() {
converter := ilk.PitFileIlkConverter{}
badLog := types.Log{
Data: []byte{1, 1, 1, 1, 1},
}
_, err := converter.ToModel(badLog)
Expect(err).To(HaveOccurred())
})
It("returns err if log is missing data", func() {
converter := ilk.PitFileIlkConverter{}
badLog := types.Log{
Topics: []common.Hash{{}, {}, {}, {}},
}
_, err := converter.ToModel(badLog)
Expect(err).To(HaveOccurred())
})
It("converts a log to an model", func() { It("converts a log to an model", func() {
converter := ilk.PitFileIlkConverter{} converter := ilk.PitFileIlkConverter{}
model, err := converter.ToModel(shared.PitContractAddress, shared.PitABI, test_data.EthPitFileIlkLog) model, err := converter.ToModel(test_data.EthPitFileIlkLog)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(model).To(Equal(test_data.PitFileIlkModel)) Expect(model).To(Equal(test_data.PitFileIlkModel))

View File

@ -58,7 +58,7 @@ func (transformer PitFileIlkTransformer) Execute() error {
return err return err
} }
for _, log := range matchingLogs { for _, log := range matchingLogs {
model, err := transformer.Converter.ToModel(pit_file.PitFileConfig.ContractAddress, shared.PitABI, log) model, err := transformer.Converter.ToModel(log)
if err != nil { if err != nil {
return err return err
} }

View File

@ -112,8 +112,6 @@ var _ = Describe("Pit file ilk transformer", func() {
err := transformer.Execute() err := transformer.Execute()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(converter.PassedContractAddress).To(Equal(pit_file.PitFileConfig.ContractAddress))
Expect(converter.PassedContractABI).To(Equal(pit_file.PitFileConfig.ContractAbi))
Expect(converter.PassedLog).To(Equal(test_data.EthPitFileIlkLog)) Expect(converter.PassedLog).To(Equal(test_data.EthPitFileIlkLog))
}) })

View File

@ -18,17 +18,22 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
) )
type Converter interface { type Converter interface {
ToModel(contractAddress string, contractAbi string, ethLog types.Log) (PitFileStabilityFeeModel, error) ToModel(ethLog types.Log) (PitFileStabilityFeeModel, error)
} }
type PitFileStabilityFeeConverter struct{} type PitFileStabilityFeeConverter struct{}
func (PitFileStabilityFeeConverter) ToModel(contractAddress string, contractAbi string, ethLog types.Log) (PitFileStabilityFeeModel, error) { func (PitFileStabilityFeeConverter) ToModel(ethLog types.Log) (PitFileStabilityFeeModel, error) {
err := verifyLog(ethLog)
if err != nil {
return PitFileStabilityFeeModel{}, err
}
what := string(bytes.Trim(ethLog.Topics[2].Bytes(), "\x00")) what := string(bytes.Trim(ethLog.Topics[2].Bytes(), "\x00"))
data := common.HexToAddress(ethLog.Topics[1].String()).Hex() data := common.HexToAddress(ethLog.Topics[1].String()).Hex()
@ -40,3 +45,10 @@ func (PitFileStabilityFeeConverter) ToModel(contractAddress string, contractAbi
Raw: raw, Raw: raw,
}, err }, err
} }
func verifyLog(log types.Log) error {
if len(log.Topics) < 3 {
return errors.New("log missing topics")
}
return nil
}

View File

@ -18,16 +18,25 @@ import (
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/stability_fee" "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"
) )
var _ = Describe("Pit file stability fee converter", func() { var _ = Describe("Pit file stability fee converter", func() {
It("returns err if log is missing topics", func() {
converter := stability_fee.PitFileStabilityFeeConverter{}
badLog := types.Log{}
_, err := converter.ToModel(badLog)
Expect(err).To(HaveOccurred())
})
It("converts a log to an model", func() { It("converts a log to an model", func() {
converter := stability_fee.PitFileStabilityFeeConverter{} converter := stability_fee.PitFileStabilityFeeConverter{}
model, err := converter.ToModel(shared.PitContractAddress, shared.PitABI, test_data.EthPitFileStabilityFeeLog) model, err := converter.ToModel(test_data.EthPitFileStabilityFeeLog)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(model).To(Equal(test_data.PitFileStabilityFeeModel)) Expect(model).To(Equal(test_data.PitFileStabilityFeeModel))

View File

@ -58,7 +58,7 @@ func (transformer PitFileStabilityFeeTransformer) Execute() error {
return err return err
} }
for _, log := range matchingLogs { for _, log := range matchingLogs {
model, err := transformer.Converter.ToModel(pit_file.PitFileConfig.ContractAddress, shared.PitABI, log) model, err := transformer.Converter.ToModel(log)
if err != nil { if err != nil {
return err return err
} }

View File

@ -112,8 +112,6 @@ var _ = Describe("", func() {
err := transformer.Execute() err := transformer.Execute()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(converter.PassedContractAddress).To(Equal(pit_file.PitFileConfig.ContractAddress))
Expect(converter.PassedContractABI).To(Equal(pit_file.PitFileConfig.ContractAbi))
Expect(converter.PassedLog).To(Equal(test_data.EthPitFileStabilityFeeLog)) Expect(converter.PassedLog).To(Equal(test_data.EthPitFileStabilityFeeLog))
}) })

View File

@ -15,6 +15,8 @@
package shared package shared
var ( var (
DataItemLength = 32
biteMethod = "Bite(bytes32,bytes32,uint256,uint256,uint256,uint256,uint256)" biteMethod = "Bite(bytes32,bytes32,uint256,uint256,uint256,uint256,uint256)"
dentMethod = "dent(uint256,uint256,uint256)" dentMethod = "dent(uint256,uint256,uint256)"
flipKickMethod = "Kick(uint256,uint256,uint256,address,uint48,bytes32,uint256)" flipKickMethod = "Kick(uint256,uint256,uint256,address,uint48,bytes32,uint256)"

View File

@ -23,14 +23,10 @@ import (
type MockPitFileDebtCeilingConverter struct { type MockPitFileDebtCeilingConverter struct {
converterErr error converterErr error
PassedContractAddress string
PassedContractABI string
PassedLog types.Log PassedLog types.Log
} }
func (converter *MockPitFileDebtCeilingConverter) ToModel(contractAddress string, contractAbi string, ethLog types.Log) (debt_ceiling.PitFileDebtCeilingModel, error) { func (converter *MockPitFileDebtCeilingConverter) ToModel(ethLog types.Log) (debt_ceiling.PitFileDebtCeilingModel, error) {
converter.PassedContractAddress = contractAddress
converter.PassedContractABI = contractAbi
converter.PassedLog = ethLog converter.PassedLog = ethLog
return test_data.PitFileDebtCeilingModel, converter.converterErr return test_data.PitFileDebtCeilingModel, converter.converterErr
} }

View File

@ -22,8 +22,6 @@ import (
) )
type MockPitFileIlkConverter struct { type MockPitFileIlkConverter struct {
PassedContractAddress string
PassedContractABI string
PassedLog types.Log PassedLog types.Log
converterError error converterError error
} }
@ -32,9 +30,7 @@ func (converter *MockPitFileIlkConverter) SetConverterError(err error) {
converter.converterError = err converter.converterError = err
} }
func (converter *MockPitFileIlkConverter) ToModel(contractAddress string, contractAbi string, ethLog types.Log) (ilk.PitFileIlkModel, error) { func (converter *MockPitFileIlkConverter) ToModel(ethLog types.Log) (ilk.PitFileIlkModel, error) {
converter.PassedContractAddress = contractAddress
converter.PassedContractABI = contractAbi
converter.PassedLog = ethLog converter.PassedLog = ethLog
return test_data.PitFileIlkModel, converter.converterError return test_data.PitFileIlkModel, converter.converterError
} }

View File

@ -23,14 +23,10 @@ import (
type MockPitFileStabilityFeeConverter struct { type MockPitFileStabilityFeeConverter struct {
converterErr error converterErr error
PassedContractAddress string
PassedContractABI string
PassedLog types.Log PassedLog types.Log
} }
func (converter *MockPitFileStabilityFeeConverter) ToModel(contractAddress string, contractAbi string, ethLog types.Log) (stability_fee.PitFileStabilityFeeModel, error) { func (converter *MockPitFileStabilityFeeConverter) ToModel(ethLog types.Log) (stability_fee.PitFileStabilityFeeModel, error) {
converter.PassedContractAddress = contractAddress
converter.PassedContractABI = contractAbi
converter.PassedLog = ethLog converter.PassedLog = ethLog
return test_data.PitFileStabilityFeeModel, converter.converterErr return test_data.PitFileStabilityFeeModel, converter.converterErr
} }