From f50a4d7726c32144df7f7ac92313e22ade4c6260 Mon Sep 17 00:00:00 2001 From: Eric Meyer Date: Mon, 13 Nov 2017 09:58:36 -0600 Subject: [PATCH] Allow users to watch and print summaries for contracts --- Gododir/main.go | 10 ++++ cmd/show_contract_summary/main.go | 25 ++++++++++ pkg/repositories/in_memory.go | 4 ++ pkg/repositories/postgres.go | 17 +++++++ pkg/repositories/repository.go | 1 + pkg/repositories/repository_test.go | 26 ++++++---- pkg/repositories/testing/helpers.go | 1 + pkg/watched_contracts/reporter.go | 10 ++++ pkg/watched_contracts/summary.go | 30 ++++++++++++ pkg/watched_contracts/summary_test.go | 47 +++++++++++++++++++ .../watched_contracts_suite_test.go | 13 +++++ 11 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 cmd/show_contract_summary/main.go create mode 100644 pkg/watched_contracts/reporter.go create mode 100644 pkg/watched_contracts/summary.go create mode 100644 pkg/watched_contracts/summary_test.go create mode 100644 pkg/watched_contracts/watched_contracts_suite_test.go diff --git a/Gododir/main.go b/Gododir/main.go index a71673f3..24c8d0a7 100644 --- a/Gododir/main.go +++ b/Gododir/main.go @@ -66,6 +66,16 @@ func tasks(p *do.Project) { context.Bash(dumpSchema) }) + p.Task("showContractSummary", nil, func(context *do.Context) { + environment := parseEnvironment(context) + contractHash := context.Args.MayString("", "contract-hash", "c") + if contractHash == "" { + log.Fatalln("--contract-hash required") + } + context.Start(`go run main.go --environment={{.environment}} --contract-hash={{.contractHash}}`, + do.M{"environment": environment, "contractHash": contractHash, "$in": "cmd/show_contract_summary"}) + }) + } func main() { diff --git a/cmd/show_contract_summary/main.go b/cmd/show_contract_summary/main.go new file mode 100644 index 00000000..a0454db5 --- /dev/null +++ b/cmd/show_contract_summary/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "flag" + + "log" + + "github.com/8thlight/vulcanizedb/cmd" + "github.com/8thlight/vulcanizedb/pkg/repositories" + "github.com/8thlight/vulcanizedb/pkg/watched_contracts" +) + +func main() { + environment := flag.String("environment", "", "Environment name") + contractHash := flag.String("contract-hash", "", "Contract hash to show summary") + flag.Parse() + config := cmd.LoadConfig(*environment) + + repository := repositories.NewPostgres(config.Database) + contractSummary, err := watched_contracts.NewSummary(repository, *contractHash) + if err != nil { + log.Fatalln(err) + } + watched_contracts.PrintReport(contractSummary) +} diff --git a/pkg/repositories/in_memory.go b/pkg/repositories/in_memory.go index 3ed1b901..65f281e3 100644 --- a/pkg/repositories/in_memory.go +++ b/pkg/repositories/in_memory.go @@ -19,6 +19,10 @@ func (repository *InMemory) IsWatchedContract(contractHash string) bool { return present } +func (repository *InMemory) FindWatchedContract(contractHash string) *core.WatchedContract { + return repository.watchedContracts[contractHash] +} + func (repository *InMemory) MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64) []int64 { missingNumbers := []int64{} for blockNumber := int64(startingBlockNumber); blockNumber <= endingBlockNumber; blockNumber++ { diff --git a/pkg/repositories/postgres.go b/pkg/repositories/postgres.go index d3fd99f4..f2d145df 100644 --- a/pkg/repositories/postgres.go +++ b/pkg/repositories/postgres.go @@ -50,6 +50,23 @@ func (repository Postgres) IsWatchedContract(contractHash string) bool { return exists } +func (repository Postgres) FindWatchedContract(contractHash string) *core.WatchedContract { + var savedContracts []core.WatchedContract + contractRows, _ := repository.Db.Query( + `select contract_hash from watched_contracts where contract_hash=$1`, contractHash) + for contractRows.Next() { + var savedContractHash string + contractRows.Scan(&savedContractHash) + savedContract := core.WatchedContract{Hash: savedContractHash} + savedContracts = append(savedContracts, savedContract) + } + if len(savedContracts) > 0 { + return &savedContracts[0] + } else { + return nil + } +} + func (repository Postgres) MaxBlockNumber() int64 { var highestBlockNumber int64 repository.Db.Get(&highestBlockNumber, `SELECT MAX(block_number) FROM blocks`) diff --git a/pkg/repositories/repository.go b/pkg/repositories/repository.go index 0664cd5c..bc246b2b 100644 --- a/pkg/repositories/repository.go +++ b/pkg/repositories/repository.go @@ -10,4 +10,5 @@ type Repository interface { MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64) []int64 CreateWatchedContract(contract core.WatchedContract) error IsWatchedContract(contractHash string) bool + FindWatchedContract(contractHash string) *core.WatchedContract } diff --git a/pkg/repositories/repository_test.go b/pkg/repositories/repository_test.go index 297013be..f09dd326 100644 --- a/pkg/repositories/repository_test.go +++ b/pkg/repositories/repository_test.go @@ -194,14 +194,6 @@ var _ = Describe("Repositories", func() { Expect(repository.MissingBlockNumbers(1, 5)).To(Equal([]int64{1, 2, 4, 5})) }) - - It("Adds a contract to the watched_contracts table", func() { - repository.CreateWatchedContract(core.WatchedContract{Hash: "x123"}) - - Expect(repository.IsWatchedContract("x123")).To(BeTrue()) - Expect(repository.IsWatchedContract("x456")).To(BeFalse()) - }) - }) Describe("The max block numbers", func() { @@ -218,6 +210,24 @@ var _ = Describe("Repositories", func() { Expect(repository.MaxBlockNumber()).To(Equal(int64(10))) }) }) + + Describe("Creating watched contracts", func() { + It("returns the watched contract when it exists", func() { + repository.CreateWatchedContract(core.WatchedContract{Hash: "x123"}) + + watchedContract := repository.FindWatchedContract("x123") + Expect(watchedContract).NotTo(BeNil()) + Expect(watchedContract.Hash).To(Equal("x123")) + + Expect(repository.IsWatchedContract("x123")).To(BeTrue()) + Expect(repository.IsWatchedContract("x456")).To(BeFalse()) + }) + + It("returns nil if contract does not exist", func() { + watchedContract := repository.FindWatchedContract("x123") + Expect(watchedContract).To(BeNil()) + }) + }) } Describe("In memory repository", func() { diff --git a/pkg/repositories/testing/helpers.go b/pkg/repositories/testing/helpers.go index e95407ef..c10ae888 100644 --- a/pkg/repositories/testing/helpers.go +++ b/pkg/repositories/testing/helpers.go @@ -3,6 +3,7 @@ package testing import "github.com/8thlight/vulcanizedb/pkg/repositories" func ClearData(postgres repositories.Postgres) { + postgres.Db.MustExec("DELETE FROM watched_contracts") postgres.Db.MustExec("DELETE FROM transactions") postgres.Db.MustExec("DELETE FROM blocks") } diff --git a/pkg/watched_contracts/reporter.go b/pkg/watched_contracts/reporter.go new file mode 100644 index 00000000..f5ec8e6d --- /dev/null +++ b/pkg/watched_contracts/reporter.go @@ -0,0 +1,10 @@ +package watched_contracts + +import "fmt" + +func PrintReport(summary *ContractSummary) { + fmt.Printf(`********************Contract Summary*********************** + +HASH: %v +`, summary.ContractHash) +} diff --git a/pkg/watched_contracts/summary.go b/pkg/watched_contracts/summary.go new file mode 100644 index 00000000..3b935859 --- /dev/null +++ b/pkg/watched_contracts/summary.go @@ -0,0 +1,30 @@ +package watched_contracts + +import ( + "errors" + "fmt" + + "github.com/8thlight/vulcanizedb/pkg/core" + "github.com/8thlight/vulcanizedb/pkg/repositories" +) + +type ContractSummary struct { + ContractHash string +} + +var NewContractNotWatchedErr = func(contractHash string) error { + return errors.New(fmt.Sprintf("Contract %v not being watched", contractHash)) +} + +func NewSummary(repository repositories.Repository, contractHash string) (*ContractSummary, error) { + contract := repository.FindWatchedContract(contractHash) + if contract != nil { + return newContractSummary(*contract), nil + } else { + return nil, NewContractNotWatchedErr(contractHash) + } +} + +func newContractSummary(contract core.WatchedContract) *ContractSummary { + return &ContractSummary{ContractHash: contract.Hash} +} diff --git a/pkg/watched_contracts/summary_test.go b/pkg/watched_contracts/summary_test.go new file mode 100644 index 00000000..9081b3fe --- /dev/null +++ b/pkg/watched_contracts/summary_test.go @@ -0,0 +1,47 @@ +package watched_contracts_test + +import ( + "github.com/8thlight/vulcanizedb/pkg/core" + "github.com/8thlight/vulcanizedb/pkg/repositories" + "github.com/8thlight/vulcanizedb/pkg/watched_contracts" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("The watched contract summary", func() { + + Context("when the given contract is not being watched", func() { + It("returns an error", func() { + repository := repositories.NewInMemory() + + contractSummary, err := watched_contracts.NewSummary(repository, "123") + + Expect(contractSummary).To(BeNil()) + Expect(err).NotTo(BeNil()) + }) + }) + + Context("when the given contract is being watched", func() { + It("returns the summary", func() { + repository := repositories.NewInMemory() + watchedContract := core.WatchedContract{Hash: "0x123"} + repository.CreateWatchedContract(watchedContract) + + contractSummary, err := watched_contracts.NewSummary(repository, "0x123") + + Expect(contractSummary).NotTo(BeNil()) + Expect(err).To(BeNil()) + }) + + It("includes the contract hash in the summary", func() { + repository := repositories.NewInMemory() + watchedContract := core.WatchedContract{Hash: "0x123"} + repository.CreateWatchedContract(watchedContract) + + contractSummary, _ := watched_contracts.NewSummary(repository, "0x123") + + Expect(contractSummary.ContractHash).To(Equal("0x123")) + }) + }) + +}) diff --git a/pkg/watched_contracts/watched_contracts_suite_test.go b/pkg/watched_contracts/watched_contracts_suite_test.go new file mode 100644 index 00000000..82ca609b --- /dev/null +++ b/pkg/watched_contracts/watched_contracts_suite_test.go @@ -0,0 +1,13 @@ +package watched_contracts_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestWatchedContracts(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "WatchedContracts Suite") +}