From 34c96654ce9db0dc10e09f5796ac1e351787e966 Mon Sep 17 00:00:00 2001 From: Rob Mulholand Date: Tue, 26 Feb 2019 18:29:27 -0600 Subject: [PATCH] Extract slow tests from omni light transformer --- integration_test/omni_light_transformer.go | 411 +++++++++++++++ pkg/fakes/mock_block_retriever.go | 14 + pkg/fakes/mock_parser.go | 38 ++ pkg/fakes/mock_poller.go | 24 + .../light/retriever/retriever_suite_test.go | 2 +- pkg/omni/light/transformer/transformer.go | 30 +- .../light/transformer/transformer_test.go | 498 +++--------------- 7 files changed, 581 insertions(+), 436 deletions(-) create mode 100644 integration_test/omni_light_transformer.go create mode 100644 pkg/fakes/mock_block_retriever.go create mode 100644 pkg/fakes/mock_parser.go create mode 100644 pkg/fakes/mock_poller.go diff --git a/integration_test/omni_light_transformer.go b/integration_test/omni_light_transformer.go new file mode 100644 index 00000000..9391ef5b --- /dev/null +++ b/integration_test/omni_light_transformer.go @@ -0,0 +1,411 @@ +package integration + +import ( + "fmt" + "github.com/ethereum/go-ethereum/common" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/vulcanize/vulcanizedb/pkg/core" + "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" + "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" + "github.com/vulcanize/vulcanizedb/pkg/omni/light/transformer" + "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants" + "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers" + "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks" + "strings" +) + +var _ = Describe("Omnit light transformer", func() { + var db *postgres.DB + var err error + var blockChain core.BlockChain + var headerRepository repositories.HeaderRepository + var headerID, headerID2 int64 + var ensAddr = strings.ToLower(constants.EnsContractAddress) + var tusdAddr = strings.ToLower(constants.TusdContractAddress) + + BeforeEach(func() { + db, blockChain = test_helpers.SetupDBandBC() + headerRepository = repositories.NewHeaderRepository(db) + }) + + AfterEach(func() { + test_helpers.TearDown(db) + }) + + Describe("Init", func() { + It("Initializes transformer's contract objects", func() { + headerRepository.CreateOrUpdateHeader(mocks.MockHeader1) + headerRepository.CreateOrUpdateHeader(mocks.MockHeader3) + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + + c, ok := t.Contracts[tusdAddr] + Expect(ok).To(Equal(true)) + + Expect(c.StartingBlock).To(Equal(int64(6194632))) + Expect(c.LastBlock).To(Equal(int64(-1))) + Expect(c.Abi).To(Equal(constants.TusdAbiString)) + Expect(c.Name).To(Equal("TrueUSD")) + Expect(c.Address).To(Equal(tusdAddr)) + }) + }) + + Describe("Execute- against TrueUSD contract", func() { + BeforeEach(func() { + header1, err := blockChain.GetHeaderByNumber(6791668) + Expect(err).ToNot(HaveOccurred()) + header2, err := blockChain.GetHeaderByNumber(6791669) + Expect(err).ToNot(HaveOccurred()) + header3, err := blockChain.GetHeaderByNumber(6791670) + Expect(err).ToNot(HaveOccurred()) + headerRepository.CreateOrUpdateHeader(header1) + headerID, err = headerRepository.CreateOrUpdateHeader(header2) + Expect(err).ToNot(HaveOccurred()) + headerRepository.CreateOrUpdateHeader(header3) + }) + + It("Transforms watched contract data into custom repositories", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) + t.SetMethods(constants.TusdContractAddress, nil) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + + log := test_helpers.LightTransferLog{} + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.transfer_event", tusdAddr)).StructScan(&log) + Expect(err).ToNot(HaveOccurred()) + // We don't know vulcID, so compare individual fields instead of complete structures + Expect(log.HeaderID).To(Equal(headerID)) + Expect(log.From).To(Equal("0x1062a747393198f70F71ec65A582423Dba7E5Ab3")) + Expect(log.To).To(Equal("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0")) + Expect(log.Value).To(Equal("9998940000000000000000")) + }) + + It("Keeps track of contract-related addresses while transforming event data if they need to be used for later method polling", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) + t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"}) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + c, ok := t.Contracts[tusdAddr] + Expect(ok).To(Equal(true)) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + Expect(len(c.EmittedAddrs)).To(Equal(4)) + Expect(len(c.EmittedHashes)).To(Equal(0)) + + b, ok := c.EmittedAddrs[common.HexToAddress("0x1062a747393198f70F71ec65A582423Dba7E5Ab3")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + b, ok = c.EmittedAddrs[common.HexToAddress("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + b, ok = c.EmittedAddrs[common.HexToAddress("0x571A326f5B15E16917dC17761c340c1ec5d06f6d")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + b, ok = c.EmittedAddrs[common.HexToAddress("0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + _, ok = c.EmittedAddrs[common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843b1234567890")] + Expect(ok).To(Equal(false)) + + _, ok = c.EmittedAddrs[common.HexToAddress("0x")] + Expect(ok).To(Equal(false)) + + _, ok = c.EmittedAddrs[""] + Expect(ok).To(Equal(false)) + + _, ok = c.EmittedAddrs[common.HexToAddress("0x09THISE21a5IS5cFAKE1D82fAND43bCE06MADEUP")] + Expect(ok).To(Equal(false)) + }) + + It("Polls given methods using generated token holder address", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) + t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"}) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + + res := test_helpers.BalanceOf{} + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x1062a747393198f70F71ec65A582423Dba7E5Ab3' AND block = '6791669'", tusdAddr)).StructScan(&res) + Expect(err).ToNot(HaveOccurred()) + Expect(res.Balance).To(Equal("55849938025000000000000")) + Expect(res.TokenName).To(Equal("TrueUSD")) + + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x09BbBBE21a5975cAc061D82f7b843b1234567890' AND block = '6791669'", tusdAddr)).StructScan(&res) + Expect(err).To(HaveOccurred()) + }) + + It("Fails if initialization has not been done", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) + t.SetMethods(constants.TusdContractAddress, nil) + err = t.Execute() + Expect(err).To(HaveOccurred()) + }) + }) + + Describe("Execute- against ENS registry contract", func() { + BeforeEach(func() { + header1, err := blockChain.GetHeaderByNumber(6885695) + Expect(err).ToNot(HaveOccurred()) + header2, err := blockChain.GetHeaderByNumber(6885696) + Expect(err).ToNot(HaveOccurred()) + header3, err := blockChain.GetHeaderByNumber(6885697) + Expect(err).ToNot(HaveOccurred()) + headerRepository.CreateOrUpdateHeader(header1) + headerID, err = headerRepository.CreateOrUpdateHeader(header2) + Expect(err).ToNot(HaveOccurred()) + headerRepository.CreateOrUpdateHeader(header3) + }) + + It("Transforms watched contract data into custom repositories", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) + t.SetMethods(constants.EnsContractAddress, nil) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + + log := test_helpers.LightNewOwnerLog{} + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.newowner_event", ensAddr)).StructScan(&log) + Expect(err).ToNot(HaveOccurred()) + // We don't know vulcID, so compare individual fields instead of complete structures + Expect(log.HeaderID).To(Equal(headerID)) + Expect(log.Node).To(Equal("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae")) + Expect(log.Label).To(Equal("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047")) + Expect(log.Owner).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")) + }) + + It("Keeps track of contract-related hashes while transforming event data if they need to be used for later method polling", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) + t.SetMethods(constants.EnsContractAddress, []string{"owner"}) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + c, ok := t.Contracts[ensAddr] + Expect(ok).To(Equal(true)) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + Expect(len(c.EmittedHashes)).To(Equal(2)) + Expect(len(c.EmittedAddrs)).To(Equal(0)) + + b, ok := c.EmittedHashes[common.HexToHash("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + b, ok = c.EmittedHashes[common.HexToHash("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + // Doesn't keep track of address since it wouldn't be used in calling the 'owner' method + _, ok = c.EmittedAddrs[common.HexToAddress("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")] + Expect(ok).To(Equal(false)) + }) + + It("Polls given method using list of collected hashes", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) + t.SetMethods(constants.EnsContractAddress, []string{"owner"}) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + + res := test_helpers.Owner{} + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885696'", ensAddr)).StructScan(&res) + Expect(err).ToNot(HaveOccurred()) + Expect(res.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")) + Expect(res.TokenName).To(Equal("")) + + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047' AND block = '6885696'", ensAddr)).StructScan(&res) + Expect(err).ToNot(HaveOccurred()) + Expect(res.Address).To(Equal("0x0000000000000000000000000000000000000000")) + Expect(res.TokenName).To(Equal("")) + + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x9THIS110dcc444fIS242510c09bbAbe21aFAKEcacNODE82f7b843HASH61ba391' AND block = '6885696'", ensAddr)).StructScan(&res) + Expect(err).To(HaveOccurred()) + }) + + It("It does not persist events if they do not pass the emitted arg filter", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) + t.SetMethods(constants.EnsContractAddress, nil) + t.SetEventArgs(constants.EnsContractAddress, []string{"fake_filter_value"}) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + + log := test_helpers.LightNewOwnerLog{} + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.newowner_event", ensAddr)).StructScan(&log) + Expect(err).To(HaveOccurred()) + }) + + It("If a method arg filter is applied, only those arguments are used in polling", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) + t.SetMethods(constants.EnsContractAddress, []string{"owner"}) + t.SetMethodArgs(constants.EnsContractAddress, []string{"0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"}) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + + res := test_helpers.Owner{} + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885696'", ensAddr)).StructScan(&res) + Expect(err).ToNot(HaveOccurred()) + Expect(res.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")) + Expect(res.TokenName).To(Equal("")) + + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047' AND block = '6885696'", ensAddr)).StructScan(&res) + Expect(err).To(HaveOccurred()) + }) + }) + + Describe("Execute- against both ENS and TrueUSD", func() { + BeforeEach(func() { + header1, err := blockChain.GetHeaderByNumber(6791668) + Expect(err).ToNot(HaveOccurred()) + header2, err := blockChain.GetHeaderByNumber(6791669) + Expect(err).ToNot(HaveOccurred()) + header3, err := blockChain.GetHeaderByNumber(6791670) + Expect(err).ToNot(HaveOccurred()) + header4, err := blockChain.GetHeaderByNumber(6885695) + Expect(err).ToNot(HaveOccurred()) + header5, err := blockChain.GetHeaderByNumber(6885696) + Expect(err).ToNot(HaveOccurred()) + header6, err := blockChain.GetHeaderByNumber(6885697) + Expect(err).ToNot(HaveOccurred()) + headerRepository.CreateOrUpdateHeader(header1) + headerID, err = headerRepository.CreateOrUpdateHeader(header2) + Expect(err).ToNot(HaveOccurred()) + headerRepository.CreateOrUpdateHeader(header3) + headerRepository.CreateOrUpdateHeader(header4) + headerID2, err = headerRepository.CreateOrUpdateHeader(header5) + Expect(err).ToNot(HaveOccurred()) + headerRepository.CreateOrUpdateHeader(header6) + }) + + It("Transforms watched contract data into custom repositories", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) + t.SetMethods(constants.EnsContractAddress, nil) + t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) + t.SetMethods(constants.TusdContractAddress, nil) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + + newOwnerLog := test_helpers.LightNewOwnerLog{} + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.newowner_event", ensAddr)).StructScan(&newOwnerLog) + Expect(err).ToNot(HaveOccurred()) + // We don't know vulcID, so compare individual fields instead of complete structures + Expect(newOwnerLog.HeaderID).To(Equal(headerID2)) + Expect(newOwnerLog.Node).To(Equal("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae")) + Expect(newOwnerLog.Label).To(Equal("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047")) + Expect(newOwnerLog.Owner).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")) + + transferLog := test_helpers.LightTransferLog{} + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.transfer_event", tusdAddr)).StructScan(&transferLog) + Expect(err).ToNot(HaveOccurred()) + // We don't know vulcID, so compare individual fields instead of complete structures + Expect(transferLog.HeaderID).To(Equal(headerID)) + Expect(transferLog.From).To(Equal("0x1062a747393198f70F71ec65A582423Dba7E5Ab3")) + Expect(transferLog.To).To(Equal("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0")) + Expect(transferLog.Value).To(Equal("9998940000000000000000")) + }) + + It("Keeps track of contract-related hashes and addresses while transforming event data if they need to be used for later method polling", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) + t.SetMethods(constants.EnsContractAddress, []string{"owner"}) + t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) + t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"}) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + ens, ok := t.Contracts[ensAddr] + Expect(ok).To(Equal(true)) + tusd, ok := t.Contracts[tusdAddr] + Expect(ok).To(Equal(true)) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + Expect(len(ens.EmittedHashes)).To(Equal(2)) + Expect(len(ens.EmittedAddrs)).To(Equal(0)) + Expect(len(tusd.EmittedAddrs)).To(Equal(4)) + Expect(len(tusd.EmittedHashes)).To(Equal(0)) + + b, ok := ens.EmittedHashes[common.HexToHash("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + b, ok = ens.EmittedHashes[common.HexToHash("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + b, ok = tusd.EmittedAddrs[common.HexToAddress("0x1062a747393198f70F71ec65A582423Dba7E5Ab3")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + b, ok = tusd.EmittedAddrs[common.HexToAddress("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + b, ok = tusd.EmittedAddrs[common.HexToAddress("0x571A326f5B15E16917dC17761c340c1ec5d06f6d")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + + b, ok = tusd.EmittedAddrs[common.HexToAddress("0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98")] + Expect(ok).To(Equal(true)) + Expect(b).To(Equal(true)) + }) + + It("Polls given methods for each contract, using list of collected values", func() { + t := transformer.NewTransformer("", blockChain, db) + t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) + t.SetMethods(constants.EnsContractAddress, []string{"owner"}) + t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) + t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"}) + err = t.Init() + Expect(err).ToNot(HaveOccurred()) + err = t.Execute() + Expect(err).ToNot(HaveOccurred()) + + owner := test_helpers.Owner{} + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885696'", ensAddr)).StructScan(&owner) + Expect(err).ToNot(HaveOccurred()) + Expect(owner.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")) + Expect(owner.TokenName).To(Equal("")) + + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047' AND block = '6885696'", ensAddr)).StructScan(&owner) + Expect(err).ToNot(HaveOccurred()) + Expect(owner.Address).To(Equal("0x0000000000000000000000000000000000000000")) + Expect(owner.TokenName).To(Equal("")) + + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHItransformers.8IS625bFAKE' AND block = '6885696'", ensAddr)).StructScan(&owner) + Expect(err).To(HaveOccurred()) + + bal := test_helpers.BalanceOf{} + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x1062a747393198f70F71ec65A582423Dba7E5Ab3' AND block = '6791669'", tusdAddr)).StructScan(&bal) + Expect(err).ToNot(HaveOccurred()) + Expect(bal.Balance).To(Equal("55849938025000000000000")) + Expect(bal.TokenName).To(Equal("TrueUSD")) + + err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x09BbBBE21a5975cAc061D82f7b843b1234567890' AND block = '6791669'", tusdAddr)).StructScan(&bal) + Expect(err).To(HaveOccurred()) + }) + }) +}) diff --git a/pkg/fakes/mock_block_retriever.go b/pkg/fakes/mock_block_retriever.go new file mode 100644 index 00000000..407e7170 --- /dev/null +++ b/pkg/fakes/mock_block_retriever.go @@ -0,0 +1,14 @@ +package fakes + +type MockBlockRetriever struct { + FirstBlock int64 + FirstBlockErr error +} + +func (retriever *MockBlockRetriever) RetrieveFirstBlock() (int64, error) { + return retriever.FirstBlock, retriever.FirstBlockErr +} + +func (retriever *MockBlockRetriever) RetrieveMostRecentBlock() (int64, error) { + return 0, nil +} diff --git a/pkg/fakes/mock_parser.go b/pkg/fakes/mock_parser.go new file mode 100644 index 00000000..e9cf3c87 --- /dev/null +++ b/pkg/fakes/mock_parser.go @@ -0,0 +1,38 @@ +package fakes + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types" +) + +type MockParser struct { + AbiToReturn string +} + +func (*MockParser) Parse(contractAddr string) error { + return nil +} + +func (*MockParser) ParseAbiStr(abiStr string) error { + panic("implement me") +} + +func (parser *MockParser) Abi() string { + return parser.AbiToReturn +} + +func (*MockParser) ParsedAbi() abi.ABI { + return abi.ABI{} +} + +func (*MockParser) GetMethods(wanted []string) []types.Method { + panic("implement me") +} + +func (*MockParser) GetSelectMethods(wanted []string) []types.Method { + return []types.Method{} +} + +func (*MockParser) GetEvents(wanted []string) map[string]types.Event { + return map[string]types.Event{} +} diff --git a/pkg/fakes/mock_poller.go b/pkg/fakes/mock_poller.go new file mode 100644 index 00000000..f1a1caec --- /dev/null +++ b/pkg/fakes/mock_poller.go @@ -0,0 +1,24 @@ +package fakes + +import ( + "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract" +) + +type MockPoller struct { + ContractName string +} + +func (*MockPoller) PollContract(con contract.Contract) error { + panic("implement me") +} + +func (*MockPoller) PollContractAt(con contract.Contract, blockNumber int64) error { + panic("implement me") +} + +func (poller *MockPoller) FetchContractData(contractAbi, contractAddress, method string, methodArgs []interface{}, result interface{}, blockNumber int64) error { + if p, ok := result.(*string); ok { + *p = poller.ContractName + } + return nil +} diff --git a/pkg/omni/light/retriever/retriever_suite_test.go b/pkg/omni/light/retriever/retriever_suite_test.go index 7494b0a9..a973ff7e 100644 --- a/pkg/omni/light/retriever/retriever_suite_test.go +++ b/pkg/omni/light/retriever/retriever_suite_test.go @@ -27,7 +27,7 @@ import ( func TestRetriever(t *testing.T) { RegisterFailHandler(Fail) - RunSpecs(t, "Light BLock Number Retriever Suite Test") + RunSpecs(t, "Light Block Number Retriever Suite Test") } var _ = BeforeSuite(func() { diff --git a/pkg/omni/light/transformer/transformer.go b/pkg/omni/light/transformer/transformer.go index 565e6966..426e3587 100644 --- a/pkg/omni/light/transformer/transformer.go +++ b/pkg/omni/light/transformer/transformer.go @@ -37,7 +37,7 @@ import ( ) // Requires a light synced vDB (headers) and a running eth node (or infura) -type transformer struct { +type Transformer struct { // Database interfaces srep.EventRepository // Holds transformed watched event log data repository.HeaderRepository // Interface for interaction with header repositories @@ -93,9 +93,9 @@ type transformer struct { // 4. Execute // Transformer takes in config for blockchain, database, and network id -func NewTransformer(network string, bc core.BlockChain, db *postgres.DB) *transformer { +func NewTransformer(network string, bc core.BlockChain, db *postgres.DB) *Transformer { - return &transformer{ + return &Transformer{ Poller: poller.NewPoller(bc, db, types.LightSync), Fetcher: fetcher.NewFetcher(bc), Parser: parser.NewParser(network), @@ -120,7 +120,7 @@ func NewTransformer(network string, bc core.BlockChain, db *postgres.DB) *transf // Loops over all of the addr => filter sets // Uses parser to pull event info from abi // Use this info to generate event filters -func (tr *transformer) Init() error { +func (tr *Transformer) Init() error { // Initialize internally configured transformer settings tr.contractAddresses = make([]string, 0) // Holds all contract addresses, for batch fetching of logs tr.sortedEventIds = make(map[string][]string) // Map to sort event column ids by contract, for post fetch processing and persisting of logs @@ -154,7 +154,7 @@ func (tr *transformer) Init() error { // Get contract name if it has one var name = new(string) - tr.FetchContractData(tr.Abi(), contractAddr, "name", nil, &name, lastBlock) + tr.Poller.FetchContractData(tr.Abi(), contractAddr, "name", nil, name, lastBlock) // Remove any potential accidental duplicate inputs in arg filter values eventArgs := map[string]bool{} @@ -221,7 +221,7 @@ func (tr *transformer) Init() error { return nil } -func (tr *transformer) Execute() error { +func (tr *Transformer) Execute() error { if len(tr.Contracts) == 0 { return errors.New("error: transformer has no initialized contracts") } @@ -311,7 +311,7 @@ func (tr *transformer) Execute() error { } // Used to poll contract methods at a given header -func (tr *transformer) methodPolling(header core.Header, sortedMethodIds map[string][]string) error { +func (tr *Transformer) methodPolling(header core.Header, sortedMethodIds map[string][]string) error { for _, con := range tr.Contracts { // Skip method polling processes if no methods are specified // Also don't try to poll methods below this contract's specified starting block @@ -336,41 +336,41 @@ func (tr *transformer) methodPolling(header core.Header, sortedMethodIds map[str } // Used to set which contract addresses and which of their events to watch -func (tr *transformer) SetEvents(contractAddr string, filterSet []string) { +func (tr *Transformer) SetEvents(contractAddr string, filterSet []string) { tr.WatchedEvents[strings.ToLower(contractAddr)] = filterSet } // Used to set subset of account addresses to watch events for -func (tr *transformer) SetEventArgs(contractAddr string, filterSet []string) { +func (tr *Transformer) SetEventArgs(contractAddr string, filterSet []string) { tr.EventArgs[strings.ToLower(contractAddr)] = filterSet } // Used to set which contract addresses and which of their methods to call -func (tr *transformer) SetMethods(contractAddr string, filterSet []string) { +func (tr *Transformer) SetMethods(contractAddr string, filterSet []string) { tr.WantedMethods[strings.ToLower(contractAddr)] = filterSet } // Used to set subset of account addresses to poll methods on -func (tr *transformer) SetMethodArgs(contractAddr string, filterSet []string) { +func (tr *Transformer) SetMethodArgs(contractAddr string, filterSet []string) { tr.MethodArgs[strings.ToLower(contractAddr)] = filterSet } // Used to set the block range to watch for a given address -func (tr *transformer) SetStartingBlock(contractAddr string, start int64) { +func (tr *Transformer) SetStartingBlock(contractAddr string, start int64) { tr.ContractStart[strings.ToLower(contractAddr)] = start } // Used to set whether or not to persist an account address list -func (tr *transformer) SetCreateAddrList(contractAddr string, on bool) { +func (tr *Transformer) SetCreateAddrList(contractAddr string, on bool) { tr.CreateAddrList[strings.ToLower(contractAddr)] = on } // Used to set whether or not to persist an hash list -func (tr *transformer) SetCreateHashList(contractAddr string, on bool) { +func (tr *Transformer) SetCreateHashList(contractAddr string, on bool) { tr.CreateHashList[strings.ToLower(contractAddr)] = on } // Used to turn method piping on for a contract -func (tr *transformer) SetPiping(contractAddr string, on bool) { +func (tr *Transformer) SetPiping(contractAddr string, on bool) { tr.Piping[strings.ToLower(contractAddr)] = on } diff --git a/pkg/omni/light/transformer/transformer_test.go b/pkg/omni/light/transformer/transformer_test.go index e776cb0b..5b914b46 100644 --- a/pkg/omni/light/transformer/transformer_test.go +++ b/pkg/omni/light/transformer/transformer_test.go @@ -17,491 +17,149 @@ package transformer_test import ( - "fmt" - "strings" - - "github.com/ethereum/go-ethereum/common" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/vulcanize/vulcanizedb/pkg/core" - "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" - "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" + "github.com/vulcanize/vulcanizedb/pkg/fakes" + "github.com/vulcanize/vulcanizedb/pkg/omni/light/retriever" "github.com/vulcanize/vulcanizedb/pkg/omni/light/transformer" - "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants" - "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers" - "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks" + "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract" + "github.com/vulcanize/vulcanizedb/pkg/omni/shared/parser" + "github.com/vulcanize/vulcanizedb/pkg/omni/shared/poller" ) var _ = Describe("Transformer", func() { - var db *postgres.DB - var err error - var blockChain core.BlockChain - var headerRepository repositories.HeaderRepository - var headerID, headerID2 int64 - var ensAddr = strings.ToLower(constants.EnsContractAddress) - var tusdAddr = strings.ToLower(constants.TusdContractAddress) - - BeforeEach(func() { - db, blockChain = test_helpers.SetupDBandBC() - headerRepository = repositories.NewHeaderRepository(db) - }) - - AfterEach(func() { - test_helpers.TearDown(db) - }) + var fakeAddress = "0x1234567890abcdef" Describe("SetEvents", func() { It("Sets which events to watch from the given contract address", func() { watchedEvents := []string{"Transfer", "Mint"} - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.TusdContractAddress, watchedEvents) - Expect(t.WatchedEvents[tusdAddr]).To(Equal(watchedEvents)) + t := getFakeTransformer(&fakes.MockBlockRetriever{}, &fakes.MockParser{}, &fakes.MockPoller{}) + t.SetEvents(fakeAddress, watchedEvents) + Expect(t.WatchedEvents[fakeAddress]).To(Equal(watchedEvents)) }) }) Describe("SetEventAddrs", func() { It("Sets which account addresses to watch events for", func() { eventAddrs := []string{"test1", "test2"} - t := transformer.NewTransformer("", blockChain, db) - t.SetEventArgs(constants.TusdContractAddress, eventAddrs) - Expect(t.EventArgs[tusdAddr]).To(Equal(eventAddrs)) + t := getFakeTransformer(&fakes.MockBlockRetriever{}, &fakes.MockParser{}, &fakes.MockPoller{}) + t.SetEventArgs(fakeAddress, eventAddrs) + Expect(t.EventArgs[fakeAddress]).To(Equal(eventAddrs)) }) }) Describe("SetMethods", func() { It("Sets which methods to poll at the given contract address", func() { watchedMethods := []string{"balanceOf", "totalSupply"} - t := transformer.NewTransformer("", blockChain, db) - t.SetMethods(constants.TusdContractAddress, watchedMethods) - Expect(t.WantedMethods[tusdAddr]).To(Equal(watchedMethods)) + t := getFakeTransformer(&fakes.MockBlockRetriever{}, &fakes.MockParser{}, &fakes.MockPoller{}) + t.SetMethods(fakeAddress, watchedMethods) + Expect(t.WantedMethods[fakeAddress]).To(Equal(watchedMethods)) }) }) Describe("SetMethodAddrs", func() { It("Sets which account addresses to poll methods against", func() { methodAddrs := []string{"test1", "test2"} - t := transformer.NewTransformer("", blockChain, db) - t.SetMethodArgs(constants.TusdContractAddress, methodAddrs) - Expect(t.MethodArgs[tusdAddr]).To(Equal(methodAddrs)) + t := getFakeTransformer(&fakes.MockBlockRetriever{}, &fakes.MockParser{}, &fakes.MockPoller{}) + t.SetMethodArgs(fakeAddress, methodAddrs) + Expect(t.MethodArgs[fakeAddress]).To(Equal(methodAddrs)) }) }) Describe("SetStartingBlock", func() { It("Sets the block range that the contract should be watched within", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetStartingBlock(constants.TusdContractAddress, 11) - Expect(t.ContractStart[tusdAddr]).To(Equal(int64(11))) + t := getFakeTransformer(&fakes.MockBlockRetriever{}, &fakes.MockParser{}, &fakes.MockPoller{}) + t.SetStartingBlock(fakeAddress, 11) + Expect(t.ContractStart[fakeAddress]).To(Equal(int64(11))) }) }) Describe("SetCreateAddrList", func() { It("Sets the block range that the contract should be watched within", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetCreateAddrList(constants.TusdContractAddress, true) - Expect(t.CreateAddrList[tusdAddr]).To(Equal(true)) + t := getFakeTransformer(&fakes.MockBlockRetriever{}, &fakes.MockParser{}, &fakes.MockPoller{}) + t.SetCreateAddrList(fakeAddress, true) + Expect(t.CreateAddrList[fakeAddress]).To(Equal(true)) }) }) Describe("SetCreateHashList", func() { It("Sets the block range that the contract should be watched within", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetCreateHashList(constants.TusdContractAddress, true) - Expect(t.CreateHashList[tusdAddr]).To(Equal(true)) + t := getFakeTransformer(&fakes.MockBlockRetriever{}, &fakes.MockParser{}, &fakes.MockPoller{}) + t.SetCreateHashList(fakeAddress, true) + Expect(t.CreateHashList[fakeAddress]).To(Equal(true)) }) }) Describe("Init", func() { It("Initializes transformer's contract objects", func() { - headerRepository.CreateOrUpdateHeader(mocks.MockHeader1) - headerRepository.CreateOrUpdateHeader(mocks.MockHeader3) - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) - err = t.Init() + blockRetriever := &fakes.MockBlockRetriever{} + firstBlock := int64(1) + blockRetriever.FirstBlock = firstBlock + + parsr := &fakes.MockParser{} + fakeAbi := "fake_abi" + parsr.AbiToReturn = fakeAbi + + pollr := &fakes.MockPoller{} + fakeContractName := "fake_contract_name" + pollr.ContractName = fakeContractName + + t := getFakeTransformer(blockRetriever, parsr, pollr) + t.SetEvents(fakeAddress, []string{"Transfer"}) + + err := t.Init() + Expect(err).ToNot(HaveOccurred()) - c, ok := t.Contracts[tusdAddr] + c, ok := t.Contracts[fakeAddress] Expect(ok).To(Equal(true)) - Expect(c.StartingBlock).To(Equal(int64(6194632))) + Expect(c.StartingBlock).To(Equal(firstBlock)) Expect(c.LastBlock).To(Equal(int64(-1))) - Expect(c.Abi).To(Equal(constants.TusdAbiString)) - Expect(c.Name).To(Equal("TrueUSD")) - Expect(c.Address).To(Equal(tusdAddr)) + Expect(c.Abi).To(Equal(fakeAbi)) + Expect(c.Name).To(Equal(fakeContractName)) + Expect(c.Address).To(Equal(fakeAddress)) }) It("Fails to initialize if first and most recent block numbers cannot be fetched from vDB headers table", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) - err = t.Init() + blockRetriever := &fakes.MockBlockRetriever{} + blockRetriever.FirstBlockErr = fakes.FakeError + t := getFakeTransformer(blockRetriever, &fakes.MockParser{}, &fakes.MockPoller{}) + t.SetEvents(fakeAddress, []string{"Transfer"}) + + err := t.Init() + Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError(fakes.FakeError)) }) It("Does nothing if watched events are unset", func() { - headerRepository.CreateOrUpdateHeader(mocks.MockHeader1) - headerRepository.CreateOrUpdateHeader(mocks.MockHeader3) - t := transformer.NewTransformer("", blockChain, db) - err = t.Init() + t := getFakeTransformer(&fakes.MockBlockRetriever{}, &fakes.MockParser{}, &fakes.MockPoller{}) + + err := t.Init() + Expect(err).ToNot(HaveOccurred()) - _, ok := t.Contracts[tusdAddr] + _, ok := t.Contracts[fakeAddress] Expect(ok).To(Equal(false)) }) }) - Describe("Execute- against TrueUSD contract", func() { - BeforeEach(func() { - header1, err := blockChain.GetHeaderByNumber(6791668) - Expect(err).ToNot(HaveOccurred()) - header2, err := blockChain.GetHeaderByNumber(6791669) - Expect(err).ToNot(HaveOccurred()) - header3, err := blockChain.GetHeaderByNumber(6791670) - Expect(err).ToNot(HaveOccurred()) - headerRepository.CreateOrUpdateHeader(header1) - headerID, err = headerRepository.CreateOrUpdateHeader(header2) - Expect(err).ToNot(HaveOccurred()) - headerRepository.CreateOrUpdateHeader(header3) - }) - - It("Transforms watched contract data into custom repositories", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) - t.SetMethods(constants.TusdContractAddress, nil) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - - log := test_helpers.LightTransferLog{} - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.transfer_event", tusdAddr)).StructScan(&log) - Expect(err).ToNot(HaveOccurred()) - // We don't know vulcID, so compare individual fields instead of complete structures - Expect(log.HeaderID).To(Equal(headerID)) - Expect(log.From).To(Equal("0x1062a747393198f70F71ec65A582423Dba7E5Ab3")) - Expect(log.To).To(Equal("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0")) - Expect(log.Value).To(Equal("9998940000000000000000")) - }) - - It("Keeps track of contract-related addresses while transforming event data if they need to be used for later method polling", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) - t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"}) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - c, ok := t.Contracts[tusdAddr] - Expect(ok).To(Equal(true)) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - Expect(len(c.EmittedAddrs)).To(Equal(4)) - Expect(len(c.EmittedHashes)).To(Equal(0)) - - b, ok := c.EmittedAddrs[common.HexToAddress("0x1062a747393198f70F71ec65A582423Dba7E5Ab3")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - b, ok = c.EmittedAddrs[common.HexToAddress("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - b, ok = c.EmittedAddrs[common.HexToAddress("0x571A326f5B15E16917dC17761c340c1ec5d06f6d")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - b, ok = c.EmittedAddrs[common.HexToAddress("0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - _, ok = c.EmittedAddrs[common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843b1234567890")] - Expect(ok).To(Equal(false)) - - _, ok = c.EmittedAddrs[common.HexToAddress("0x")] - Expect(ok).To(Equal(false)) - - _, ok = c.EmittedAddrs[""] - Expect(ok).To(Equal(false)) - - _, ok = c.EmittedAddrs[common.HexToAddress("0x09THISE21a5IS5cFAKE1D82fAND43bCE06MADEUP")] - Expect(ok).To(Equal(false)) - }) - - It("Polls given methods using generated token holder address", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) - t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"}) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - - res := test_helpers.BalanceOf{} - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x1062a747393198f70F71ec65A582423Dba7E5Ab3' AND block = '6791669'", tusdAddr)).StructScan(&res) - Expect(err).ToNot(HaveOccurred()) - Expect(res.Balance).To(Equal("55849938025000000000000")) - Expect(res.TokenName).To(Equal("TrueUSD")) - - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x09BbBBE21a5975cAc061D82f7b843b1234567890' AND block = '6791669'", tusdAddr)).StructScan(&res) - Expect(err).To(HaveOccurred()) - }) - - It("Fails if initialization has not been done", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) - t.SetMethods(constants.TusdContractAddress, nil) - err = t.Execute() - Expect(err).To(HaveOccurred()) - }) - }) - - Describe("Execute- against ENS registry contract", func() { - BeforeEach(func() { - header1, err := blockChain.GetHeaderByNumber(6885695) - Expect(err).ToNot(HaveOccurred()) - header2, err := blockChain.GetHeaderByNumber(6885696) - Expect(err).ToNot(HaveOccurred()) - header3, err := blockChain.GetHeaderByNumber(6885697) - Expect(err).ToNot(HaveOccurred()) - headerRepository.CreateOrUpdateHeader(header1) - headerID, err = headerRepository.CreateOrUpdateHeader(header2) - Expect(err).ToNot(HaveOccurred()) - headerRepository.CreateOrUpdateHeader(header3) - }) - - It("Transforms watched contract data into custom repositories", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) - t.SetMethods(constants.EnsContractAddress, nil) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - - log := test_helpers.LightNewOwnerLog{} - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.newowner_event", ensAddr)).StructScan(&log) - Expect(err).ToNot(HaveOccurred()) - // We don't know vulcID, so compare individual fields instead of complete structures - Expect(log.HeaderID).To(Equal(headerID)) - Expect(log.Node).To(Equal("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae")) - Expect(log.Label).To(Equal("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047")) - Expect(log.Owner).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")) - }) - - It("Keeps track of contract-related hashes while transforming event data if they need to be used for later method polling", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) - t.SetMethods(constants.EnsContractAddress, []string{"owner"}) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - c, ok := t.Contracts[ensAddr] - Expect(ok).To(Equal(true)) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - Expect(len(c.EmittedHashes)).To(Equal(2)) - Expect(len(c.EmittedAddrs)).To(Equal(0)) - - b, ok := c.EmittedHashes[common.HexToHash("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - b, ok = c.EmittedHashes[common.HexToHash("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - // Doesn't keep track of address since it wouldn't be used in calling the 'owner' method - _, ok = c.EmittedAddrs[common.HexToAddress("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")] - Expect(ok).To(Equal(false)) - }) - - It("Polls given method using list of collected hashes", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) - t.SetMethods(constants.EnsContractAddress, []string{"owner"}) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - - res := test_helpers.Owner{} - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885696'", ensAddr)).StructScan(&res) - Expect(err).ToNot(HaveOccurred()) - Expect(res.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")) - Expect(res.TokenName).To(Equal("")) - - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047' AND block = '6885696'", ensAddr)).StructScan(&res) - Expect(err).ToNot(HaveOccurred()) - Expect(res.Address).To(Equal("0x0000000000000000000000000000000000000000")) - Expect(res.TokenName).To(Equal("")) - - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x9THIS110dcc444fIS242510c09bbAbe21aFAKEcacNODE82f7b843HASH61ba391' AND block = '6885696'", ensAddr)).StructScan(&res) - Expect(err).To(HaveOccurred()) - }) - - It("It does not persist events if they do not pass the emitted arg filter", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) - t.SetMethods(constants.EnsContractAddress, nil) - t.SetEventArgs(constants.EnsContractAddress, []string{"fake_filter_value"}) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - - log := test_helpers.LightNewOwnerLog{} - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.newowner_event", ensAddr)).StructScan(&log) - Expect(err).To(HaveOccurred()) - }) - - It("If a method arg filter is applied, only those arguments are used in polling", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) - t.SetMethods(constants.EnsContractAddress, []string{"owner"}) - t.SetMethodArgs(constants.EnsContractAddress, []string{"0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"}) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - - res := test_helpers.Owner{} - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885696'", ensAddr)).StructScan(&res) - Expect(err).ToNot(HaveOccurred()) - Expect(res.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")) - Expect(res.TokenName).To(Equal("")) - - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047' AND block = '6885696'", ensAddr)).StructScan(&res) - Expect(err).To(HaveOccurred()) - }) - }) - - Describe("Execute- against both ENS and TrueUSD", func() { - BeforeEach(func() { - header1, err := blockChain.GetHeaderByNumber(6791668) - Expect(err).ToNot(HaveOccurred()) - header2, err := blockChain.GetHeaderByNumber(6791669) - Expect(err).ToNot(HaveOccurred()) - header3, err := blockChain.GetHeaderByNumber(6791670) - Expect(err).ToNot(HaveOccurred()) - header4, err := blockChain.GetHeaderByNumber(6885695) - Expect(err).ToNot(HaveOccurred()) - header5, err := blockChain.GetHeaderByNumber(6885696) - Expect(err).ToNot(HaveOccurred()) - header6, err := blockChain.GetHeaderByNumber(6885697) - Expect(err).ToNot(HaveOccurred()) - headerRepository.CreateOrUpdateHeader(header1) - headerID, err = headerRepository.CreateOrUpdateHeader(header2) - Expect(err).ToNot(HaveOccurred()) - headerRepository.CreateOrUpdateHeader(header3) - headerRepository.CreateOrUpdateHeader(header4) - headerID2, err = headerRepository.CreateOrUpdateHeader(header5) - Expect(err).ToNot(HaveOccurred()) - headerRepository.CreateOrUpdateHeader(header6) - }) - - It("Transforms watched contract data into custom repositories", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) - t.SetMethods(constants.EnsContractAddress, nil) - t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) - t.SetMethods(constants.TusdContractAddress, nil) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - - newOwnerLog := test_helpers.LightNewOwnerLog{} - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.newowner_event", ensAddr)).StructScan(&newOwnerLog) - Expect(err).ToNot(HaveOccurred()) - // We don't know vulcID, so compare individual fields instead of complete structures - Expect(newOwnerLog.HeaderID).To(Equal(headerID2)) - Expect(newOwnerLog.Node).To(Equal("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae")) - Expect(newOwnerLog.Label).To(Equal("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047")) - Expect(newOwnerLog.Owner).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")) - - transferLog := test_helpers.LightTransferLog{} - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.transfer_event", tusdAddr)).StructScan(&transferLog) - Expect(err).ToNot(HaveOccurred()) - // We don't know vulcID, so compare individual fields instead of complete structures - Expect(transferLog.HeaderID).To(Equal(headerID)) - Expect(transferLog.From).To(Equal("0x1062a747393198f70F71ec65A582423Dba7E5Ab3")) - Expect(transferLog.To).To(Equal("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0")) - Expect(transferLog.Value).To(Equal("9998940000000000000000")) - }) - - It("Keeps track of contract-related hashes and addresses while transforming event data if they need to be used for later method polling", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) - t.SetMethods(constants.EnsContractAddress, []string{"owner"}) - t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) - t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"}) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - ens, ok := t.Contracts[ensAddr] - Expect(ok).To(Equal(true)) - tusd, ok := t.Contracts[tusdAddr] - Expect(ok).To(Equal(true)) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - Expect(len(ens.EmittedHashes)).To(Equal(2)) - Expect(len(ens.EmittedAddrs)).To(Equal(0)) - Expect(len(tusd.EmittedAddrs)).To(Equal(4)) - Expect(len(tusd.EmittedHashes)).To(Equal(0)) - - b, ok := ens.EmittedHashes[common.HexToHash("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - b, ok = ens.EmittedHashes[common.HexToHash("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - b, ok = tusd.EmittedAddrs[common.HexToAddress("0x1062a747393198f70F71ec65A582423Dba7E5Ab3")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - b, ok = tusd.EmittedAddrs[common.HexToAddress("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - b, ok = tusd.EmittedAddrs[common.HexToAddress("0x571A326f5B15E16917dC17761c340c1ec5d06f6d")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - - b, ok = tusd.EmittedAddrs[common.HexToAddress("0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98")] - Expect(ok).To(Equal(true)) - Expect(b).To(Equal(true)) - }) - - It("Polls given methods for each contract, using list of collected values", func() { - t := transformer.NewTransformer("", blockChain, db) - t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"}) - t.SetMethods(constants.EnsContractAddress, []string{"owner"}) - t.SetEvents(constants.TusdContractAddress, []string{"Transfer"}) - t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"}) - err = t.Init() - Expect(err).ToNot(HaveOccurred()) - err = t.Execute() - Expect(err).ToNot(HaveOccurred()) - - owner := test_helpers.Owner{} - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885696'", ensAddr)).StructScan(&owner) - Expect(err).ToNot(HaveOccurred()) - Expect(owner.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")) - Expect(owner.TokenName).To(Equal("")) - - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047' AND block = '6885696'", ensAddr)).StructScan(&owner) - Expect(err).ToNot(HaveOccurred()) - Expect(owner.Address).To(Equal("0x0000000000000000000000000000000000000000")) - Expect(owner.TokenName).To(Equal("")) - - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHItransformers.8IS625bFAKE' AND block = '6885696'", ensAddr)).StructScan(&owner) - Expect(err).To(HaveOccurred()) - - bal := test_helpers.BalanceOf{} - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x1062a747393198f70F71ec65A582423Dba7E5Ab3' AND block = '6791669'", tusdAddr)).StructScan(&bal) - Expect(err).ToNot(HaveOccurred()) - Expect(bal.Balance).To(Equal("55849938025000000000000")) - Expect(bal.TokenName).To(Equal("TrueUSD")) - - err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x09BbBBE21a5975cAc061D82f7b843b1234567890' AND block = '6791669'", tusdAddr)).StructScan(&bal) - Expect(err).To(HaveOccurred()) - }) - }) }) + +func getFakeTransformer(blockRetriever retriever.BlockRetriever, parsr parser.Parser, pollr poller.Poller) transformer.Transformer { + return transformer.Transformer{ + Parser: parsr, + BlockRetriever: blockRetriever, + Poller: pollr, + Contracts: map[string]*contract.Contract{}, + WatchedEvents: map[string][]string{}, + WantedMethods: map[string][]string{}, + ContractStart: map[string]int64{}, + EventArgs: map[string][]string{}, + MethodArgs: map[string][]string{}, + CreateAddrList: map[string]bool{}, + CreateHashList: map[string]bool{}, + } +}