From aa2068bd0814f72217fef31053c219342641d27c Mon Sep 17 00:00:00 2001 From: Ian Norden Date: Tue, 28 Aug 2018 12:50:53 -0500 Subject: [PATCH] adjust retriever to pull token holder addresses from Transfer and Approval events (iterating over Approvals might be redundant); edit Makefile to import new missing dependencies of go-ethereum/accounts/keystore, organizing mocks and adding event related mocks and filters --- Makefile | 1 + examples/constants/constants.go | 20 + .../event_triggered/converter_test.go | 2 +- .../erc20_watcher/every_block/transformer.go | 2 +- examples/generic/retriever.go | 100 +++-- examples/mocks/event_repo.go | 71 ++++ examples/mocks/every_block_repo.go | 75 ++++ examples/mocks/failure_repo.go | 116 ++++++ examples/mocks/fetcher.go | 159 ++++++++ examples/mocks/getter.go | 78 ++++ examples/mocks/mocks.go | 369 ------------------ 11 files changed, 597 insertions(+), 396 deletions(-) create mode 100644 examples/mocks/event_repo.go create mode 100644 examples/mocks/every_block_repo.go create mode 100644 examples/mocks/failure_repo.go create mode 100644 examples/mocks/fetcher.go create mode 100644 examples/mocks/getter.go delete mode 100644 examples/mocks/mocks.go diff --git a/Makefile b/Makefile index 30ddcc29..5769da09 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ lint: .PHONY: test test: | $(GINKGO) $(LINT) + go get -t ./... go vet ./... go fmt ./... $(GINKGO) -r diff --git a/examples/constants/constants.go b/examples/constants/constants.go index 77a9aa5e..bb79c9b8 100644 --- a/examples/constants/constants.go +++ b/examples/constants/constants.go @@ -17,6 +17,8 @@ package constants import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/vulcanize/vulcanizedb/examples/generic/helpers" + "github.com/vulcanize/vulcanizedb/pkg/core" + "github.com/vulcanize/vulcanizedb/pkg/filters" "github.com/vulcanize/vulcanizedb/pkg/geth" "log" ) @@ -53,3 +55,21 @@ func init() { // Hashed event signatures var TransferEventSignature = helpers.GenerateSignature("Transfer(address,address,uint)") var ApprovalEventSignature = helpers.GenerateSignature("Approval(address,address,uint)") + +// Filters +var DaiFilters = []filters.LogFilter{ + { + Name: "Transfers", + FromBlock: 0, + ToBlock: -1, + Address: DaiContractAddress, + Topics: core.Topics{TransferEventSignature}, + }, + { + Name: "Approvals", + FromBlock: 0, + ToBlock: -1, + Address: DaiContractAddress, + Topics: core.Topics{ApprovalEventSignature}, + }, +} diff --git a/examples/erc20_watcher/event_triggered/converter_test.go b/examples/erc20_watcher/event_triggered/converter_test.go index cb2f1b2a..8803c003 100644 --- a/examples/erc20_watcher/event_triggered/converter_test.go +++ b/examples/erc20_watcher/event_triggered/converter_test.go @@ -88,7 +88,7 @@ var approvalEvent = core.WatchedEvent{ Address: constants.DaiContractAddress, TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae", Index: 110, - Topic0: constants.TransferEventSignature, + Topic0: constants.ApprovalEventSignature, Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21", Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391", Topic3: "", diff --git a/examples/erc20_watcher/every_block/transformer.go b/examples/erc20_watcher/every_block/transformer.go index 4c88d733..72db2adc 100644 --- a/examples/erc20_watcher/every_block/transformer.go +++ b/examples/erc20_watcher/every_block/transformer.go @@ -125,7 +125,7 @@ func (t Transformer) Execute() error { // Retrieve all token holder addresses for the given contract configuration - tokenHolderAddresses, err := t.Retriever.RetrieveContractAssociatedAddresses() + tokenHolderAddresses, err := t.Retriever.RetrieveTokenHolderAddresses() if err != nil { return newTransformerError(err, t.Config.FirstBlock, FetchingTokenAddressesError) } diff --git a/examples/generic/retriever.go b/examples/generic/retriever.go index 309d558c..6cc14f43 100644 --- a/examples/generic/retriever.go +++ b/examples/generic/retriever.go @@ -25,8 +25,8 @@ import ( // address in an attempt to generate a list of token holder addresses type RetrieverInterface interface { - RetrieveSendingAddresses() ([]string, error) - RetrieveReceivingAddresses() ([]string, error) + retrieveTransferEventAddresses() ([][2]string, error) + retrieveApprovalEventAddresses() ([][2]string, error) RetrieveContractAssociatedAddresses() (map[common.Address]bool, error) } @@ -55,8 +55,10 @@ func newRetrieverError(err error, msg string, address string) error { // Constant error definitions const ( - GetSenderError = "Error fetching addresses receiving from contract %s: %s" - GetReceiverError = "Error fetching addresses sending to contract %s: %s" + GetSendersError = "Error fetching token senders from contract %s: %s" + GetReceiversError = "Error fetching token receivers from contract %s: %s" + GetOwnersError = "Error fetching token owners from contract %s: %s" + GetSpendersError = "Error fetching token spenders from contract %s: %s" ) func NewRetriever(db *postgres.DB, address string) Retriever { @@ -66,59 +68,107 @@ func NewRetriever(db *postgres.DB, address string) Retriever { } } -func (rt Retriever) RetrieveReceivingAddresses() ([]string, error) { +func (rt Retriever) retrieveTokenSenders() ([]string, error) { - receiversFromContract := make([]string, 0) + senders := make([]string, 0) err := rt.Database.DB.Select( - &receiversFromContract, - `SELECT tx_to FROM TRANSACTIONS - WHERE tx_from = $1 - LIMIT 20`, + &senders, + `SELECT from_address FROM token_transfers + WHERE token_address = $1`, rt.ContractAddress, ) if err != nil { - return []string{}, newRetrieverError(err, GetReceiverError, rt.ContractAddress) + return []string{}, newRetrieverError(err, GetSendersError, rt.ContractAddress) } - return receiversFromContract, err + return senders, err } -func (rt Retriever) RetrieveSendingAddresses() ([]string, error) { +func (rt Retriever) retrieveTokenReceivers() ([]string, error) { - sendersToContract := make([]string, 0) + receivers := make([]string, 0) err := rt.Database.DB.Select( - &sendersToContract, - `SELECT tx_from FROM TRANSACTIONS - WHERE tx_to = $1 - LIMIT 20`, + &receivers, + `SELECT to_address FROM token_transfers + WHERE token_address = $1`, rt.ContractAddress, ) if err != nil { - return []string{}, newRetrieverError(err, GetSenderError, rt.ContractAddress) + return []string{}, newRetrieverError(err, GetReceiversError, rt.ContractAddress) } - return sendersToContract, err + return receivers, err } -func (rt Retriever) RetrieveContractAssociatedAddresses() (map[common.Address]bool, error) { +func (rt Retriever) retrieveTokenOwners() ([]string, error) { - sending, err := rt.RetrieveSendingAddresses() + owners := make([]string, 0) + + err := rt.Database.DB.Select( + &owners, + `SELECT owner FROM token_approvals + WHERE token_address = $1`, + rt.ContractAddress, + ) + if err != nil { + return []string{}, newRetrieverError(err, GetOwnersError, rt.ContractAddress) + } + return owners, err +} + +func (rt Retriever) retrieveTokenSpenders() ([]string, error) { + + spenders := make([]string, 0) + + err := rt.Database.DB.Select( + &spenders, + `SELECT spender FROM token_approvals + WHERE token_address = $1`, + rt.ContractAddress, + ) + if err != nil { + return []string{}, newRetrieverError(err, GetSpendersError, rt.ContractAddress) + } + return spenders, err +} + +func (rt Retriever) RetrieveTokenHolderAddresses() (map[common.Address]bool, error) { + + senders, err := rt.retrieveTokenSenders() if err != nil { return nil, err } - receiving, err := rt.RetrieveReceivingAddresses() + receivers, err := rt.retrieveTokenReceivers() + if err != nil { + return nil, err + } + + owners, err := rt.retrieveTokenOwners() + if err != nil { + return nil, err + } + + spenders, err := rt.retrieveTokenSenders() if err != nil { return nil, err } contractAddresses := make(map[common.Address]bool) - for _, addr := range sending { + for _, addr := range senders { contractAddresses[common.HexToAddress(addr)] = true } - for _, addr := range receiving { + for _, addr := range receivers { + contractAddresses[common.HexToAddress(addr)] = true + } + + for _, addr := range owners { + contractAddresses[common.HexToAddress(addr)] = true + } + + for _, addr := range spenders { contractAddresses[common.HexToAddress(addr)] = true } diff --git a/examples/mocks/event_repo.go b/examples/mocks/event_repo.go new file mode 100644 index 00000000..b9997def --- /dev/null +++ b/examples/mocks/event_repo.go @@ -0,0 +1,71 @@ +// 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 mocks + +import ( + "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered" + "github.com/vulcanize/vulcanizedb/pkg/core" + "github.com/vulcanize/vulcanizedb/pkg/filters" +) + +type MockWatchedEventsRepository struct { + watchedEvents []*core.WatchedEvent + Names []string +} + +func (mwer *MockWatchedEventsRepository) SetWatchedEvents(watchedEvents []*core.WatchedEvent) { + mwer.watchedEvents = watchedEvents +} + +func (mwer *MockWatchedEventsRepository) GetWatchedEvents(name string) ([]*core.WatchedEvent, error) { + mwer.Names = append(mwer.Names, name) + result := mwer.watchedEvents + // clear watched events once returned so same events are returned for every filter while testing + mwer.watchedEvents = []*core.WatchedEvent{} + return result, nil +} + +type MockTransferRepo struct { + LogMakes []event_triggered.TransferModel + VulcanizeLogIDs []int64 +} + +func (molr *MockTransferRepo) Create(offerModel event_triggered.TransferModel, vulcanizeLogId int64) error { + molr.LogMakes = append(molr.LogMakes, offerModel) + molr.VulcanizeLogIDs = append(molr.VulcanizeLogIDs, vulcanizeLogId) + return nil +} + +type MockApprovalRepo struct { + LogKills []event_triggered.ApprovalModel + VulcanizeLogIDs []int64 +} + +func (molk *MockApprovalRepo) Create(model event_triggered.ApprovalModel, vulcanizeLogID int64) error { + molk.LogKills = append(molk.LogKills, model) + molk.VulcanizeLogIDs = append(molk.VulcanizeLogIDs, vulcanizeLogID) + return nil +} + +type MockFilterRepository struct { +} + +func (MockFilterRepository) CreateFilter(filter filters.LogFilter) error { + panic("implement me") +} + +func (MockFilterRepository) GetFilter(name string) (filters.LogFilter, error) { + panic("implement me") +} diff --git a/examples/mocks/every_block_repo.go b/examples/mocks/every_block_repo.go new file mode 100644 index 00000000..cf58f0db --- /dev/null +++ b/examples/mocks/every_block_repo.go @@ -0,0 +1,75 @@ +// 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 mocks + +import ( + "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block" +) + +type ERC20TokenRepository struct { + TotalSuppliesCreated []every_block.TokenSupply + MissingSupplyBlockNumbers []int64 + TotalBalancesCreated []every_block.TokenBalance + MissingBalanceBlockNumbers []int64 + TotalAllowancesCreated []every_block.TokenAllowance + MissingAllowanceBlockNumbers []int64 + StartingBlock int64 + EndingBlock int64 +} + +func (fr *ERC20TokenRepository) CreateSupply(supply every_block.TokenSupply) error { + fr.TotalSuppliesCreated = append(fr.TotalSuppliesCreated, supply) + return nil +} + +func (fr *ERC20TokenRepository) CreateBalance(balance every_block.TokenBalance) error { + fr.TotalBalancesCreated = append(fr.TotalBalancesCreated, balance) + return nil +} + +func (fr *ERC20TokenRepository) CreateAllowance(allowance every_block.TokenAllowance) error { + fr.TotalAllowancesCreated = append(fr.TotalAllowancesCreated, allowance) + return nil +} + +func (fr *ERC20TokenRepository) MissingSupplyBlocks(startingBlock, highestBlock int64, tokenAddress string) ([]int64, error) { + fr.StartingBlock = startingBlock + fr.EndingBlock = highestBlock + return fr.MissingSupplyBlockNumbers, nil +} + +func (fr *ERC20TokenRepository) MissingBalanceBlocks(startingBlock, highestBlock int64, tokenAddress, holderAddress string) ([]int64, error) { + fr.StartingBlock = startingBlock + fr.EndingBlock = highestBlock + return fr.MissingBalanceBlockNumbers, nil +} + +func (fr *ERC20TokenRepository) MissingAllowanceBlocks(startingBlock, highestBlock int64, tokenAddress, holderAddress, spenderAddress string) ([]int64, error) { + fr.StartingBlock = startingBlock + fr.EndingBlock = highestBlock + return fr.MissingAllowanceBlockNumbers, nil +} + +func (fr *ERC20TokenRepository) SetMissingSupplyBlocks(missingBlocks []int64) { + fr.MissingSupplyBlockNumbers = missingBlocks +} + +func (fr *ERC20TokenRepository) SetMissingBalanceBlocks(missingBlocks []int64) { + fr.MissingBalanceBlockNumbers = missingBlocks +} + +func (fr *ERC20TokenRepository) SetMissingAllowanceBlocks(missingBlocks []int64) { + fr.MissingAllowanceBlockNumbers = missingBlocks +} diff --git a/examples/mocks/failure_repo.go b/examples/mocks/failure_repo.go new file mode 100644 index 00000000..315296d4 --- /dev/null +++ b/examples/mocks/failure_repo.go @@ -0,0 +1,116 @@ +// 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 mocks + +import ( + "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block" + "github.com/vulcanize/vulcanizedb/pkg/fakes" +) + +type FailureRepository struct { + createSupplyFail bool + createBalanceFail bool + createAllowanceFail bool + missingSupplyBlocksFail bool + missingBalanceBlocksFail bool + missingAllowanceBlocksFail bool + missingSupplyBlocksNumbers []int64 + missingBalanceBlocksNumbers []int64 + missingAllowanceBlocksNumbers []int64 +} + +func (fr *FailureRepository) CreateSupply(supply every_block.TokenSupply) error { + if fr.createSupplyFail { + return fakes.FakeError + } else { + return nil + } +} + +func (fr *FailureRepository) CreateBalance(balance every_block.TokenBalance) error { + if fr.createBalanceFail { + return fakes.FakeError + } else { + return nil + } +} + +func (fr *FailureRepository) CreateAllowance(allowance every_block.TokenAllowance) error { + if fr.createAllowanceFail { + return fakes.FakeError + } else { + return nil + } +} + +func (fr *FailureRepository) MissingSupplyBlocks(startingBlock, highestBlock int64, tokenAddress string) ([]int64, error) { + if fr.missingSupplyBlocksFail { + return []int64{}, fakes.FakeError + } else { + return fr.missingSupplyBlocksNumbers, nil + } +} + +func (fr *FailureRepository) MissingBalanceBlocks(startingBlock, highestBlock int64, tokenAddress, holderAddress string) ([]int64, error) { + if fr.missingBalanceBlocksFail { + return []int64{}, fakes.FakeError + } else { + return fr.missingBalanceBlocksNumbers, nil + } +} + +func (fr *FailureRepository) MissingAllowanceBlocks(startingBlock, highestBlock int64, tokenAddress, holderAddress, spenderAddress string) ([]int64, error) { + if fr.missingAllowanceBlocksFail { + return []int64{}, fakes.FakeError + } else { + return fr.missingAllowanceBlocksNumbers, nil + } +} + +func (fr *FailureRepository) SetCreateSupplyFail(fail bool) { + fr.createSupplyFail = fail +} + +func (fr *FailureRepository) SetCreateBalanceFail(fail bool) { + fr.createBalanceFail = fail +} + +func (fr *FailureRepository) SetCreateAllowanceFail(fail bool) { + fr.createAllowanceFail = fail +} + +func (fr *FailureRepository) SetMissingSupplyBlocksFail(fail bool) { + fr.missingSupplyBlocksFail = fail +} + +func (fr *FailureRepository) SetMissingBalanceBlocksFail(fail bool) { + fr.missingBalanceBlocksFail = fail +} + +func (fr *FailureRepository) SetMissingAllowanceBlocksFail(fail bool) { + fr.missingAllowanceBlocksFail = fail +} + +func (fr *FailureRepository) SetMissingSupplyBlocks(missingBlocks []int64) { + fr.missingSupplyBlocksNumbers = missingBlocks +} + +func (fr *FailureRepository) SetMissingBalanceBlocks(missingBlocks []int64) { + fr.missingBalanceBlocksNumbers = missingBlocks +} + +func (fr *FailureRepository) SetMissingAllowanceBlocks(missingBlocks []int64) { + fr.missingAllowanceBlocksNumbers = missingBlocks +} diff --git a/examples/mocks/fetcher.go b/examples/mocks/fetcher.go new file mode 100644 index 00000000..4104577c --- /dev/null +++ b/examples/mocks/fetcher.go @@ -0,0 +1,159 @@ +// 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 mocks + +import ( + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/vulcanize/vulcanizedb/pkg/core" + "reflect" +) + +type Fetcher struct { + ContractAddress string + Abi string + FetchedBlocks []int64 + BlockChain core.BlockChain + supply big.Int + balance map[string]*big.Int + allowance map[string]map[string]*big.Int + owner common.Address + stopped bool + stringName string + hashName common.Hash + stringSymbol string + hashSymbol common.Hash +} + +func (f *Fetcher) SetSupply(supply string) { + f.supply.SetString(supply, 10) +} + +func (f Fetcher) GetBlockChain() core.BlockChain { + return f.BlockChain +} + +func (f *Fetcher) FetchBigInt(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error) { + + f.Abi = contractAbi + f.ContractAddress = contractAddress + f.FetchedBlocks = append(f.FetchedBlocks, blockNumber) + + accumulator := big.NewInt(1) + + if method == "totalSupply" { + f.supply.Add(&f.supply, accumulator) + + return f.supply, nil + } + + if method == "balanceOf" { + rfl := reflect.ValueOf(methodArgs[0]) + tokenHolderAddr := rfl.Interface().(string) + pnt := f.balance[tokenHolderAddr] + f.balance[tokenHolderAddr].Add(pnt, accumulator) + + return *f.balance[tokenHolderAddr], nil + } + + if method == "allowance" { + rfl1 := reflect.ValueOf(methodArgs[0]) + rfl2 := reflect.ValueOf(methodArgs[1]) + tokenHolderAddr := rfl1.Interface().(string) + spenderAddr := rfl2.Interface().(string) + pnt := f.allowance[tokenHolderAddr][spenderAddr] + f.allowance[tokenHolderAddr][spenderAddr].Add(pnt, accumulator) + + return *f.allowance[tokenHolderAddr][spenderAddr], nil + } + + return *big.NewInt(0), errors.New("invalid method argument") + +} + +func (f *Fetcher) FetchBool(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (bool, error) { + + f.Abi = contractAbi + f.ContractAddress = contractAddress + f.FetchedBlocks = append(f.FetchedBlocks, blockNumber) + + b := true + + if method == "stopped" { + f.stopped = b + + return f.stopped, nil + } + + return false, errors.New("invalid method argument") +} + +func (f *Fetcher) FetchAddress(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (common.Address, error) { + + f.Abi = contractAbi + f.ContractAddress = contractAddress + f.FetchedBlocks = append(f.FetchedBlocks, blockNumber) + + adr := common.StringToAddress("test_address") + + if method == "owner" { + f.owner = adr + + return f.owner, nil + } + return common.StringToAddress(""), errors.New("invalid method argument") +} + +func (f *Fetcher) FetchString(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (string, error) { + + f.Abi = contractAbi + f.ContractAddress = contractAddress + f.FetchedBlocks = append(f.FetchedBlocks, blockNumber) + + if method == "name" { + f.stringName = "test_name" + + return f.stringName, nil + } + + if method == "symbol" { + f.stringSymbol = "test_symbol" + + return f.stringSymbol, nil + } + return "", errors.New("invalid method argument") +} + +func (f *Fetcher) FetchHash(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (common.Hash, error) { + + f.Abi = contractAbi + f.ContractAddress = contractAddress + f.FetchedBlocks = append(f.FetchedBlocks, blockNumber) + + if method == "name" { + f.hashName = common.StringToHash("test_name") + + return f.hashName, nil + } + + if method == "symbol" { + f.hashSymbol = common.StringToHash("test_symbol") + + return f.hashSymbol, nil + } + return common.StringToHash(""), errors.New("invalid method argument") +} diff --git a/examples/mocks/getter.go b/examples/mocks/getter.go new file mode 100644 index 00000000..ff147b5b --- /dev/null +++ b/examples/mocks/getter.go @@ -0,0 +1,78 @@ +// 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 mocks + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/vulcanize/vulcanizedb/pkg/core" +) + +type Getter struct { + Fetcher Fetcher +} + +func NewGetter(blockChain core.BlockChain) Getter { + return Getter{ + Fetcher: Fetcher{ + BlockChain: blockChain, + }, + } +} + +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) +} + +func (g *Getter) GetOwner(contractAbi, contractAddress string, blockNumber int64) (common.Address, error) { + return g.Fetcher.FetchAddress("owner", contractAbi, contractAddress, blockNumber, nil) +} + +func (g *Getter) GetStoppedStatus(contractAbi, contractAddress string, blockNumber int64) (bool, error) { + return g.Fetcher.FetchBool("stopped", contractAbi, contractAddress, blockNumber, nil) +} + +func (g *Getter) GetStringName(contractAbi, contractAddress string, blockNumber int64) (string, error) { + return g.Fetcher.FetchString("name", contractAbi, contractAddress, blockNumber, nil) +} + +func (g *Getter) GetHashName(contractAbi, contractAddress string, blockNumber int64) (common.Hash, error) { + return g.Fetcher.FetchHash("name", contractAbi, contractAddress, blockNumber, nil) +} + +func (g *Getter) GetStringSymbol(contractAbi, contractAddress string, blockNumber int64) (string, error) { + return g.Fetcher.FetchString("symbol", contractAbi, contractAddress, blockNumber, nil) +} + +func (g *Getter) GetHashSymbol(contractAbi, contractAddress string, blockNumber int64) (common.Hash, error) { + return g.Fetcher.FetchHash("symbol", contractAbi, contractAddress, blockNumber, nil) +} + +func (g *Getter) GetDecimals(contractAbi, contractAddress string, blockNumber int64) (big.Int, error) { + return g.Fetcher.FetchBigInt("decimals", contractAbi, contractAddress, blockNumber, nil) +} + +func (g *Getter) GetBlockChain() core.BlockChain { + return g.Fetcher.BlockChain +} diff --git a/examples/mocks/mocks.go b/examples/mocks/mocks.go deleted file mode 100644 index 063310b1..00000000 --- a/examples/mocks/mocks.go +++ /dev/null @@ -1,369 +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 mocks - -import ( - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block" - "github.com/vulcanize/vulcanizedb/pkg/core" - "github.com/vulcanize/vulcanizedb/pkg/fakes" - "reflect" -) - -type Fetcher struct { - ContractAddress string - Abi string - FetchedBlocks []int64 - BlockChain core.BlockChain - supply big.Int - balance map[string]*big.Int - allowance map[string]map[string]*big.Int - owner common.Address - stopped bool - stringName string - hashName common.Hash - stringSymbol string - hashSymbol common.Hash -} - -func (f *Fetcher) SetSupply(supply string) { - f.supply.SetString(supply, 10) -} - -func (f Fetcher) GetBlockChain() core.BlockChain { - return f.BlockChain -} - -func (f *Fetcher) FetchBigInt(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error) { - - f.Abi = contractAbi - f.ContractAddress = contractAddress - f.FetchedBlocks = append(f.FetchedBlocks, blockNumber) - - accumulator := big.NewInt(1) - - if method == "totalSupply" { - f.supply.Add(&f.supply, accumulator) - - return f.supply, nil - } - - if method == "balanceOf" { - rfl := reflect.ValueOf(methodArgs[0]) - tokenHolderAddr := rfl.Interface().(string) - pnt := f.balance[tokenHolderAddr] - f.balance[tokenHolderAddr].Add(pnt, accumulator) - - return *f.balance[tokenHolderAddr], nil - } - - if method == "allowance" { - rfl1 := reflect.ValueOf(methodArgs[0]) - rfl2 := reflect.ValueOf(methodArgs[1]) - tokenHolderAddr := rfl1.Interface().(string) - spenderAddr := rfl2.Interface().(string) - pnt := f.allowance[tokenHolderAddr][spenderAddr] - f.allowance[tokenHolderAddr][spenderAddr].Add(pnt, accumulator) - - return *f.allowance[tokenHolderAddr][spenderAddr], nil - } - - return *big.NewInt(0), errors.New("invalid method argument") - -} - -func (f *Fetcher) FetchBool(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (bool, error) { - - f.Abi = contractAbi - f.ContractAddress = contractAddress - f.FetchedBlocks = append(f.FetchedBlocks, blockNumber) - - b := true - - if method == "stopped" { - f.stopped = b - - return f.stopped, nil - } - - return false, errors.New("invalid method argument") -} - -func (f *Fetcher) FetchAddress(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (common.Address, error) { - - f.Abi = contractAbi - f.ContractAddress = contractAddress - f.FetchedBlocks = append(f.FetchedBlocks, blockNumber) - - adr := common.StringToAddress("test_address") - - if method == "owner" { - f.owner = adr - - return f.owner, nil - } - return common.StringToAddress(""), errors.New("invalid method argument") -} - -func (f *Fetcher) FetchString(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (string, error) { - - f.Abi = contractAbi - f.ContractAddress = contractAddress - f.FetchedBlocks = append(f.FetchedBlocks, blockNumber) - - if method == "name" { - f.stringName = "test_name" - - return f.stringName, nil - } - - if method == "symbol" { - f.stringSymbol = "test_symbol" - - return f.stringSymbol, nil - } - return "", errors.New("invalid method argument") -} - -func (f *Fetcher) FetchHash(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (common.Hash, error) { - - f.Abi = contractAbi - f.ContractAddress = contractAddress - f.FetchedBlocks = append(f.FetchedBlocks, blockNumber) - - if method == "name" { - f.hashName = common.StringToHash("test_name") - - return f.hashName, nil - } - - if method == "symbol" { - f.hashSymbol = common.StringToHash("test_symbol") - - return f.hashSymbol, nil - } - return common.StringToHash(""), errors.New("invalid method argument") -} - -type Getter struct { - Fetcher Fetcher -} - -func NewGetter(blockChain core.BlockChain) Getter { - return Getter{ - Fetcher: Fetcher{ - BlockChain: blockChain, - }, - } -} - -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) -} - -func (g *Getter) GetOwner(contractAbi, contractAddress string, blockNumber int64) (common.Address, error) { - return g.Fetcher.FetchAddress("owner", contractAbi, contractAddress, blockNumber, nil) -} - -func (g *Getter) GetStoppedStatus(contractAbi, contractAddress string, blockNumber int64) (bool, error) { - return g.Fetcher.FetchBool("stopped", contractAbi, contractAddress, blockNumber, nil) -} - -func (g *Getter) GetStringName(contractAbi, contractAddress string, blockNumber int64) (string, error) { - return g.Fetcher.FetchString("name", contractAbi, contractAddress, blockNumber, nil) -} - -func (g *Getter) GetHashName(contractAbi, contractAddress string, blockNumber int64) (common.Hash, error) { - return g.Fetcher.FetchHash("name", contractAbi, contractAddress, blockNumber, nil) -} - -func (g *Getter) GetStringSymbol(contractAbi, contractAddress string, blockNumber int64) (string, error) { - return g.Fetcher.FetchString("symbol", contractAbi, contractAddress, blockNumber, nil) -} - -func (g *Getter) GetHashSymbol(contractAbi, contractAddress string, blockNumber int64) (common.Hash, error) { - return g.Fetcher.FetchHash("symbol", contractAbi, contractAddress, blockNumber, nil) -} - -func (g *Getter) GetDecimals(contractAbi, contractAddress string, blockNumber int64) (big.Int, error) { - return g.Fetcher.FetchBigInt("decimals", contractAbi, contractAddress, blockNumber, nil) -} - -func (g *Getter) GetBlockChain() core.BlockChain { - return g.Fetcher.BlockChain -} - -type ERC20TokenRepository struct { - TotalSuppliesCreated []every_block.TokenSupply - MissingSupplyBlockNumbers []int64 - TotalBalancesCreated []every_block.TokenBalance - MissingBalanceBlockNumbers []int64 - TotalAllowancesCreated []every_block.TokenAllowance - MissingAllowanceBlockNumbers []int64 - StartingBlock int64 - EndingBlock int64 -} - -func (fr *ERC20TokenRepository) CreateSupply(supply every_block.TokenSupply) error { - fr.TotalSuppliesCreated = append(fr.TotalSuppliesCreated, supply) - return nil -} - -func (fr *ERC20TokenRepository) CreateBalance(balance every_block.TokenBalance) error { - fr.TotalBalancesCreated = append(fr.TotalBalancesCreated, balance) - return nil -} - -func (fr *ERC20TokenRepository) CreateAllowance(allowance every_block.TokenAllowance) error { - fr.TotalAllowancesCreated = append(fr.TotalAllowancesCreated, allowance) - return nil -} - -func (fr *ERC20TokenRepository) MissingSupplyBlocks(startingBlock, highestBlock int64, tokenAddress string) ([]int64, error) { - fr.StartingBlock = startingBlock - fr.EndingBlock = highestBlock - return fr.MissingSupplyBlockNumbers, nil -} - -func (fr *ERC20TokenRepository) MissingBalanceBlocks(startingBlock, highestBlock int64, tokenAddress, holderAddress string) ([]int64, error) { - fr.StartingBlock = startingBlock - fr.EndingBlock = highestBlock - return fr.MissingBalanceBlockNumbers, nil -} - -func (fr *ERC20TokenRepository) MissingAllowanceBlocks(startingBlock, highestBlock int64, tokenAddress, holderAddress, spenderAddress string) ([]int64, error) { - fr.StartingBlock = startingBlock - fr.EndingBlock = highestBlock - return fr.MissingAllowanceBlockNumbers, nil -} - -func (fr *ERC20TokenRepository) SetMissingSupplyBlocks(missingBlocks []int64) { - fr.MissingSupplyBlockNumbers = missingBlocks -} - -func (fr *ERC20TokenRepository) SetMissingBalanceBlocks(missingBlocks []int64) { - fr.MissingBalanceBlockNumbers = missingBlocks -} - -func (fr *ERC20TokenRepository) SetMissingAllowanceBlocks(missingBlocks []int64) { - fr.MissingAllowanceBlockNumbers = missingBlocks -} - -type FailureRepository struct { - createSupplyFail bool - createBalanceFail bool - createAllowanceFail bool - missingSupplyBlocksFail bool - missingBalanceBlocksFail bool - missingAllowanceBlocksFail bool - missingSupplyBlocksNumbers []int64 - missingBalanceBlocksNumbers []int64 - missingAllowanceBlocksNumbers []int64 -} - -func (fr *FailureRepository) CreateSupply(supply every_block.TokenSupply) error { - if fr.createSupplyFail { - return fakes.FakeError - } else { - return nil - } -} - -func (fr *FailureRepository) CreateBalance(balance every_block.TokenBalance) error { - if fr.createBalanceFail { - return fakes.FakeError - } else { - return nil - } -} - -func (fr *FailureRepository) CreateAllowance(allowance every_block.TokenAllowance) error { - if fr.createAllowanceFail { - return fakes.FakeError - } else { - return nil - } -} - -func (fr *FailureRepository) MissingSupplyBlocks(startingBlock, highestBlock int64, tokenAddress string) ([]int64, error) { - if fr.missingSupplyBlocksFail { - return []int64{}, fakes.FakeError - } else { - return fr.missingSupplyBlocksNumbers, nil - } -} - -func (fr *FailureRepository) MissingBalanceBlocks(startingBlock, highestBlock int64, tokenAddress, holderAddress string) ([]int64, error) { - if fr.missingBalanceBlocksFail { - return []int64{}, fakes.FakeError - } else { - return fr.missingBalanceBlocksNumbers, nil - } -} - -func (fr *FailureRepository) MissingAllowanceBlocks(startingBlock, highestBlock int64, tokenAddress, holderAddress, spenderAddress string) ([]int64, error) { - if fr.missingAllowanceBlocksFail { - return []int64{}, fakes.FakeError - } else { - return fr.missingAllowanceBlocksNumbers, nil - } -} - -func (fr *FailureRepository) SetCreateSupplyFail(fail bool) { - fr.createSupplyFail = fail -} - -func (fr *FailureRepository) SetCreateBalanceFail(fail bool) { - fr.createBalanceFail = fail -} - -func (fr *FailureRepository) SetCreateAllowanceFail(fail bool) { - fr.createAllowanceFail = fail -} - -func (fr *FailureRepository) SetMissingSupplyBlocksFail(fail bool) { - fr.missingSupplyBlocksFail = fail -} - -func (fr *FailureRepository) SetMissingBalanceBlocksFail(fail bool) { - fr.missingBalanceBlocksFail = fail -} - -func (fr *FailureRepository) SetMissingAllowanceBlocksFail(fail bool) { - fr.missingAllowanceBlocksFail = fail -} - -func (fr *FailureRepository) SetMissingSupplyBlocks(missingBlocks []int64) { - fr.missingSupplyBlocksNumbers = missingBlocks -} - -func (fr *FailureRepository) SetMissingBalanceBlocks(missingBlocks []int64) { - fr.missingBalanceBlocksNumbers = missingBlocks -} - -func (fr *FailureRepository) SetMissingAllowanceBlocks(missingBlocks []int64) { - fr.missingAllowanceBlocksNumbers = missingBlocks -}