From 30fadffb14a7fbef95cce0421da758e4f7a648c2 Mon Sep 17 00:00:00 2001 From: Matt Krump Date: Thu, 9 Nov 2017 13:59:12 -0600 Subject: [PATCH 1/3] 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 " From 4ad1d531a8df7e275affdebc40b228ec1d9769cf Mon Sep 17 00:00:00 2001 From: Matt Krump Date: Mon, 13 Nov 2017 10:11:27 -0600 Subject: [PATCH 2/3] Update contract naming per Eric PR review --- Gododir/main.go | 2 +- cmd/subscribe_contract/main.go | 2 +- .../1510257608_add_contracts_table.down.sql | 2 +- .../1510257608_add_contracts_table.up.sql | 2 +- db/schema.sql | 93 ++++++++++--------- pkg/core/contract.go | 2 +- pkg/repositories/in_memory.go | 14 +-- pkg/repositories/postgres.go | 6 +- pkg/repositories/repository.go | 2 +- pkg/repositories/repository_test.go | 4 +- 10 files changed, 66 insertions(+), 63 deletions(-) diff --git a/Gododir/main.go b/Gododir/main.go index 21f0e644..a71673f3 100644 --- a/Gododir/main.go +++ b/Gododir/main.go @@ -36,7 +36,7 @@ func tasks(p *do.Project) { do.M{"environment": environment, "startingNumber": startingNumber, "$in": "cmd/populate_blocks"}) }) - p.Task("subscribeToContract", nil, func(context *do.Context) { + p.Task("watchContract", nil, func(context *do.Context) { environment := parseEnvironment(context) contractHash := context.Args.MayString("", "contract-hash", "c") if contractHash == "" { diff --git a/cmd/subscribe_contract/main.go b/cmd/subscribe_contract/main.go index 3b1f2cc2..9d15b3fb 100644 --- a/cmd/subscribe_contract/main.go +++ b/cmd/subscribe_contract/main.go @@ -14,5 +14,5 @@ func main() { flag.Parse() config := cmd.LoadConfig(*environment) repository := repositories.NewPostgres(config.Database) - repository.CreateContract(core.Contract{Hash: *contractHash}) + repository.CreateWatchedContract(core.WatchedContract{Hash: *contractHash}) } diff --git a/db/migrations/1510257608_add_contracts_table.down.sql b/db/migrations/1510257608_add_contracts_table.down.sql index 9384f713..3762ad16 100644 --- a/db/migrations/1510257608_add_contracts_table.down.sql +++ b/db/migrations/1510257608_add_contracts_table.down.sql @@ -1 +1 @@ -DROP TABLE contracts \ No newline at end of file +DROP TABLE watched_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 index 83201096..c6dfe39a 100644 --- a/db/migrations/1510257608_add_contracts_table.up.sql +++ b/db/migrations/1510257608_add_contracts_table.up.sql @@ -1,4 +1,4 @@ -CREATE TABLE contracts +CREATE TABLE watched_contracts ( contract_id SERIAL PRIMARY KEY, contract_hash VARCHAR(66) diff --git a/db/schema.sql b/db/schema.sql index dc690b06..623e2c8e 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -3,7 +3,7 @@ -- -- Dumped from database version 10.0 --- Dumped by pg_dump version 10.0 +-- Dumped by pg_dump version 10.1 SET statement_timeout = 0; SET lock_timeout = 0; @@ -58,6 +58,7 @@ CREATE TABLE blocks ( -- CREATE SEQUENCE blocks_id_seq + AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE @@ -72,35 +73,6 @@ 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: - -- @@ -132,6 +104,7 @@ CREATE TABLE transactions ( -- CREATE SEQUENCE transactions_id_seq + AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE @@ -146,6 +119,36 @@ CREATE SEQUENCE transactions_id_seq ALTER SEQUENCE transactions_id_seq OWNED BY transactions.id; +-- +-- Name: watched_contracts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE watched_contracts ( + contract_id integer NOT NULL, + contract_hash character varying(66) +); + + +-- +-- Name: watched_contracts_contract_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE watched_contracts_contract_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: watched_contracts_contract_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE watched_contracts_contract_id_seq OWNED BY watched_contracts.contract_id; + + -- -- Name: blocks id; Type: DEFAULT; Schema: public; Owner: - -- @@ -153,13 +156,6 @@ 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: - -- @@ -167,6 +163,13 @@ ALTER TABLE ONLY contracts ALTER COLUMN contract_id SET DEFAULT nextval('contrac ALTER TABLE ONLY transactions ALTER COLUMN id SET DEFAULT nextval('transactions_id_seq'::regclass); +-- +-- Name: watched_contracts contract_id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY watched_contracts ALTER COLUMN contract_id SET DEFAULT nextval('watched_contracts_contract_id_seq'::regclass); + + -- -- Name: blocks blocks_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -175,14 +178,6 @@ 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: - -- @@ -199,6 +194,14 @@ ALTER TABLE ONLY transactions ADD CONSTRAINT transactions_pkey PRIMARY KEY (id); +-- +-- Name: watched_contracts watched_contracts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY watched_contracts + ADD CONSTRAINT watched_contracts_pkey PRIMARY KEY (contract_id); + + -- -- Name: block_number_index; Type: INDEX; Schema: public; Owner: - -- diff --git a/pkg/core/contract.go b/pkg/core/contract.go index 370f4fd6..a01b8d46 100644 --- a/pkg/core/contract.go +++ b/pkg/core/contract.go @@ -1,5 +1,5 @@ package core -type Contract struct { +type WatchedContract struct { Hash string } diff --git a/pkg/repositories/in_memory.go b/pkg/repositories/in_memory.go index 35ec08e9..3ed1b901 100644 --- a/pkg/repositories/in_memory.go +++ b/pkg/repositories/in_memory.go @@ -5,17 +5,17 @@ import ( ) type InMemory struct { - blocks map[int64]*core.Block - contracts map[string]*core.Contract + blocks map[int64]*core.Block + watchedContracts map[string]*core.WatchedContract } -func (repository *InMemory) CreateContract(contract core.Contract) error { - repository.contracts[contract.Hash] = &contract +func (repository *InMemory) CreateWatchedContract(watchedContract core.WatchedContract) error { + repository.watchedContracts[watchedContract.Hash] = &watchedContract return nil } func (repository *InMemory) IsWatchedContract(contractHash string) bool { - _, present := repository.contracts[contractHash] + _, present := repository.watchedContracts[contractHash] return present } @@ -31,8 +31,8 @@ func (repository *InMemory) MissingBlockNumbers(startingBlockNumber int64, endin func NewInMemory() *InMemory { return &InMemory{ - blocks: make(map[int64]*core.Block), - contracts: make(map[string]*core.Contract), + blocks: make(map[int64]*core.Block), + watchedContracts: make(map[string]*core.WatchedContract), } } diff --git a/pkg/repositories/postgres.go b/pkg/repositories/postgres.go index 9bbccfca..444523fb 100644 --- a/pkg/repositories/postgres.go +++ b/pkg/repositories/postgres.go @@ -31,9 +31,9 @@ func NewPostgres(databaseConfig config.Database) Postgres { return Postgres{Db: db} } -func (repository Postgres) CreateContract(contract core.Contract) error { +func (repository Postgres) CreateWatchedContract(contract core.WatchedContract) error { _, err := repository.Db.Exec( - `INSERT INTO contracts (contract_hash) VALUES ($1)`, contract.Hash) + `INSERT INTO watched_contracts (contract_hash) VALUES ($1)`, contract.Hash) if err != nil { return ErrDBInsertFailed } @@ -43,7 +43,7 @@ func (repository Postgres) CreateContract(contract core.Contract) error { 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) + `SELECT exists(select 1 from watched_contracts where contract_hash=$1) FROM watched_contracts`, contractHash).Scan(&exists) if err != nil && err != sql.ErrNoRows { log.Fatalf("error checking if row exists %v", err) } diff --git a/pkg/repositories/repository.go b/pkg/repositories/repository.go index d355a4f5..0664cd5c 100644 --- a/pkg/repositories/repository.go +++ b/pkg/repositories/repository.go @@ -8,6 +8,6 @@ type Repository interface { FindBlockByNumber(blockNumber int64) *core.Block MaxBlockNumber() int64 MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64) []int64 - CreateContract(contract core.Contract) error + CreateWatchedContract(contract core.WatchedContract) error IsWatchedContract(contractHash string) bool } diff --git a/pkg/repositories/repository_test.go b/pkg/repositories/repository_test.go index 6e139a34..11e5b943 100644 --- a/pkg/repositories/repository_test.go +++ b/pkg/repositories/repository_test.go @@ -192,8 +192,8 @@ 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"}) + 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()) From e510154c81d28b20499fa98241e566c58a76f425 Mon Sep 17 00:00:00 2001 From: Matt Krump Date: Mon, 13 Nov 2017 10:37:09 -0600 Subject: [PATCH 3/3] mend --- db/schema.sql | 3 --- 1 file changed, 3 deletions(-) diff --git a/db/schema.sql b/db/schema.sql index 623e2c8e..bfa8cc2c 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -58,7 +58,6 @@ CREATE TABLE blocks ( -- CREATE SEQUENCE blocks_id_seq - AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE @@ -104,7 +103,6 @@ CREATE TABLE transactions ( -- CREATE SEQUENCE transactions_id_seq - AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE @@ -134,7 +132,6 @@ CREATE TABLE watched_contracts ( -- CREATE SEQUENCE watched_contracts_contract_id_seq - AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE