diff --git a/Gododir/main.go b/Gododir/main.go index edb5a530..a71673f3 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("watchContract", 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..9d15b3fb --- /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.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 new file mode 100644 index 00000000..3762ad16 --- /dev/null +++ b/db/migrations/1510257608_add_contracts_table.down.sql @@ -0,0 +1 @@ +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 new file mode 100644 index 00000000..c6dfe39a --- /dev/null +++ b/db/migrations/1510257608_add_contracts_table.up.sql @@ -0,0 +1,5 @@ +CREATE TABLE watched_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 e9b5e91e..e6434288 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; @@ -118,6 +118,35 @@ 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 + 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: - -- @@ -132,6 +161,13 @@ ALTER TABLE ONLY blocks ALTER COLUMN id SET DEFAULT nextval('blocks_id_seq'::reg 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: - -- @@ -156,6 +192,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 new file mode 100644 index 00000000..a01b8d46 --- /dev/null +++ b/pkg/core/contract.go @@ -0,0 +1,5 @@ +package core + +type WatchedContract struct { + Hash string +} diff --git a/pkg/repositories/in_memory.go b/pkg/repositories/in_memory.go index 5af378fa..3ed1b901 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 + watchedContracts map[string]*core.WatchedContract +} + +func (repository *InMemory) CreateWatchedContract(watchedContract core.WatchedContract) error { + repository.watchedContracts[watchedContract.Hash] = &watchedContract + return nil +} + +func (repository *InMemory) IsWatchedContract(contractHash string) bool { + _, present := repository.watchedContracts[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), + watchedContracts: make(map[string]*core.WatchedContract), } } diff --git a/pkg/repositories/postgres.go b/pkg/repositories/postgres.go index fb11e3f7..d3fd99f4 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) CreateWatchedContract(contract core.WatchedContract) error { + _, err := repository.Db.Exec( + `INSERT INTO watched_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 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) + } + return exists +} func (repository Postgres) MaxBlockNumber() int64 { var highestBlockNumber int64 diff --git a/pkg/repositories/repository.go b/pkg/repositories/repository.go index 1df8d339..0664cd5c 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 + CreateWatchedContract(contract core.WatchedContract) error + IsWatchedContract(contractHash string) bool } diff --git a/pkg/repositories/repository_test.go b/pkg/repositories/repository_test.go index 65ace621..297013be 100644 --- a/pkg/repositories/repository_test.go +++ b/pkg/repositories/repository_test.go @@ -195,6 +195,13 @@ 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() { 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 "