From 30fadffb14a7fbef95cce0421da758e4f7a648c2 Mon Sep 17 00:00:00 2001 From: Matt Krump Date: Thu, 9 Nov 2017 13:59:12 -0600 Subject: [PATCH] Add contracts table / start building out watch contracts --- Gododir/main.go | 10 +++++ cmd/subscribe_contract/main.go | 18 ++++++++ .../1510257608_add_contracts_table.down.sql | 1 + .../1510257608_add_contracts_table.up.sql | 5 +++ db/schema.sql | 44 +++++++++++++++++++ pkg/core/contract.go | 5 +++ pkg/repositories/in_memory.go | 16 ++++++- pkg/repositories/postgres.go | 25 +++++++++-- pkg/repositories/repository.go | 2 + pkg/repositories/repository_test.go | 7 +++ scripts/create_migration | 2 +- 11 files changed, 129 insertions(+), 6 deletions(-) create mode 100644 cmd/subscribe_contract/main.go create mode 100644 db/migrations/1510257608_add_contracts_table.down.sql create mode 100644 db/migrations/1510257608_add_contracts_table.up.sql create mode 100644 pkg/core/contract.go diff --git a/Gododir/main.go b/Gododir/main.go index edb5a530..21f0e644 100644 --- a/Gododir/main.go +++ b/Gododir/main.go @@ -36,6 +36,16 @@ func tasks(p *do.Project) { do.M{"environment": environment, "startingNumber": startingNumber, "$in": "cmd/populate_blocks"}) }) + p.Task("subscribeToContract", 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/subscribe_contract"}) + }) + p.Task("migrate", nil, func(context *do.Context) { environment := parseEnvironment(context) cfg := cmd.LoadConfig(environment) diff --git a/cmd/subscribe_contract/main.go b/cmd/subscribe_contract/main.go new file mode 100644 index 00000000..3b1f2cc2 --- /dev/null +++ b/cmd/subscribe_contract/main.go @@ -0,0 +1,18 @@ +package main + +import ( + "flag" + + "github.com/8thlight/vulcanizedb/cmd" + "github.com/8thlight/vulcanizedb/pkg/core" + "github.com/8thlight/vulcanizedb/pkg/repositories" +) + +func main() { + environment := flag.String("environment", "", "Environment name") + contractHash := flag.String("contract-hash", "", "contract-hash=x1234") + flag.Parse() + config := cmd.LoadConfig(*environment) + repository := repositories.NewPostgres(config.Database) + repository.CreateContract(core.Contract{Hash: *contractHash}) +} diff --git a/db/migrations/1510257608_add_contracts_table.down.sql b/db/migrations/1510257608_add_contracts_table.down.sql new file mode 100644 index 00000000..9384f713 --- /dev/null +++ b/db/migrations/1510257608_add_contracts_table.down.sql @@ -0,0 +1 @@ +DROP TABLE contracts \ No newline at end of file diff --git a/db/migrations/1510257608_add_contracts_table.up.sql b/db/migrations/1510257608_add_contracts_table.up.sql new file mode 100644 index 00000000..83201096 --- /dev/null +++ b/db/migrations/1510257608_add_contracts_table.up.sql @@ -0,0 +1,5 @@ +CREATE TABLE contracts +( + contract_id SERIAL PRIMARY KEY, + contract_hash VARCHAR(66) +) \ No newline at end of file diff --git a/db/schema.sql b/db/schema.sql index 2f6b40ab..dc690b06 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -72,6 +72,35 @@ CREATE SEQUENCE blocks_id_seq ALTER SEQUENCE blocks_id_seq OWNED BY blocks.id; +-- +-- Name: contracts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE contracts ( + contract_id integer NOT NULL, + contract_hash character varying(66) +); + + +-- +-- Name: contracts_contract_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE contracts_contract_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: contracts_contract_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE contracts_contract_id_seq OWNED BY contracts.contract_id; + + -- -- Name: schema_migrations; Type: TABLE; Schema: public; Owner: - -- @@ -124,6 +153,13 @@ ALTER SEQUENCE transactions_id_seq OWNED BY transactions.id; ALTER TABLE ONLY blocks ALTER COLUMN id SET DEFAULT nextval('blocks_id_seq'::regclass); +-- +-- Name: contracts contract_id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY contracts ALTER COLUMN contract_id SET DEFAULT nextval('contracts_contract_id_seq'::regclass); + + -- -- Name: transactions id; Type: DEFAULT; Schema: public; Owner: - -- @@ -139,6 +175,14 @@ ALTER TABLE ONLY blocks ADD CONSTRAINT blocks_pkey PRIMARY KEY (id); +-- +-- Name: contracts contracts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY contracts + ADD CONSTRAINT contracts_pkey PRIMARY KEY (contract_id); + + -- -- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- diff --git a/pkg/core/contract.go b/pkg/core/contract.go new file mode 100644 index 00000000..370f4fd6 --- /dev/null +++ b/pkg/core/contract.go @@ -0,0 +1,5 @@ +package core + +type Contract struct { + Hash string +} diff --git a/pkg/repositories/in_memory.go b/pkg/repositories/in_memory.go index 5af378fa..35ec08e9 100644 --- a/pkg/repositories/in_memory.go +++ b/pkg/repositories/in_memory.go @@ -5,7 +5,18 @@ import ( ) type InMemory struct { - blocks map[int64]*core.Block + blocks map[int64]*core.Block + contracts map[string]*core.Contract +} + +func (repository *InMemory) CreateContract(contract core.Contract) error { + repository.contracts[contract.Hash] = &contract + return nil +} + +func (repository *InMemory) IsWatchedContract(contractHash string) bool { + _, present := repository.contracts[contractHash] + return present } func (repository *InMemory) MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64) []int64 { @@ -20,7 +31,8 @@ func (repository *InMemory) MissingBlockNumbers(startingBlockNumber int64, endin func NewInMemory() *InMemory { return &InMemory{ - blocks: make(map[int64]*core.Block), + blocks: make(map[int64]*core.Block), + contracts: make(map[string]*core.Contract), } } diff --git a/pkg/repositories/postgres.go b/pkg/repositories/postgres.go index 72cdd660..9bbccfca 100644 --- a/pkg/repositories/postgres.go +++ b/pkg/repositories/postgres.go @@ -18,6 +18,10 @@ type Postgres struct { Db *sqlx.DB } +var ( + ErrDBInsertFailed = errors.New("postgres: insert failed") +) + func NewPostgres(databaseConfig config.Database) Postgres { connectString := config.DbConnectionString(databaseConfig) db, err := sqlx.Connect("postgres", connectString) @@ -27,9 +31,24 @@ func NewPostgres(databaseConfig config.Database) Postgres { return Postgres{Db: db} } -var ( - ErrDBInsertFailed = errors.New("postgres: insert failed") -) +func (repository Postgres) CreateContract(contract core.Contract) error { + _, err := repository.Db.Exec( + `INSERT INTO contracts (contract_hash) VALUES ($1)`, contract.Hash) + if err != nil { + return ErrDBInsertFailed + } + return nil +} + +func (repository Postgres) IsWatchedContract(contractHash string) bool { + var exists bool + err := repository.Db.QueryRow( + `SELECT exists(select 1 from contracts where contract_hash=$1) FROM contracts`, contractHash).Scan(&exists) + if err != nil && err != sql.ErrNoRows { + log.Fatalf("error checking if row exists %v", err) + } + return exists +} func (repository Postgres) MaxBlockNumber() int64 { var highestBlockNumber int64 diff --git a/pkg/repositories/repository.go b/pkg/repositories/repository.go index 1df8d339..d355a4f5 100644 --- a/pkg/repositories/repository.go +++ b/pkg/repositories/repository.go @@ -8,4 +8,6 @@ type Repository interface { FindBlockByNumber(blockNumber int64) *core.Block MaxBlockNumber() int64 MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64) []int64 + CreateContract(contract core.Contract) error + IsWatchedContract(contractHash string) bool } diff --git a/pkg/repositories/repository_test.go b/pkg/repositories/repository_test.go index 98e0fe28..6e139a34 100644 --- a/pkg/repositories/repository_test.go +++ b/pkg/repositories/repository_test.go @@ -192,6 +192,13 @@ var _ = Describe("Repositories", func() { Expect(repository.MissingBlockNumbers(1, 5)).To(Equal([]int64{1, 2, 4, 5})) }) + It("Adds a contract to the contracts table", func() { + repository.CreateContract(core.Contract{Hash: "x123"}) + + Expect(repository.IsWatchedContract("x123")).To(BeTrue()) + Expect(repository.IsWatchedContract("x456")).To(BeFalse()) + }) + }) Describe("The max block numbers", func() { diff --git a/scripts/create_migration b/scripts/create_migration index b51a0cae..23148ff6 100755 --- a/scripts/create_migration +++ b/scripts/create_migration @@ -2,7 +2,7 @@ if [ $# -eq 1 ] then - migrate create -dir ./migrations -ext sql $1 + migrate create -dir ./db/migrations -ext sql $1 else echo "**An Error Occurred**" echo "Usage: ./scripts/create_migration "