forked from cerc-io/ipld-eth-server
Moved fetcher to generic directory (methods have to remain public since it is in seperate package now), added FetchHash method, created ERC20 and generic getters which call the fetcher with specific contract methods (GetTotalSupply, GetBalance, GetAllowance for ERC20 getter, and GetOwner, GetStoppedStatus, GetStringName, GetHashName, GetStringSymbol, GetHashSymbol, and GetDecimals for generic getter). Getter tests cover all but GetBalance and GetAllowance, and also cover all of the Fetcher methods- but with only nil methodArgs. GetAllowance and GetBalance tests are not working against infura and these are the only contract method calls with arguments passed in so I suspect this might be where the issue lies. Have tested GetBalance using previous version of FetchContractData without the variadic input to the Pack method and it fails with the same error so I don’t think it is due to those changes.
This commit is contained in:
@@ -25,7 +25,7 @@ import (
|
||||
|
||||
func TestEveryBlock(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "EveryBlock Suite")
|
||||
RunSpecs(t, "ERC20 EveryBlock Suite")
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func() {
|
||||
|
||||
@@ -1,105 +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 every_block
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
// Interface definition for a Fetcher
|
||||
type ERC20FetcherInterface interface {
|
||||
FetchBigInt(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error)
|
||||
FetchBool(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (bool, error)
|
||||
FetchAddress(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (common.Address, error)
|
||||
GetBlockChain() core.BlockChain
|
||||
}
|
||||
|
||||
// Initializes and returns a Fetcher with the given blockchain
|
||||
func NewFetcher(blockChain core.BlockChain) Fetcher {
|
||||
return Fetcher{
|
||||
BlockChain: blockChain,
|
||||
}
|
||||
}
|
||||
|
||||
// Fetcher struct
|
||||
type Fetcher struct {
|
||||
BlockChain core.BlockChain
|
||||
ContractAbi string
|
||||
ContractAddress string
|
||||
}
|
||||
|
||||
// Fetcher error
|
||||
type fetcherError struct {
|
||||
err string
|
||||
fetchMethod string
|
||||
}
|
||||
|
||||
// Fetcher error method
|
||||
func (fe *fetcherError) Error() string {
|
||||
return fmt.Sprintf("Error fetching %s: %s", fe.fetchMethod, fe.err)
|
||||
}
|
||||
|
||||
// Used to create a new Fetcher error for a given error and fetch method
|
||||
func newFetcherError(err error, fetchMethod string) *fetcherError {
|
||||
e := fetcherError{err.Error(), fetchMethod}
|
||||
log.Println(e.Error())
|
||||
return &e
|
||||
}
|
||||
|
||||
// Method used to fetch big.Int result from contract
|
||||
func (f Fetcher) FetchBigInt(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error) {
|
||||
var result = new(big.Int)
|
||||
err := f.BlockChain.FetchContractData(contractAbi, contractAddress, method, methodArgs, &result, blockNumber)
|
||||
|
||||
if err != nil {
|
||||
return *result, newFetcherError(err, method)
|
||||
}
|
||||
|
||||
return *result, nil
|
||||
}
|
||||
|
||||
// Method used to fetch bool result from contract
|
||||
func (f Fetcher) FetchBool(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (bool, error) {
|
||||
var result = new(bool)
|
||||
err := f.BlockChain.FetchContractData(contractAbi, contractAddress, method, methodArgs, &result, blockNumber)
|
||||
|
||||
if err != nil {
|
||||
return *result, newFetcherError(err, method)
|
||||
}
|
||||
|
||||
return *result, nil
|
||||
}
|
||||
|
||||
// Method used to fetch address result from contract
|
||||
func (f Fetcher) FetchAddress(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (common.Address, error) {
|
||||
var result = new(common.Address)
|
||||
err := f.BlockChain.FetchContractData(contractAbi, contractAddress, method, methodArgs, &result, blockNumber)
|
||||
|
||||
if err != nil {
|
||||
return *result, newFetcherError(err, method)
|
||||
}
|
||||
|
||||
return *result, nil
|
||||
}
|
||||
|
||||
// Getter method for Fetcher's blockchain
|
||||
func (f Fetcher) GetBlockChain() core.BlockChain {
|
||||
return f.BlockChain
|
||||
}
|
||||
@@ -1,176 +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 every_block_test
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
var _ = Describe("ERC20 Fetcher", func() {
|
||||
blockNumber := int64(5502914)
|
||||
|
||||
Describe("totalSupply", func() {
|
||||
It("fetches total supply data from the blockchain with the correct arguments", func() {
|
||||
fakeBlockChain := fakes.NewMockBlockChain()
|
||||
testFetcher := every_block.NewFetcher(fakeBlockChain)
|
||||
testAbi := "testAbi"
|
||||
testContractAddress := "testContractAddress"
|
||||
|
||||
_, err := testFetcher.FetchBigInt("totalSupply", testAbi, testContractAddress, blockNumber, nil)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
expectedResult := big.Int{}
|
||||
expected := &expectedResult
|
||||
fakeBlockChain.AssertFetchContractDataCalledWith(testAbi, testContractAddress, "totalSupply", nil, &expected, blockNumber)
|
||||
})
|
||||
|
||||
It("fetches dai token's total supply at the given block height", func() {
|
||||
infuraIPC := "https://mainnet.infura.io/v3/b09888c1113640cc9ab42750ce750c05"
|
||||
rawRpcClient, err := rpc.Dial(infuraIPC)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, infuraIPC)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
realFetcher := every_block.NewFetcher(blockChain)
|
||||
result, err := realFetcher.FetchBigInt("totalSupply", constants.DaiAbiString, constants.DaiContractAddress, blockNumber, nil)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
expectedResult := big.Int{}
|
||||
expectedResult.SetString("27647235749155415536952630", 10)
|
||||
Expect(result).To(Equal(expectedResult))
|
||||
})
|
||||
|
||||
It("returns an error if the call to the blockchain fails", func() {
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetFetchContractDataErr(fakes.FakeError)
|
||||
errorFetcher := every_block.NewFetcher(blockChain)
|
||||
result, err := errorFetcher.FetchBigInt("totalSupply", "", "", 0, nil)
|
||||
|
||||
Expect(result.String()).To(Equal("0"))
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("totalSupply"))
|
||||
Expect(err.Error()).To(ContainSubstring(fakes.FakeError.Error()))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("stopped", func() {
|
||||
It("checks whether or not the contract has been stopped", func() {
|
||||
fakeBlockChain := fakes.NewMockBlockChain()
|
||||
testFetcher := every_block.NewFetcher(fakeBlockChain)
|
||||
testAbi := "testAbi"
|
||||
testContractAddress := "testContractAddress"
|
||||
|
||||
_, err := testFetcher.FetchBool("stopped", testAbi, testContractAddress, blockNumber, nil)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var expectedResult bool
|
||||
expected := &expectedResult
|
||||
fakeBlockChain.AssertFetchContractDataCalledWith(testAbi, testContractAddress, "stopped", nil, &expected, blockNumber)
|
||||
})
|
||||
|
||||
It("fetches dai token's stopped status at the given block height", func() {
|
||||
infuraIPC := "https://mainnet.infura.io/v3/b09888c1113640cc9ab42750ce750c05"
|
||||
rawRpcClient, err := rpc.Dial(infuraIPC)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, infuraIPC)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
realFetcher := every_block.NewFetcher(blockChain)
|
||||
result, err := realFetcher.FetchBool("stopped", constants.DaiAbiString, constants.DaiContractAddress, blockNumber, nil)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(result).To(Equal(false))
|
||||
})
|
||||
|
||||
It("returns an error if the call to the blockchain fails", func() {
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetFetchContractDataErr(fakes.FakeError)
|
||||
errorFetcher := every_block.NewFetcher(blockChain)
|
||||
result, err := errorFetcher.FetchBool("stopped", "", "", 0, nil)
|
||||
|
||||
Expect(result).To(Equal(false))
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("stopped"))
|
||||
Expect(err.Error()).To(ContainSubstring(fakes.FakeError.Error()))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("owner", func() {
|
||||
It("checks what the contract's owner address is", func() {
|
||||
fakeBlockChain := fakes.NewMockBlockChain()
|
||||
testFetcher := every_block.NewFetcher(fakeBlockChain)
|
||||
testAbi := "testAbi"
|
||||
testContractAddress := "testContractAddress"
|
||||
|
||||
_, err := testFetcher.FetchAddress("owner", testAbi, testContractAddress, blockNumber, nil)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var expectedResult common.Address
|
||||
expected := &expectedResult
|
||||
fakeBlockChain.AssertFetchContractDataCalledWith(testAbi, testContractAddress, "owner", nil, &expected, blockNumber)
|
||||
})
|
||||
|
||||
It("fetches dai token's owner address at the given block height", func() {
|
||||
infuraIPC := "https://mainnet.infura.io/v3/b09888c1113640cc9ab42750ce750c05"
|
||||
rawRpcClient, err := rpc.Dial(infuraIPC)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, infuraIPC)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
realFetcher := every_block.NewFetcher(blockChain)
|
||||
result, err := realFetcher.FetchAddress("owner", constants.DaiAbiString, constants.DaiContractAddress, blockNumber, nil)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
expectedResult := common.HexToAddress("0x0000000000000000000000000000000000000000")
|
||||
Expect(result).To(Equal(expectedResult))
|
||||
})
|
||||
|
||||
It("returns an error if the call to the blockchain fails", func() {
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetFetchContractDataErr(fakes.FakeError)
|
||||
errorFetcher := every_block.NewFetcher(blockChain)
|
||||
result, err := errorFetcher.FetchAddress("owner", "", "", 0, nil)
|
||||
|
||||
expectedResult := new(common.Address)
|
||||
Expect(result).To(Equal(*expectedResult))
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("owner"))
|
||||
Expect(err.Error()).To(ContainSubstring(fakes.FakeError.Error()))
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,64 @@
|
||||
// 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 og 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 Og ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package every_block
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
// Getter serves as a higher level data fetcher that invokes its underlying Fetcher methods for a given contract method
|
||||
|
||||
// Interface definition for a Getter
|
||||
type ERC20GetterInterface interface {
|
||||
GetTotalSupply(contractAbi, contractAddress string, blockNumber int64) (big.Int, error)
|
||||
GetBalance(contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error)
|
||||
GetAllowance(contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error)
|
||||
GetBlockChain() core.BlockChain
|
||||
}
|
||||
|
||||
// Getter struct
|
||||
type Getter struct {
|
||||
fetcher generic.Fetcher
|
||||
}
|
||||
|
||||
// Initializes and returns a Getter with the given blockchain
|
||||
func NewGetter(blockChain core.BlockChain) Getter {
|
||||
return Getter{
|
||||
fetcher: generic.Fetcher{
|
||||
BlockChain: blockChain,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Public getter methods for calling contract methods
|
||||
func (g Getter) GetTotalSupply(contractAbi, contractAddress string, blockNumber int64) (big.Int, error) {
|
||||
return g.fetcher.FetchBigInt("totalSupply", contractAbi, contractAddress, blockNumber, nil)
|
||||
}
|
||||
|
||||
func (g Getter) GetBalance(contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error) {
|
||||
return g.fetcher.FetchBigInt("balanceOf", contractAbi, contractAddress, blockNumber, methodArgs)
|
||||
}
|
||||
|
||||
func (g Getter) GetAllowance(contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error) {
|
||||
return g.fetcher.FetchBigInt("allowance", contractAbi, contractAddress, blockNumber, methodArgs)
|
||||
}
|
||||
|
||||
// Method to retrieve the Getter's blockchain
|
||||
func (g Getter) GetBlockChain() core.BlockChain {
|
||||
return g.fetcher.BlockChain
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// 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 every_block_test
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||
)
|
||||
|
||||
var _ = Describe("ERC20 Getter", func() {
|
||||
blockNumber := int64(5502914)
|
||||
|
||||
Describe("totalSupply", func() {
|
||||
It("gets total supply data from the blockchain with the correct arguments", func() {
|
||||
fakeBlockChain := fakes.NewMockBlockChain()
|
||||
testGetter := every_block.NewGetter(fakeBlockChain)
|
||||
testAbi := "testAbi"
|
||||
testContractAddress := "testContractAddress"
|
||||
|
||||
_, err := testGetter.GetTotalSupply(testAbi, testContractAddress, blockNumber)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
expectedResult := big.Int{}
|
||||
expected := &expectedResult
|
||||
fakeBlockChain.AssertFetchContractDataCalledWith(testAbi, testContractAddress, "totalSupply", nil, &expected, blockNumber)
|
||||
})
|
||||
|
||||
It("gets dai token's total supply at the given block height", func() {
|
||||
infuraIPC := "https://mainnet.infura.io/v3/b09888c1113640cc9ab42750ce750c05"
|
||||
rawRpcClient, err := rpc.Dial(infuraIPC)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, infuraIPC)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
realGetter := every_block.NewGetter(blockChain)
|
||||
result, err := realGetter.GetTotalSupply(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
expectedResult := big.Int{}
|
||||
expectedResult.SetString("27647235749155415536952630", 10)
|
||||
Expect(result).To(Equal(expectedResult))
|
||||
})
|
||||
|
||||
It("returns an error if the call to the blockchain fails", func() {
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetFetchContractDataErr(fakes.FakeError)
|
||||
errorGetter := every_block.NewGetter(blockChain)
|
||||
result, err := errorGetter.GetTotalSupply("", "", 0)
|
||||
|
||||
Expect(result.String()).To(Equal("0"))
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("totalSupply"))
|
||||
Expect(err.Error()).To(ContainSubstring(fakes.FakeError.Error()))
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -99,4 +99,4 @@ func (tsp *ERC20TokenRepository) MissingSupplyBlocks(startingBlock, highestBlock
|
||||
return []int64{}, newRepositoryError(err, MissingBlockError, startingBlock)
|
||||
}
|
||||
return blockNumbers, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,9 +192,9 @@ func supplyModel(blockNumber int64, tokenAddress, supplyValue string) every_bloc
|
||||
|
||||
func createTokenSupplyFor(repository every_block.ERC20TokenRepository, blockNumber int64, tokenAddress string) {
|
||||
err := repository.CreateSupply(every_block.TokenSupply{
|
||||
BlockNumber: blockNumber,
|
||||
BlockNumber: blockNumber,
|
||||
TokenAddress: tokenAddress,
|
||||
Value: "0",
|
||||
Value: "0",
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
)
|
||||
|
||||
type Transformer struct {
|
||||
Fetcher ERC20FetcherInterface
|
||||
Getter ERC20GetterInterface
|
||||
Repository ERC20RepositoryInterface
|
||||
Config erc20_watcher.ContractConfig
|
||||
}
|
||||
@@ -38,11 +38,11 @@ type TokenSupplyTransformerInitializer struct {
|
||||
Config erc20_watcher.ContractConfig
|
||||
}
|
||||
|
||||
func (i TokenSupplyTransformerInitializer) NewTokenSupplyTransformer(db *postgres.DB, blockchain core.BlockChain) shared.Transformer {
|
||||
fetcher := NewFetcher(blockchain)
|
||||
func (i TokenSupplyTransformerInitializer) NewTokenSupplyTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
|
||||
getter := NewGetter(blockChain)
|
||||
repository := ERC20TokenRepository{DB: db}
|
||||
transformer := Transformer{
|
||||
Fetcher: &fetcher,
|
||||
Getter: &getter,
|
||||
Repository: &repository,
|
||||
Config: i.Config,
|
||||
}
|
||||
@@ -51,8 +51,8 @@ func (i TokenSupplyTransformerInitializer) NewTokenSupplyTransformer(db *postgre
|
||||
}
|
||||
|
||||
const (
|
||||
FetchingBlocksError = "Error fetching missing blocks starting at block number %d: %s"
|
||||
FetchingSupplyError = "Error fetching supply for block %d: %s"
|
||||
FetchingBlocksError = "Error getting missing blocks starting at block number %d: %s"
|
||||
GetSupplyError = "Error getting supply for block %d: %s"
|
||||
CreateSupplyError = "Error inserting token_supply for block %d: %s"
|
||||
)
|
||||
|
||||
@@ -74,8 +74,8 @@ func newTransformerError(err error, blockNumber int64, msg string) error {
|
||||
|
||||
func (t Transformer) Execute() error {
|
||||
var upperBoundBlock int64
|
||||
blockchain := t.Fetcher.GetBlockChain()
|
||||
lastBlock := blockchain.LastBlock().Int64()
|
||||
blockChain := t.Getter.GetBlockChain()
|
||||
lastBlock := blockChain.LastBlock().Int64()
|
||||
|
||||
if t.Config.LastBlock == -1 {
|
||||
upperBoundBlock = lastBlock
|
||||
@@ -93,14 +93,14 @@ func (t Transformer) Execute() error {
|
||||
}
|
||||
|
||||
// Fetch supply for missing blocks
|
||||
log.Printf("Fetching totalSupply for %d blocks", len(blocks))
|
||||
log.Printf("Gets totalSupply for %d blocks", len(blocks))
|
||||
|
||||
// For each block missing total supply, create supply model and feed the missing data into the repository
|
||||
for _, blockNumber := range blocks {
|
||||
totalSupply, err := t.Fetcher.FetchBigInt("totalSupply", t.Config.Abi, t.Config.Address, blockNumber, nil)
|
||||
totalSupply, err := t.Getter.GetTotalSupply(t.Config.Abi, t.Config.Address, blockNumber)
|
||||
|
||||
if err != nil {
|
||||
return newTransformerError(err, blockNumber, FetchingSupplyError)
|
||||
return newTransformerError(err, blockNumber, GetSupplyError)
|
||||
}
|
||||
// Create the supply model
|
||||
model := createTokenSupplyModel(totalSupply, t.Config.Address, blockNumber)
|
||||
|
||||
@@ -38,7 +38,7 @@ var testContractConfig = erc20_watcher.ContractConfig{
|
||||
var config = testContractConfig
|
||||
|
||||
var _ = Describe("Everyblock transformer", func() {
|
||||
var fetcher mocks.Fetcher
|
||||
var getter mocks.Getter
|
||||
var repository mocks.ERC20TokenRepository
|
||||
var transformer every_block.Transformer
|
||||
var blockChain *fakes.MockBlockChain
|
||||
@@ -51,14 +51,14 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
BeforeEach(func() {
|
||||
blockChain = fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(&defaultLastBlock)
|
||||
fetcher = mocks.Fetcher{BlockChain: blockChain}
|
||||
fetcher.SetSupply(initialSupply)
|
||||
getter = mocks.NewGetter(blockChain)
|
||||
getter.Fetcher.SetSupply(initialSupply)
|
||||
repository = mocks.ERC20TokenRepository{}
|
||||
repository.SetMissingSupplyBlocks([]int64{config.FirstBlock})
|
||||
//setting the mock repository to return the first block as the missing blocks
|
||||
|
||||
transformer = every_block.Transformer{
|
||||
Fetcher: &fetcher,
|
||||
Getter: &getter,
|
||||
Repository: &repository,
|
||||
}
|
||||
transformer.SetConfiguration(config)
|
||||
@@ -68,10 +68,10 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
err := transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(len(fetcher.FetchedBlocks)).To(Equal(1))
|
||||
Expect(fetcher.FetchedBlocks).To(ConsistOf(config.FirstBlock))
|
||||
Expect(fetcher.Abi).To(Equal(config.Abi))
|
||||
Expect(fetcher.ContractAddress).To(Equal(config.Address))
|
||||
Expect(len(getter.Fetcher.FetchedBlocks)).To(Equal(1))
|
||||
Expect(getter.Fetcher.FetchedBlocks).To(ConsistOf(config.FirstBlock))
|
||||
Expect(getter.Fetcher.Abi).To(Equal(config.Abi))
|
||||
Expect(getter.Fetcher.ContractAddress).To(Equal(config.Address))
|
||||
|
||||
Expect(repository.StartingBlock).To(Equal(config.FirstBlock))
|
||||
Expect(repository.EndingBlock).To(Equal(config.LastBlock))
|
||||
@@ -93,10 +93,10 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
err := transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(len(fetcher.FetchedBlocks)).To(Equal(3))
|
||||
Expect(fetcher.FetchedBlocks).To(ConsistOf(config.FirstBlock, config.FirstBlock+1, config.FirstBlock+2))
|
||||
Expect(fetcher.Abi).To(Equal(config.Abi))
|
||||
Expect(fetcher.ContractAddress).To(Equal(config.Address))
|
||||
Expect(len(getter.Fetcher.FetchedBlocks)).To(Equal(3))
|
||||
Expect(getter.Fetcher.FetchedBlocks).To(ConsistOf(config.FirstBlock, config.FirstBlock+1, config.FirstBlock+2))
|
||||
Expect(getter.Fetcher.Abi).To(Equal(config.Abi))
|
||||
Expect(getter.Fetcher.ContractAddress).To(Equal(config.Address))
|
||||
|
||||
Expect(len(repository.TotalSuppliesCreated)).To(Equal(3))
|
||||
Expect(repository.TotalSuppliesCreated[0].Value).To(Equal(initialSupplyPlusOne))
|
||||
@@ -110,9 +110,9 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
err := transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(fetcher.FetchedBlocks).To(ConsistOf(testContractConfig.FirstBlock))
|
||||
Expect(fetcher.Abi).To(Equal(testContractConfig.Abi))
|
||||
Expect(fetcher.ContractAddress).To(Equal(testContractConfig.Address))
|
||||
Expect(getter.Fetcher.FetchedBlocks).To(ConsistOf(testContractConfig.FirstBlock))
|
||||
Expect(getter.Fetcher.Abi).To(Equal(testContractConfig.Abi))
|
||||
Expect(getter.Fetcher.ContractAddress).To(Equal(testContractConfig.Address))
|
||||
|
||||
Expect(repository.StartingBlock).To(Equal(testContractConfig.FirstBlock))
|
||||
Expect(repository.EndingBlock).To(Equal(testContractConfig.LastBlock))
|
||||
@@ -146,22 +146,22 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
failureRepository := mocks.FailureRepository{}
|
||||
failureRepository.SetMissingSupplyBlocksFail(true)
|
||||
transformer = every_block.Transformer{
|
||||
Fetcher: &fetcher,
|
||||
Getter: &getter,
|
||||
Repository: &failureRepository,
|
||||
}
|
||||
err := transformer.Execute()
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring(fakes.FakeError.Error()))
|
||||
Expect(err.Error()).To(ContainSubstring("fetching missing blocks"))
|
||||
Expect(err.Error()).To(ContainSubstring("getting missing blocks"))
|
||||
})
|
||||
|
||||
It("returns an error if the call to the blockChain fails", func() {
|
||||
failureBlockchain := fakes.NewMockBlockChain()
|
||||
failureBlockchain.SetLastBlock(&defaultLastBlock)
|
||||
failureBlockchain.SetFetchContractDataErr(fakes.FakeError)
|
||||
fetcher := every_block.NewFetcher(failureBlockchain)
|
||||
getter := every_block.NewGetter(failureBlockchain)
|
||||
transformer = every_block.Transformer{
|
||||
Fetcher: &fetcher,
|
||||
Getter: &getter,
|
||||
Repository: &repository,
|
||||
}
|
||||
err := transformer.Execute()
|
||||
@@ -176,7 +176,7 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
failureRepository.SetCreateSupplyFail(true)
|
||||
|
||||
transformer = every_block.Transformer{
|
||||
Fetcher: &fetcher,
|
||||
Getter: &getter,
|
||||
Repository: &failureRepository,
|
||||
}
|
||||
err := transformer.Execute()
|
||||
|
||||
Reference in New Issue
Block a user