diff --git a/.travis.yml b/.travis.yml index 1d93167d..db4a5119 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,16 @@ +dist: trusty +sudo: required language: go go: - 1.9 +services: + - postgresql +before_script: + - go get -u -d github.com/mattes/migrate/cli github.com/lib/pq + - go build -tags 'postgres' -o /usr/local/bin/migrate github.com/mattes/migrate/cli + - psql -c 'create database vulcanize;' -U postgres + - migrate -database 'postgresql://localhost:5432/vulcanize?sslmode=disable' -path ./migrations up script: - go test -v ./core/... +notifications: + email: false diff --git a/Gopkg.lock b/Gopkg.lock index ecf95c80..a0c67bb3 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -19,6 +19,18 @@ revision = "817915b46b97fd7bb80e8ab6b69f01a53ac3eebf" version = "v1.6.0" +[[projects]] + branch = "master" + name = "github.com/jmoiron/sqlx" + packages = [".","reflectx"] + revision = "3379e5993990b1f927fc8db926485e6f6becf2d2" + +[[projects]] + branch = "master" + name = "github.com/lib/pq" + packages = [".","oid"] + revision = "b609790bd85edf8e9ab7e0f8912750a786177bcf" + [[projects]] name = "github.com/onsi/ginkgo" packages = [".","config","internal/codelocation","internal/containernode","internal/failer","internal/leafnodes","internal/remote","internal/spec","internal/spec_iterator","internal/specrunner","internal/suite","internal/testingtproxy","internal/writer","reporters","reporters/stenographer","reporters/stenographer/support/go-colorable","reporters/stenographer/support/go-isatty","types"] @@ -88,6 +100,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "1f89d2d001b1d5929ecd9f83d34d67edc4c1ae8baea497f4b5b76d9f6cc7f8d5" + inputs-digest = "28c66c62724453afdc526c6cf9de955240b487fb81b027fefbe7ed4e1545caec" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 14015b23..0b5b260c 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -28,3 +28,7 @@ [[constraint]] branch = "master" name = "github.com/jmoiron/sqlx" + +[[constraint]] + branch = "master" + name = "github.com/lib/pq" diff --git a/README.md b/README.md index 3f169743..674c83b8 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,19 @@ - Go 1.9+ - https://github.com/golang/dep + - `brew install dep` works for Homebrew users - Postgres 10 ### Cloning the Repository 1. `git config --global url."git@github.com:".insteadOf "https://github.com/"` - By default, `go get` does not work for private GitHub repos. This will fix that. - 2. `go get github.com/8thlight/vulcanizedb` 3. `go get github.com/ethereum/go-ethereum` - This will take a while and gives poor indication of progress. 4. `go install github.com/ethereum/go-ethereum/cmd/geth` +5. `cd $GOPATH/src/github.com/8thlight/vulcanizedb` +6. `dep ensure` ### Setting up the Development Database @@ -27,7 +29,8 @@ 3. `go get -u -d github.com/mattes/migrate/cli github.com/lib/pq` 4. `go build -tags 'postgres' -o /usr/local/bin/migrate github.com/mattes/migrate/cli` 5. `createdb vulcanize` -6. `migrate -database 'postgresql://localhost:5432/vulcanize?sslmode=disable' -path ./migrations up` +6. `cd $GOPATH/src/github.com/8thlight/vulcanizedb` +7. `migrate -database 'postgresql://localhost:5432/vulcanize?sslmode=disable' -path ./migrations up` Adding a new migration: `migrate -database postgresql://localhost:5432/postgres create -dir ./migrations -ext sql ` @@ -44,19 +47,21 @@ Here are some instructions for creating a private blockchain that does not depen `./scripts/start_blockchain` +### IPC File Paths + +The default location for Ethereum is: + - `$HOME/Library/Ethereum` for Mac + - `$HOME/.ethereum` for Ubuntu + - `$GOPATH/src/gihub.com/8thlight/vulcanizedb/test_data_dir/geth.ipc` for private blockchain. + +**Note the location of the ipc file is outputted when you connect to a blockchain. It is needed to start the listener below** + ## Running Listener 1. Start a blockchain. 2. In a separate terminal start listener (ipcDir location) - `go run main.go --ipcPath /path/to/file.ipc` -### IPC File Paths - -The default location for the Ethereum blockchain to be stored is: - - `$HOME/Library/Ethereum` for Mac - - `$HOME/.ethereum` for Ubuntu - - `$GOPATH/src/gihub.com/8thlight/vulcanizedb/test_data_dir/geth.ipc` for private blockchain. - ## Running the Tests ### Integration Test @@ -68,4 +73,4 @@ In order to run the integration tests, you will need to run them against a real ### Unit Tests -`go test ./core` \ No newline at end of file +1. `go test ./core` diff --git a/core/blockchain_db_observer.go b/core/blockchain_db_observer.go new file mode 100644 index 00000000..51622592 --- /dev/null +++ b/core/blockchain_db_observer.go @@ -0,0 +1,19 @@ +package core + +import ( + "github.com/jmoiron/sqlx" + _ "github.com/lib/pq" +) + +type BlockRecord struct { + BlockNumber int64 `db:"block_number"` +} + +type BlockchainDBObserver struct { + Db *sqlx.DB +} + +func (observer BlockchainDBObserver) NotifyBlockAdded(block Block) { + observer.Db.NamedExec("INSERT INTO blocks (block_number) VALUES (:block_number)", &BlockRecord{BlockNumber: block.Number.Int64()}) + //observer.Db.MustExec("Insert INTO blocks (block_number) VALUES ($1)", block.Number.Int64()) +} diff --git a/core/blockchain_db_observer_test.go b/core/blockchain_db_observer_test.go new file mode 100644 index 00000000..83824107 --- /dev/null +++ b/core/blockchain_db_observer_test.go @@ -0,0 +1,72 @@ +package core_test + +import ( + "math/big" + + "fmt" + + "github.com/8thlight/vulcanizedb/core" + "github.com/jmoiron/sqlx" + _ "github.com/lib/pq" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +const ( + host = "localhost" + port = 5432 + user = "postgres" + password = "postgres" + dbname = "vulcanize" +) + +var _ = Describe("Saving blocks to the database", func() { + + var db *sqlx.DB + var err error + + BeforeEach(func() { + pgConfig := fmt.Sprintf( + "host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", + host, port, user, password, dbname) + db, err = sqlx.Connect("postgres", pgConfig) + db.MustExec("DELETE FROM blocks") + }) + + It("implements the observer interface", func() { + var observer core.BlockchainObserver = core.BlockchainDBObserver{Db: db} + Expect(observer).NotTo(BeNil()) + }) + + It("connects to the database", func() { + Expect(err).Should(BeNil()) + Expect(db).ShouldNot(BeNil()) + }) + + It("starts with no blocks", func() { + var count int + queryError := db.Get(&count, "SELECT COUNT(*) FROM blocks") + Expect(queryError).Should(BeNil()) + Expect(count).Should(Equal(0)) + }) + + It("inserts a block", func() { + block := core.Block{Number: big.NewInt(1)} + + observer := core.BlockchainDBObserver{Db: db} + observer.NotifyBlockAdded(block) + + rows, err := db.Queryx("SELECT * FROM blocks") + Expect(err).To(BeNil()) + var savedBlocks []core.BlockRecord + for rows.Next() { + var savedBlock core.BlockRecord + rows.StructScan(&savedBlock) + savedBlocks = append(savedBlocks, savedBlock) + } + + Expect(len(savedBlocks)).To(Equal(1)) + Expect(savedBlocks[0].BlockNumber).To(Equal(int64(1))) + }) + +}) diff --git a/main.go b/main.go index 20a6d2cc..133480f3 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,11 @@ package main import ( "flag" + + "log" + "github.com/8thlight/vulcanizedb/core" + "github.com/jmoiron/sqlx" ) func main() { @@ -11,5 +15,11 @@ func main() { var blockchain core.Blockchain = core.NewGethBlockchain(*ipcPath) blockchain.RegisterObserver(core.BlockchainLoggingObserver{}) + pgConfig := "host=localhost port=5432 dbname=vulcanize sslmode=disable" + db, err := sqlx.Connect("postgres", pgConfig) + if err != nil { + log.Fatalf("Error connecting to DB: %v\n", err) + } + blockchain.RegisterObserver(core.BlockchainDBObserver{Db: db}) blockchain.SubscribeToEvents() }