Extract price feed contract addresses to config

This commit is contained in:
Rob Mulholand
2018-08-16 11:22:16 -05:00
parent 72a849a272
commit 9231d40369
23 changed files with 152 additions and 124 deletions
+1 -17
View File
@@ -18,11 +18,6 @@ type MockBlockChain struct {
fetchContractDataPassedMethodArg interface{}
fetchContractDataPassedResult interface{}
fetchContractDataPassedBlockNumber int64
getLogsPassedContract core.Contract
getLogsPassedStartingBlockNumber *big.Int
getLogsPassedEndingBlockNumber *big.Int
getLogsReturnLogs []core.Log
getLogsReturnErr error
getBlockByNumberErr error
logQuery ethereum.FilterQuery
logQueryErr error
@@ -57,14 +52,6 @@ func (chain *MockBlockChain) SetGetEthLogsWithCustomQueryReturnLogs(logs []types
chain.logQueryReturnLogs = logs
}
func (chain *MockBlockChain) SetGetLogsReturnErr(err error) {
chain.getLogsReturnErr = err
}
func (chain *MockBlockChain) SetGetLogsReturnLogs(logs []core.Log) {
chain.getLogsReturnLogs = logs
}
func (chain *MockBlockChain) FetchContractData(abiJSON, address, method string, methodArg, result interface{}, blockNumber int64) error {
chain.fetchContractDataPassedAbi = abiJSON
chain.fetchContractDataPassedAddress = address
@@ -89,10 +76,7 @@ func (chain *MockBlockChain) GetHeaderByNumber(blockNumber int64) (core.Header,
}
func (chain *MockBlockChain) GetLogs(contract core.Contract, startingBlockNumber, endingBlockNumber *big.Int) ([]core.Log, error) {
chain.getLogsPassedContract = contract
chain.getLogsPassedStartingBlockNumber = startingBlockNumber
chain.getLogsPassedEndingBlockNumber = endingBlockNumber
return chain.getLogsReturnLogs, chain.getLogsReturnErr
return []core.Log{}, nil
}
func (chain *MockBlockChain) CallContract(contractHash string, input []byte, blockNumber *big.Int) ([]byte, error) {
@@ -10,12 +10,9 @@ var (
ErrNoMatchingLog = errors.New("no matching log")
Ether = big.NewFloat(1e18)
PeekMethodName = "peek"
PepAddress = "0x99041F808D598B782D5a3e498681C2452A31da08"
PepLogTopic0 = "0x296ba4ca62c6c21c95e828080cb8aec7481b71390585605300a8a76f9e95b527"
PipAddress = "0x729D19f657BD0614b4985Cf1D82531c67569197B"
PipLogTopic0 = "0x1817835800000000000000000000000000000000000000000000000000000000"
PipMedianizerABI = `[{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"","type":"bytes32"}],"name":"poke","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"poke","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"compute","outputs":[{"name":"","type":"bytes32"},{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wat","type":"address"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wat","type":"address"}],"name":"unset","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"indexes","outputs":[{"name":"","type":"bytes12"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"next","outputs":[{"name":"","type":"bytes12"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"read","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"peek","outputs":[{"name":"","type":"bytes32"},{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes12"}],"name":"values","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"min_","type":"uint96"}],"name":"setMin","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"void","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"pos","type":"bytes12"},{"name":"wat","type":"address"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"pos","type":"bytes12"}],"name":"unset","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"next_","type":"bytes12"}],"name":"setNext","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"min","outputs":[{"name":"","type":"uint96"}],"payable":false,"type":"function"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]`
Ray = big.NewFloat(1e27)
RepAddress = "0xF5f94b7F9De14D43112e713835BCef2d55b76c1C"
RepLogTopic0 = "0x296ba4ca62c6c21c95e828080cb8aec7481b71390585605300a8a76f9e95b527"
)
+6 -4
View File
@@ -16,12 +16,14 @@ type IPepFetcher interface {
}
type PepFetcher struct {
blockChain core.BlockChain
blockChain core.BlockChain
contractAddress string
}
func NewPepFetcher(chain core.BlockChain) PepFetcher {
func NewPepFetcher(chain core.BlockChain, contractAddress string) PepFetcher {
return PepFetcher{
blockChain: chain,
blockChain: chain,
contractAddress: contractAddress,
}
}
@@ -30,7 +32,7 @@ func (fetcher PepFetcher) FetchPepValue(header core.Header) (string, error) {
query := ethereum.FilterQuery{
FromBlock: blockNumber,
ToBlock: blockNumber,
Addresses: []common.Address{common.HexToAddress(price_feeds.PepAddress)},
Addresses: []common.Address{common.HexToAddress(fetcher.contractAddress)},
Topics: [][]common.Hash{{common.HexToHash(price_feeds.PepLogTopic0)}},
}
logs, err := fetcher.blockChain.GetEthLogsWithCustomQuery(query)
@@ -18,8 +18,9 @@ var _ = Describe("Pep fetcher", func() {
It("gets logs describing updated mkr/usd value", func() {
mockBlockChain := fakes.NewMockBlockChain()
mockBlockChain.SetGetEthLogsWithCustomQueryReturnLogs([]types.Log{{}})
fetcher := pep.NewPepFetcher(mockBlockChain)
blockNumber := int64(100)
contractAddress := "pep-contract-address"
fetcher := pep.NewPepFetcher(mockBlockChain, contractAddress)
blockNumber := int64(12345)
header := core.Header{
BlockNumber: blockNumber,
Hash: "",
@@ -32,7 +33,7 @@ var _ = Describe("Pep fetcher", func() {
expectedQuery := ethereum.FilterQuery{
FromBlock: big.NewInt(blockNumber),
ToBlock: big.NewInt(blockNumber),
Addresses: []common.Address{common.HexToAddress(price_feeds.PepAddress)},
Addresses: []common.Address{common.HexToAddress(contractAddress)},
Topics: [][]common.Hash{{common.HexToHash(price_feeds.PepLogTopic0)}},
}
mockBlockChain.AssertGetEthLogsWithCustomQueryCalledWith(expectedQuery)
@@ -42,7 +43,7 @@ var _ = Describe("Pep fetcher", func() {
mockBlockChain := fakes.NewMockBlockChain()
mockBlockChain.SetGetEthLogsWithCustomQueryReturnLogs([]types.Log{{}})
mockBlockChain.SetGetEthLogsWithCustomQueryErr(fakes.FakeError)
fetcher := pep.NewPepFetcher(mockBlockChain)
fetcher := pep.NewPepFetcher(mockBlockChain, "pep-contract-address")
_, err := fetcher.FetchPepValue(core.Header{})
@@ -52,7 +53,7 @@ var _ = Describe("Pep fetcher", func() {
It("returns no matching logs error if no logs returned", func() {
mockBlockChain := fakes.NewMockBlockChain()
fetcher := pep.NewPepFetcher(mockBlockChain)
fetcher := pep.NewPepFetcher(mockBlockChain, "pep-contract-address")
_, err := fetcher.FetchPepValue(core.Header{})
@@ -63,7 +64,7 @@ var _ = Describe("Pep fetcher", func() {
It("returns error if more than one matching logs returned", func() {
mockBlockChain := fakes.NewMockBlockChain()
mockBlockChain.SetGetEthLogsWithCustomQueryReturnLogs([]types.Log{{}, {}})
fetcher := pep.NewPepFetcher(mockBlockChain)
fetcher := pep.NewPepFetcher(mockBlockChain, "pep-contract-address")
_, err := fetcher.FetchPepValue(core.Header{})
@@ -11,8 +11,8 @@ type PepTransformer struct {
repository IPepRepository
}
func NewPepTransformer(chain core.BlockChain, db *postgres.DB) PepTransformer {
fetcher := NewPepFetcher(chain)
func NewPepTransformer(chain core.BlockChain, db *postgres.DB, contractAddress string) PepTransformer {
fetcher := NewPepFetcher(chain, contractAddress)
repository := NewPepRepository(db)
return PepTransformer{
fetcher: fetcher,
@@ -17,7 +17,7 @@ var _ = Describe("Pep transformer", func() {
It("returns nil if no logs found", func() {
chain := fakes.NewMockBlockChain()
db := test_config.NewTestDB(core.Node{})
transformer := pep.NewPepTransformer(chain, db)
transformer := pep.NewPepTransformer(chain, db, "pep-contract-address")
err := transformer.Execute(core.Header{}, 123)
@@ -33,7 +33,7 @@ var _ = Describe("Pep transformer", func() {
header := core.Header{BlockNumber: 12345}
headerID, err := headerRepository.CreateOrUpdateHeader(header)
Expect(err).NotTo(HaveOccurred())
transformer := pep.NewPepTransformer(chain, db)
transformer := pep.NewPepTransformer(chain, db, "pep-contract-address")
err = transformer.Execute(header, headerID)
+7 -5
View File
@@ -14,12 +14,14 @@ type IPipFetcher interface {
}
type PipFetcher struct {
blockChain core.BlockChain
blockChain core.BlockChain
contractAddress string
}
func NewPipFetcher(chain core.BlockChain) PipFetcher {
func NewPipFetcher(chain core.BlockChain, contractAddress string) PipFetcher {
return PipFetcher{
blockChain: chain,
blockChain: chain,
contractAddress: contractAddress,
}
}
@@ -28,7 +30,7 @@ func (fetcher PipFetcher) FetchPipValue(header core.Header) (string, error) {
query := ethereum.FilterQuery{
FromBlock: blockNumber,
ToBlock: blockNumber,
Addresses: []common.Address{common.HexToAddress(price_feeds.PipAddress)},
Addresses: []common.Address{common.HexToAddress(fetcher.contractAddress)},
Topics: [][]common.Hash{{common.HexToHash(price_feeds.PipLogTopic0)}},
}
logs, err := fetcher.blockChain.GetEthLogsWithCustomQuery(query)
@@ -50,7 +52,7 @@ func (fetcher PipFetcher) getLogValue(logs []types.Log, err error) (string, erro
ret0,
ret1,
}
err = fetcher.blockChain.FetchContractData(price_feeds.PipMedianizerABI, price_feeds.PipAddress, price_feeds.PeekMethodName, nil, r, int64(logs[0].BlockNumber))
err = fetcher.blockChain.FetchContractData(price_feeds.PipMedianizerABI, fetcher.contractAddress, price_feeds.PeekMethodName, nil, r, int64(logs[0].BlockNumber))
if err != nil {
return "", err
}
@@ -14,7 +14,7 @@ var _ = Describe("Pip fetcher", func() {
It("returns error if fetching logs fails", func() {
chain := fakes.NewMockBlockChain()
chain.SetGetEthLogsWithCustomQueryErr(fakes.FakeError)
fetcher := pip.NewPipFetcher(chain)
fetcher := pip.NewPipFetcher(chain, "pip-contract-address")
_, err := fetcher.FetchPipValue(core.Header{})
@@ -24,7 +24,7 @@ var _ = Describe("Pip fetcher", func() {
It("returns no matching logs error if no logs returned", func() {
chain := fakes.NewMockBlockChain()
fetcher := pip.NewPipFetcher(chain)
fetcher := pip.NewPipFetcher(chain, "pip-contract-address")
_, err := fetcher.FetchPipValue(core.Header{})
@@ -37,19 +37,20 @@ var _ = Describe("Pip fetcher", func() {
blockNumber := uint64(12345)
chain := fakes.NewMockBlockChain()
chain.SetGetEthLogsWithCustomQueryReturnLogs([]types.Log{{BlockNumber: blockNumber}})
fetcher := pip.NewPipFetcher(chain)
contractAddress := "pip-contract-address"
fetcher := pip.NewPipFetcher(chain, contractAddress)
_, err := fetcher.FetchPipValue(core.Header{})
Expect(err).NotTo(HaveOccurred())
chain.AssertFetchContractDataCalledWith(price_feeds.PipMedianizerABI, price_feeds.PipAddress, price_feeds.PeekMethodName, nil, &[]interface{}{[32]byte{}, false}, int64(blockNumber))
chain.AssertFetchContractDataCalledWith(price_feeds.PipMedianizerABI, contractAddress, price_feeds.PeekMethodName, nil, &[]interface{}{[32]byte{}, false}, int64(blockNumber))
})
It("returns error if contract call fails", func() {
chain := fakes.NewMockBlockChain()
chain.SetGetEthLogsWithCustomQueryReturnLogs([]types.Log{{BlockNumber: uint64(12345)}})
chain.SetFetchContractDataErr(fakes.FakeError)
fetcher := pip.NewPipFetcher(chain)
fetcher := pip.NewPipFetcher(chain, "pip-contract-address")
_, err := fetcher.FetchPipValue(core.Header{})
@@ -11,8 +11,8 @@ type PipTransformer struct {
repository IPipRepository
}
func NewPipTransformer(chain core.BlockChain, db *postgres.DB) PipTransformer {
fetcher := NewPipFetcher(chain)
func NewPipTransformer(chain core.BlockChain, db *postgres.DB, contractAddress string) PipTransformer {
fetcher := NewPipFetcher(chain, contractAddress)
repository := NewPipRepository(db)
return PipTransformer{
fetcher: fetcher,
@@ -16,7 +16,7 @@ var _ = Describe("Pip transformer", func() {
It("returns nil if no logs found", func() {
chain := fakes.NewMockBlockChain()
db := test_config.NewTestDB(core.Node{})
transformer := pip.NewPipTransformer(chain, db)
transformer := pip.NewPipTransformer(chain, db, "pip-contract-address")
err := transformer.Execute(core.Header{}, 123)
@@ -32,7 +32,7 @@ var _ = Describe("Pip transformer", func() {
header := core.Header{BlockNumber: 12345}
headerID, err := headerRepository.CreateOrUpdateHeader(header)
Expect(err).NotTo(HaveOccurred())
transformer := pip.NewPipTransformer(chain, db)
transformer := pip.NewPipTransformer(chain, db, "pip-contract-address")
err = transformer.Execute(header, headerID)
+17 -6
View File
@@ -1,6 +1,9 @@
package rep
import (
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/transformers/price_feeds"
"math/big"
@@ -11,22 +14,30 @@ type IRepFetcher interface {
}
type RepFetcher struct {
chain core.BlockChain
chain core.BlockChain
contractAddress string
}
func NewRepFetcher(chain core.BlockChain) RepFetcher {
func NewRepFetcher(chain core.BlockChain, contractAddress string) RepFetcher {
return RepFetcher{
chain: chain,
chain: chain,
contractAddress: contractAddress,
}
}
func (fetcher RepFetcher) FetchRepValue(header core.Header) (string, error) {
blockNumber := big.NewInt(header.BlockNumber)
logs, err := fetcher.chain.GetLogs(price_feeds.RepAddress, price_feeds.RepLogTopic0, blockNumber, blockNumber)
query := ethereum.FilterQuery{
FromBlock: blockNumber,
ToBlock: blockNumber,
Addresses: []common.Address{common.HexToAddress(fetcher.contractAddress)},
Topics: [][]common.Hash{{common.HexToHash(price_feeds.RepLogTopic0)}},
}
logs, err := fetcher.chain.GetEthLogsWithCustomQuery(query)
return fetcher.getLogValue(logs, err)
}
func (fetcher RepFetcher) getLogValue(logs []core.Log, err error) (string, error) {
func (fetcher RepFetcher) getLogValue(logs []types.Log, err error) (string, error) {
if err != nil {
return "", err
}
@@ -36,5 +47,5 @@ func (fetcher RepFetcher) getLogValue(logs []core.Log, err error) (string, error
if len(logs) > 1 {
return "", price_feeds.ErrMultipleLogs
}
return logs[0].Data, nil
return string(logs[0].Data), nil
}
@@ -1,6 +1,9 @@
package rep_test
import (
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/core"
@@ -13,10 +16,12 @@ import (
var _ = Describe("Rep fetcher", func() {
It("gets logs describing updated rep/usd value", func() {
mockBlockChain := fakes.NewMockBlockChain()
mockBlockChain.SetGetLogsReturnLogs([]core.Log{{}})
fetcher := rep.NewRepFetcher(mockBlockChain)
mockBlockChain.SetGetEthLogsWithCustomQueryReturnLogs([]types.Log{{}})
contractAddress := "rep-contract-address"
fetcher := rep.NewRepFetcher(mockBlockChain, contractAddress)
blockNumber := int64(100)
header := core.Header{
BlockNumber: 100,
BlockNumber: blockNumber,
Hash: "",
Raw: nil,
}
@@ -24,14 +29,19 @@ var _ = Describe("Rep fetcher", func() {
_, err := fetcher.FetchRepValue(header)
Expect(err).NotTo(HaveOccurred())
mockBlockChain.AssertGetLogsCalledWith(price_feeds.RepAddress, price_feeds.RepLogTopic0, big.NewInt(header.BlockNumber), big.NewInt(header.BlockNumber))
expectedQuery := ethereum.FilterQuery{
FromBlock: big.NewInt(blockNumber),
ToBlock: big.NewInt(blockNumber),
Addresses: []common.Address{common.HexToAddress(contractAddress)},
Topics: [][]common.Hash{{common.HexToHash(price_feeds.RepLogTopic0)}},
}
mockBlockChain.AssertGetEthLogsWithCustomQueryCalledWith(expectedQuery)
})
It("returns error if getting logs fails", func() {
mockBlockChain := fakes.NewMockBlockChain()
mockBlockChain.SetGetLogsReturnLogs([]core.Log{{}})
mockBlockChain.SetGetLogsReturnErr(fakes.FakeError)
fetcher := rep.NewRepFetcher(mockBlockChain)
mockBlockChain.SetGetEthLogsWithCustomQueryErr(fakes.FakeError)
fetcher := rep.NewRepFetcher(mockBlockChain, "rep-contract-address")
_, err := fetcher.FetchRepValue(core.Header{})
@@ -41,7 +51,7 @@ var _ = Describe("Rep fetcher", func() {
It("returns no matching logs error if no logs returned", func() {
mockBlockChain := fakes.NewMockBlockChain()
fetcher := rep.NewRepFetcher(mockBlockChain)
fetcher := rep.NewRepFetcher(mockBlockChain, "rep-contract-address")
_, err := fetcher.FetchRepValue(core.Header{})
@@ -51,8 +61,8 @@ var _ = Describe("Rep fetcher", func() {
It("returns error if more than one matching logs returned", func() {
mockBlockChain := fakes.NewMockBlockChain()
mockBlockChain.SetGetLogsReturnLogs([]core.Log{{}, {}})
fetcher := rep.NewRepFetcher(mockBlockChain)
mockBlockChain.SetGetEthLogsWithCustomQueryReturnLogs([]types.Log{{}, {}})
fetcher := rep.NewRepFetcher(mockBlockChain, "rep-contract-address")
_, err := fetcher.FetchRepValue(core.Header{})
@@ -27,6 +27,7 @@ var _ = Describe("Rep repository", func() {
It("creates a rep when matching header exists", func() {
db := test_config.NewTestDB(core.Node{})
test_config.CleanTestDB(db)
repository := rep.NewRepRepository(db)
header := core.Header{BlockNumber: 12345}
headerRepository := repositories.NewHeaderRepository(db)
@@ -11,8 +11,8 @@ type RepTransformer struct {
repository IRepRepository
}
func NewRepTransformer(chain core.BlockChain, db *postgres.DB) RepTransformer {
fetcher := NewRepFetcher(chain)
func NewRepTransformer(chain core.BlockChain, db *postgres.DB, contractAddress string) RepTransformer {
fetcher := NewRepFetcher(chain, contractAddress)
repository := NewRepRepository(db)
return RepTransformer{
fetcher: fetcher,
@@ -1,10 +1,10 @@
package rep_test
import (
"github.com/ethereum/go-ethereum/common"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
@@ -17,7 +17,7 @@ var _ = Describe("Rep transformer", func() {
It("returns nil if no logs found", func() {
chain := fakes.NewMockBlockChain()
db := test_config.NewTestDB(core.Node{})
transformer := rep.NewRepTransformer(chain, db)
transformer := rep.NewRepTransformer(chain, db, "rep-contract-address")
err := transformer.Execute(core.Header{}, 123)
@@ -26,13 +26,14 @@ var _ = Describe("Rep transformer", func() {
It("creates rep row for found log", func() {
chain := fakes.NewMockBlockChain()
chain.SetGetLogsReturnLogs([]core.Log{{Data: common.ToHex([]byte{1, 2, 3, 4, 5})}})
chain.SetGetEthLogsWithCustomQueryReturnLogs([]types.Log{{Data: []byte{1, 2, 3, 4, 5}}})
db := test_config.NewTestDB(core.Node{})
test_config.CleanTestDB(db)
headerRepository := repositories.NewHeaderRepository(db)
header := core.Header{BlockNumber: 12345}
headerID, err := headerRepository.CreateOrUpdateHeader(header)
Expect(err).NotTo(HaveOccurred())
transformer := rep.NewRepTransformer(chain, db)
transformer := rep.NewRepTransformer(chain, db, "rep-contract-address")
err = transformer.Execute(header, headerID)