forked from cerc-io/ipld-eth-server
Handle events
- Adds interfaces for developers to build handlers that update data in response to log events - Resolves #29
This commit is contained in:
@@ -1,79 +1,6 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"fmt"
|
||||
|
||||
"path/filepath"
|
||||
|
||||
"path"
|
||||
"runtime"
|
||||
|
||||
"errors"
|
||||
|
||||
"net/url"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Database Database
|
||||
Client Client
|
||||
}
|
||||
|
||||
var NewErrConfigFileNotFound = func(environment string) error {
|
||||
return errors.New(fmt.Sprintf("No configuration found for environment: %v", environment))
|
||||
}
|
||||
|
||||
var NewErrBadConnectionString = func(connectionString string) error {
|
||||
return errors.New(fmt.Sprintf("connection string is invalid: %v", connectionString))
|
||||
}
|
||||
|
||||
func NewConfig(environment string) (Config, error) {
|
||||
filenameWithExtension := fmt.Sprintf("%s.toml", environment)
|
||||
absolutePath := filepath.Join(ProjectRoot(), "environments", filenameWithExtension)
|
||||
config, err := parseConfigFile(absolutePath)
|
||||
if err != nil {
|
||||
return Config{}, NewErrConfigFileNotFound(environment)
|
||||
} else {
|
||||
if !filepath.IsAbs(config.Client.IPCPath) && !isUrl(config.Client.IPCPath) {
|
||||
config.Client.IPCPath = filepath.Join(ProjectRoot(), config.Client.IPCPath)
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
}
|
||||
|
||||
func ProjectRoot() string {
|
||||
var _, filename, _, _ = runtime.Caller(0)
|
||||
return path.Join(path.Dir(filename), "..", "..")
|
||||
}
|
||||
|
||||
func isUrl(s string) bool {
|
||||
_, err := url.ParseRequestURI(s)
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func fileExists(s string) bool {
|
||||
_, err := os.Stat(s)
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func parseConfigFile(filePath string) (Config, error) {
|
||||
var cfg Config
|
||||
if !isUrl(filePath) && !fileExists(filePath) {
|
||||
return Config{}, NewErrBadConnectionString(filePath)
|
||||
} else {
|
||||
_, err := toml.DecodeFile(filePath, &cfg)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
}
|
||||
|
||||
+10
-27
@@ -1,41 +1,24 @@
|
||||
package config_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
cfg "github.com/vulcanize/vulcanizedb/pkg/config"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var _ = Describe("Loading the config", func() {
|
||||
|
||||
It("reads the private config using the environment", func() {
|
||||
privateConfig, err := cfg.NewConfig("private")
|
||||
|
||||
testConfig := viper.New()
|
||||
testConfig.SetConfigName("private")
|
||||
testConfig.AddConfigPath("$GOPATH/src/github.com/vulcanize/vulcanizedb/environments/")
|
||||
err := testConfig.ReadInConfig()
|
||||
Expect(viper.Get("client.ipcpath")).To(BeNil())
|
||||
Expect(err).To(BeNil())
|
||||
Expect(privateConfig.Database.Hostname).To(Equal("localhost"))
|
||||
Expect(privateConfig.Database.Name).To(Equal("vulcanize_private"))
|
||||
Expect(privateConfig.Database.Port).To(Equal(5432))
|
||||
expandedPath := filepath.Join(cfg.ProjectRoot(), "test_data_dir/geth.ipc")
|
||||
Expect(privateConfig.Client.IPCPath).To(Equal(expandedPath))
|
||||
})
|
||||
|
||||
It("returns an error when there is no matching config file", func() {
|
||||
config, err := cfg.NewConfig("bad-config")
|
||||
|
||||
Expect(config).To(Equal(cfg.Config{}))
|
||||
Expect(err).NotTo(BeNil())
|
||||
})
|
||||
|
||||
It("reads the infura config using the environment", func() {
|
||||
infuraConfig, err := cfg.NewConfig("infura")
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
Expect(infuraConfig.Database.Hostname).To(Equal("localhost"))
|
||||
Expect(infuraConfig.Database.Name).To(Equal("vulcanize_private"))
|
||||
Expect(infuraConfig.Database.Port).To(Equal(5432))
|
||||
Expect(infuraConfig.Client.IPCPath).To(Equal("https://mainnet.infura.io/J5Vd2fRtGsw0zZ0Ov3BL"))
|
||||
Expect(testConfig.Get("database.hostname")).To(Equal("localhost"))
|
||||
Expect(testConfig.Get("database.name")).To(Equal("vulcanize_private"))
|
||||
Expect(testConfig.Get("database.port")).To(Equal(int64(5432)))
|
||||
Expect(testConfig.Get("client.ipcpath")).To(Equal("test_data_dir/geth.ipc"))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@@ -30,11 +30,10 @@ func template() string {
|
||||
func transactionToString(transaction *core.Transaction) string {
|
||||
if transaction == nil {
|
||||
return "NONE"
|
||||
} else {
|
||||
return fmt.Sprintf(`Hash: %s
|
||||
}
|
||||
return fmt.Sprintf(`Hash: %s
|
||||
To: %s
|
||||
From: %s`, transaction.Hash, transaction.To, transaction.From)
|
||||
}
|
||||
}
|
||||
|
||||
func attributesString(summary ContractSummary) string {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
)
|
||||
|
||||
type ContractSummary struct {
|
||||
@@ -17,13 +17,12 @@ type ContractSummary struct {
|
||||
blockChain core.Blockchain
|
||||
}
|
||||
|
||||
func NewSummary(blockchain core.Blockchain, contractRepository repositories.ContractRepository, contractHash string, blockNumber *big.Int) (ContractSummary, error) {
|
||||
func NewSummary(blockchain core.Blockchain, contractRepository datastore.ContractRepository, contractHash string, blockNumber *big.Int) (ContractSummary, error) {
|
||||
contract, err := contractRepository.GetContract(contractHash)
|
||||
if err != nil {
|
||||
return ContractSummary{}, err
|
||||
} else {
|
||||
return newContractSummary(blockchain, contract, blockNumber), nil
|
||||
}
|
||||
return newContractSummary(blockchain, contract, blockNumber), nil
|
||||
}
|
||||
|
||||
func (contractSummary ContractSummary) GetStateAttribute(attributeName string) interface{} {
|
||||
@@ -48,7 +47,6 @@ func newContractSummary(blockchain core.Blockchain, contract core.Contract, bloc
|
||||
func lastTransaction(contract core.Contract) *core.Transaction {
|
||||
if len(contract.Transactions) > 0 {
|
||||
return &contract.Transactions[0]
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/contract_summary"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/inmemory"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/inmemory"
|
||||
)
|
||||
|
||||
func NewCurrentContractSummary(blockchain core.Blockchain, contractRepository repositories.ContractRepository, contractHash string) (contract_summary.ContractSummary, error) {
|
||||
func NewCurrentContractSummary(blockchain core.Blockchain, contractRepository datastore.ContractRepository, contractHash string) (contract_summary.ContractSummary, error) {
|
||||
return contract_summary.NewSummary(blockchain, contractRepository, contractHash, nil)
|
||||
}
|
||||
|
||||
@@ -143,6 +143,7 @@ var _ = Describe("The contract summary", func() {
|
||||
},
|
||||
))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@@ -3,10 +3,14 @@ package core
|
||||
import "math/big"
|
||||
|
||||
type Blockchain interface {
|
||||
GetAttribute(contract Contract, attributeName string, blockNumber *big.Int) (interface{}, error)
|
||||
GetAttributes(contract Contract) (ContractAttributes, error)
|
||||
GetBlockByNumber(blockNumber int64) Block
|
||||
GetLogs(contract Contract, startingBlockNumber *big.Int, endingBlockNumber *big.Int) ([]Log, error)
|
||||
LastBlock() *big.Int
|
||||
Node() Node
|
||||
GetAttributes(contract Contract) (ContractAttributes, error)
|
||||
GetAttribute(contract Contract, attributeName string, blockNumber *big.Int) (interface{}, error)
|
||||
GetLogs(contract Contract, startingBlockNumber *big.Int, endingBlockNumber *big.Int) ([]Log, error)
|
||||
}
|
||||
|
||||
type ContractDataFetcher interface {
|
||||
FetchContractData(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) error
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package core
|
||||
|
||||
type Node struct {
|
||||
GenesisBlock string
|
||||
NetworkId float64
|
||||
Id string
|
||||
NetworkID float64
|
||||
ID string
|
||||
ClientName string
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package core
|
||||
|
||||
type WatchedEvent struct {
|
||||
Name string `json:"name"` // name
|
||||
BlockNumber int64 `json:"block_number" db:"block_number"` // block_number
|
||||
Address string `json:"address"` // address
|
||||
TxHash string `json:"tx_hash" db:"tx_hash"` // tx_hash
|
||||
Index int64 `json:"index"` // index
|
||||
Topic0 string `json:"topic0"` // topic0
|
||||
Topic1 string `json:"topic1"` // topic1
|
||||
Topic2 string `json:"topic2"` // topic2
|
||||
Topic3 string `json:"topic3"` // topic3
|
||||
Data string `json:"data"` // data
|
||||
LogID int64 `json:"log_id" db:"id"`
|
||||
Name string `json:"name"`
|
||||
BlockNumber int64 `json:"block_number" db:"block_number"`
|
||||
Address string `json:"address"`
|
||||
TxHash string `json:"tx_hash" db:"tx_hash"`
|
||||
Index int64 `json:"index"`
|
||||
Topic0 string `json:"topic0"`
|
||||
Topic1 string `json:"topic1"`
|
||||
Topic2 string `json:"topic2"`
|
||||
Topic3 string `json:"topic3"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ package inmemory
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
)
|
||||
|
||||
type BlockRepository struct {
|
||||
@@ -23,7 +23,7 @@ func (blockRepository *BlockRepository) GetBlock(blockNumber int64) (core.Block,
|
||||
if block, ok := blockRepository.blocks[blockNumber]; ok {
|
||||
return block, nil
|
||||
}
|
||||
return core.Block{}, repositories.ErrBlockDoesNotExist(blockNumber)
|
||||
return core.Block{}, datastore.ErrBlockDoesNotExist(blockNumber)
|
||||
}
|
||||
|
||||
func (blockRepository *BlockRepository) MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64) []int64 {
|
||||
+2
-2
@@ -2,7 +2,7 @@ package inmemory
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
)
|
||||
|
||||
type ContractRepostiory struct {
|
||||
@@ -17,7 +17,7 @@ func (contractRepository *ContractRepostiory) ContractExists(contractHash string
|
||||
func (contractRepository *ContractRepostiory) GetContract(contractHash string) (core.Contract, error) {
|
||||
contract, ok := contractRepository.contracts[contractHash]
|
||||
if !ok {
|
||||
return core.Contract{}, repositories.ErrContractDoesNotExist(contractHash)
|
||||
return core.Contract{}, datastore.ErrContractDoesNotExist(contractHash)
|
||||
}
|
||||
for _, block := range contractRepository.blocks {
|
||||
for _, transaction := range block.Transactions {
|
||||
@@ -4,15 +4,15 @@ import (
|
||||
"errors"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/lib/pq" //postgres driver
|
||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
type DB struct {
|
||||
*sqlx.DB
|
||||
node core.Node
|
||||
nodeId int64
|
||||
Node core.Node
|
||||
NodeID int64
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -28,7 +28,7 @@ func NewDB(databaseConfig config.Database, node core.Node) (*DB, error) {
|
||||
if err != nil {
|
||||
return &DB{}, ErrDBConnectionFailed
|
||||
}
|
||||
pg := DB{DB: db, node: node}
|
||||
pg := DB{DB: db, Node: node}
|
||||
err = pg.CreateNode(&node)
|
||||
if err != nil {
|
||||
return &DB{}, ErrUnableToSetNode
|
||||
@@ -48,10 +48,10 @@ func (db *DB) CreateNode(node *core.Node) error {
|
||||
node_id = $3,
|
||||
client_name = $4
|
||||
RETURNING id`,
|
||||
node.GenesisBlock, node.NetworkId, node.Id, node.ClientName).Scan(&nodeId)
|
||||
node.GenesisBlock, node.NetworkID, node.ID, node.ClientName).Scan(&nodeId)
|
||||
if err != nil {
|
||||
return ErrUnableToSetNode
|
||||
}
|
||||
db.nodeId = nodeId
|
||||
db.NodeID = nodeId
|
||||
return nil
|
||||
}
|
||||
+23
-35
@@ -15,7 +15,9 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -23,24 +25,14 @@ func init() {
|
||||
}
|
||||
|
||||
var _ = Describe("Postgres DB", func() {
|
||||
var db *postgres.DB
|
||||
var sqlxdb *sqlx.DB
|
||||
|
||||
It("connects to the database", func() {
|
||||
cfg, _ := config.NewConfig("private")
|
||||
pgConfig := config.DbConnectionString(cfg.Database)
|
||||
db, err := sqlx.Connect("postgres", pgConfig)
|
||||
var err error
|
||||
pgConfig := config.DbConnectionString(test_config.DBConfig)
|
||||
sqlxdb, err = sqlx.Connect("postgres", pgConfig)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(db).ShouldNot(BeNil())
|
||||
})
|
||||
|
||||
BeforeEach(func() {
|
||||
node := core.Node{
|
||||
GenesisBlock: "GENESIS",
|
||||
NetworkId: 1,
|
||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||
}
|
||||
db = postgres.NewTestDB(node)
|
||||
Expect(sqlxdb).ShouldNot(BeNil())
|
||||
})
|
||||
|
||||
It("serializes big.Int to db", func() {
|
||||
@@ -51,9 +43,9 @@ var _ = Describe("Postgres DB", func() {
|
||||
// sized int, so use string representation of big.Int
|
||||
// and cast on insert
|
||||
|
||||
cfg, _ := config.NewConfig("private")
|
||||
pgConfig := config.DbConnectionString(cfg.Database)
|
||||
db, err := sqlx.Connect("postgres", pgConfig)
|
||||
pgConnectString := config.DbConnectionString(test_config.DBConfig)
|
||||
db, err := sqlx.Connect("postgres", pgConnectString)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
bi := new(big.Int)
|
||||
bi.SetString("34940183920000000000", 10)
|
||||
@@ -87,10 +79,9 @@ var _ = Describe("Postgres DB", func() {
|
||||
Nonce: badNonce,
|
||||
Transactions: []core.Transaction{},
|
||||
}
|
||||
cfg, _ := config.NewConfig("private")
|
||||
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
||||
db, _ := postgres.NewDB(cfg.Database, node)
|
||||
blocksRepository := postgres.BlockRepository{DB: db}
|
||||
node := core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "geth"}
|
||||
db := test_config.NewTestDB(node)
|
||||
blocksRepository := repositories.BlockRepository{DB: db}
|
||||
|
||||
err1 := blocksRepository.CreateOrUpdateBlock(badBlock)
|
||||
savedBlock, err2 := blocksRepository.GetBlock(123)
|
||||
@@ -102,16 +93,15 @@ var _ = Describe("Postgres DB", func() {
|
||||
|
||||
It("throws error when can't connect to the database", func() {
|
||||
invalidDatabase := config.Database{}
|
||||
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
||||
node := core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "geth"}
|
||||
_, err := postgres.NewDB(invalidDatabase, node)
|
||||
Expect(err).To(Equal(postgres.ErrDBConnectionFailed))
|
||||
})
|
||||
|
||||
It("throws error when can't create node", func() {
|
||||
cfg, _ := config.NewConfig("private")
|
||||
badHash := fmt.Sprintf("x %s", strings.Repeat("1", 100))
|
||||
node := core.Node{GenesisBlock: badHash, NetworkId: 1, Id: "x123", ClientName: "geth"}
|
||||
_, err := postgres.NewDB(cfg.Database, node)
|
||||
node := core.Node{GenesisBlock: badHash, NetworkID: 1, ID: "x123", ClientName: "geth"}
|
||||
_, err := postgres.NewDB(test_config.DBConfig, node)
|
||||
Expect(err).To(Equal(postgres.ErrUnableToSetNode))
|
||||
})
|
||||
|
||||
@@ -123,10 +113,9 @@ var _ = Describe("Postgres DB", func() {
|
||||
BlockNumber: 1,
|
||||
TxHash: badTxHash,
|
||||
}
|
||||
cfg, _ := config.NewConfig("private")
|
||||
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
||||
db, _ := postgres.NewDB(cfg.Database, node)
|
||||
logRepository := postgres.LogRepository{DB: db}
|
||||
node := core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "geth"}
|
||||
db, _ := postgres.NewDB(test_config.DBConfig, node)
|
||||
logRepository := repositories.LogRepository{DB: db}
|
||||
|
||||
err := logRepository.CreateLogs([]core.Log{badLog})
|
||||
savedBlock := logRepository.GetLogs("x123", 1)
|
||||
@@ -143,10 +132,9 @@ var _ = Describe("Postgres DB", func() {
|
||||
Number: 123,
|
||||
Transactions: []core.Transaction{badTransaction},
|
||||
}
|
||||
cfg, _ := config.NewConfig("private")
|
||||
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
||||
db, _ := postgres.NewDB(cfg.Database, node)
|
||||
blockRepository := postgres.BlockRepository{DB: db}
|
||||
node := core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "geth"}
|
||||
db, _ := postgres.NewDB(test_config.DBConfig, node)
|
||||
blockRepository := repositories.BlockRepository{DB: db}
|
||||
|
||||
err1 := blockRepository.CreateOrUpdateBlock(block)
|
||||
savedBlock, err2 := blockRepository.GetBlock(123)
|
||||
+13
-14
@@ -1,15 +1,15 @@
|
||||
package postgres
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"log"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -17,7 +17,7 @@ const (
|
||||
)
|
||||
|
||||
type BlockRepository struct {
|
||||
*DB
|
||||
*postgres.DB
|
||||
}
|
||||
|
||||
func (blockRepository BlockRepository) SetBlocksStatus(chainHead int64) {
|
||||
@@ -79,12 +79,12 @@ func (blockRepository BlockRepository) GetBlock(blockNumber int64) (core.Block,
|
||||
reward,
|
||||
uncles_reward
|
||||
FROM blocks
|
||||
WHERE node_id = $1 AND number = $2`, blockRepository.nodeId, blockNumber)
|
||||
WHERE node_id = $1 AND number = $2`, blockRepository.NodeID, blockNumber)
|
||||
savedBlock, err := blockRepository.loadBlock(blockRows)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case sql.ErrNoRows:
|
||||
return core.Block{}, repositories.ErrBlockDoesNotExist(blockNumber)
|
||||
return core.Block{}, datastore.ErrBlockDoesNotExist(blockNumber)
|
||||
default:
|
||||
return savedBlock, err
|
||||
}
|
||||
@@ -100,16 +100,16 @@ func (blockRepository BlockRepository) insertBlock(block core.Block) error {
|
||||
(node_id, number, gaslimit, gasused, time, difficulty, hash, nonce, parenthash, size, uncle_hash, is_final, miner, extra_data, reward, uncles_reward)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||
RETURNING id `,
|
||||
blockRepository.nodeId, block.Number, block.GasLimit, block.GasUsed, block.Time, block.Difficulty, block.Hash, block.Nonce, block.ParentHash, block.Size, block.UncleHash, block.IsFinal, block.Miner, block.ExtraData, block.Reward, block.UnclesReward).
|
||||
blockRepository.NodeID, block.Number, block.GasLimit, block.GasUsed, block.Time, block.Difficulty, block.Hash, block.Nonce, block.ParentHash, block.Size, block.UncleHash, block.IsFinal, block.Miner, block.ExtraData, block.Reward, block.UnclesReward).
|
||||
Scan(&blockId)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return ErrDBInsertFailed
|
||||
return postgres.ErrDBInsertFailed
|
||||
}
|
||||
err = blockRepository.createTransactions(tx, blockId, block.Transactions)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return ErrDBInsertFailed
|
||||
return postgres.ErrDBInsertFailed
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
@@ -191,7 +191,7 @@ func (blockRepository BlockRepository) getBlockHash(block core.Block) (string, b
|
||||
`SELECT hash
|
||||
FROM blocks
|
||||
WHERE number = $1 AND node_id = $2`,
|
||||
block.Number, blockRepository.nodeId)
|
||||
block.Number, blockRepository.NodeID)
|
||||
return retrievedBlockHash, blockExists(retrievedBlockHash)
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ func (blockRepository BlockRepository) createLogs(tx *sql.Tx, logs []core.Log, r
|
||||
tlog.BlockNumber, tlog.Address, tlog.TxHash, tlog.Index, tlog.Topics[0], tlog.Topics[1], tlog.Topics[2], tlog.Topics[3], tlog.Data, receiptId,
|
||||
)
|
||||
if err != nil {
|
||||
return ErrDBInsertFailed
|
||||
return postgres.ErrDBInsertFailed
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -219,9 +219,9 @@ func (blockRepository BlockRepository) removeBlock(blockNumber int64) error {
|
||||
`DELETE FROM
|
||||
blocks
|
||||
WHERE number=$1 AND node_id=$2`,
|
||||
blockNumber, blockRepository.nodeId)
|
||||
blockNumber, blockRepository.NodeID)
|
||||
if err != nil {
|
||||
return ErrDBDeleteFailed
|
||||
return postgres.ErrDBDeleteFailed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -261,7 +261,6 @@ func (blockRepository BlockRepository) LoadTransactions(transactionRows *sqlx.Ro
|
||||
var transaction core.Transaction
|
||||
err := transactionRows.StructScan(&transaction)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
transactions = append(transactions, transaction)
|
||||
+17
-16
@@ -1,4 +1,4 @@
|
||||
package postgres_test
|
||||
package repositories_test
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
@@ -7,22 +7,24 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
|
||||
var _ = Describe("Saving blocks", func() {
|
||||
var db *postgres.DB
|
||||
var blockRepository repositories.BlockRepository
|
||||
var blockRepository datastore.BlockRepository
|
||||
BeforeEach(func() {
|
||||
node := core.Node{
|
||||
GenesisBlock: "GENESIS",
|
||||
NetworkId: 1,
|
||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
NetworkID: 1,
|
||||
ID: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||
}
|
||||
db = postgres.NewTestDB(node)
|
||||
blockRepository = postgres.BlockRepository{DB: db}
|
||||
db = test_config.NewTestDB(node)
|
||||
blockRepository = repositories.BlockRepository{DB: db}
|
||||
|
||||
})
|
||||
|
||||
@@ -33,12 +35,12 @@ var _ = Describe("Saving blocks", func() {
|
||||
blockRepository.CreateOrUpdateBlock(block)
|
||||
nodeTwo := core.Node{
|
||||
GenesisBlock: "0x456",
|
||||
NetworkId: 1,
|
||||
Id: "x123456",
|
||||
NetworkID: 1,
|
||||
ID: "x123456",
|
||||
ClientName: "Geth",
|
||||
}
|
||||
dbTwo := postgres.NewTestDB(nodeTwo)
|
||||
repositoryTwo := postgres.BlockRepository{DB: dbTwo}
|
||||
dbTwo := test_config.NewTestDB(nodeTwo)
|
||||
repositoryTwo := repositories.BlockRepository{DB: dbTwo}
|
||||
|
||||
_, err := repositoryTwo.GetBlock(123)
|
||||
Expect(err).To(HaveOccurred())
|
||||
@@ -161,10 +163,10 @@ var _ = Describe("Saving blocks", func() {
|
||||
blockRepository.CreateOrUpdateBlock(blockOne)
|
||||
nodeTwo := core.Node{
|
||||
GenesisBlock: "0x456",
|
||||
NetworkId: 1,
|
||||
NetworkID: 1,
|
||||
}
|
||||
dbTwo := postgres.NewTestDB(nodeTwo)
|
||||
repositoryTwo := postgres.BlockRepository{DB: dbTwo}
|
||||
dbTwo := test_config.NewTestDB(nodeTwo)
|
||||
repositoryTwo := repositories.BlockRepository{DB: dbTwo}
|
||||
|
||||
blockRepository.CreateOrUpdateBlock(blockOne)
|
||||
repositoryTwo.CreateOrUpdateBlock(blockTwo)
|
||||
@@ -283,6 +285,5 @@ var _ = Describe("Saving blocks", func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(blockTwo.IsFinal).To(BeFalse())
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
+6
-5
@@ -1,14 +1,15 @@
|
||||
package postgres
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type ContractRepository struct {
|
||||
*DB
|
||||
*postgres.DB
|
||||
}
|
||||
|
||||
func (contractRepository ContractRepository) CreateContract(contract core.Contract) error {
|
||||
@@ -25,7 +26,7 @@ func (contractRepository ContractRepository) CreateContract(contract core.Contra
|
||||
SET contract_hash = $1, contract_abi = $2
|
||||
`, contract.Hash, abiToInsert)
|
||||
if err != nil {
|
||||
return ErrDBInsertFailed
|
||||
return postgres.ErrDBInsertFailed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -47,7 +48,7 @@ func (contractRepository ContractRepository) GetContract(contractHash string) (c
|
||||
`SELECT contract_hash, contract_abi FROM watched_contracts WHERE contract_hash=$1`, contractHash)
|
||||
err := contract.Scan(&hash, &abi)
|
||||
if err == sql.ErrNoRows {
|
||||
return core.Contract{}, repositories.ErrContractDoesNotExist(contractHash)
|
||||
return core.Contract{}, datastore.ErrContractDoesNotExist(contractHash)
|
||||
}
|
||||
savedContract := contractRepository.addTransactions(core.Contract{Hash: hash, Abi: abi})
|
||||
return savedContract, nil
|
||||
+12
-10
@@ -1,4 +1,4 @@
|
||||
package postgres_test
|
||||
package repositories_test
|
||||
|
||||
import (
|
||||
"sort"
|
||||
@@ -6,24 +6,26 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
|
||||
var _ = Describe("Creating contracts", func() {
|
||||
var db *postgres.DB
|
||||
var contractRepository repositories.ContractRepository
|
||||
var contractRepository datastore.ContractRepository
|
||||
var node core.Node
|
||||
|
||||
BeforeEach(func() {
|
||||
node = core.Node{
|
||||
GenesisBlock: "GENESIS",
|
||||
NetworkId: 1,
|
||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
NetworkID: 1,
|
||||
ID: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||
}
|
||||
db = postgres.NewTestDB(node)
|
||||
contractRepository = postgres.ContractRepository{DB: db}
|
||||
db = test_config.NewTestDB(node)
|
||||
contractRepository = repositories.ContractRepository{DB: db}
|
||||
})
|
||||
|
||||
It("returns the contract when it exists", func() {
|
||||
@@ -50,8 +52,8 @@ var _ = Describe("Creating contracts", func() {
|
||||
})
|
||||
|
||||
It("returns transactions 'To' a contract", func() {
|
||||
var blockRepository repositories.BlockRepository
|
||||
blockRepository = postgres.BlockRepository{DB: db}
|
||||
var blockRepository datastore.BlockRepository
|
||||
blockRepository = repositories.BlockRepository{DB: db}
|
||||
block := core.Block{
|
||||
Number: 123,
|
||||
Transactions: []core.Transaction{
|
||||
+6
-7
@@ -1,4 +1,4 @@
|
||||
package postgres
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
@@ -6,12 +6,13 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
)
|
||||
|
||||
type FilterRepository struct {
|
||||
*DB
|
||||
*postgres.DB
|
||||
}
|
||||
|
||||
func (filterRepository FilterRepository) CreateFilter(query filters.LogFilter) error {
|
||||
@@ -41,7 +42,7 @@ func (filterRepository FilterRepository) GetFilter(name string) (filters.LogFilt
|
||||
if err != nil {
|
||||
switch err {
|
||||
case sql.ErrNoRows:
|
||||
return filters.LogFilter{}, repositories.ErrFilterDoesNotExist(name)
|
||||
return filters.LogFilter{}, datastore.ErrFilterDoesNotExist(name)
|
||||
default:
|
||||
return filters.LogFilter{}, err
|
||||
}
|
||||
@@ -57,9 +58,7 @@ func (t *DBTopics) Scan(src interface{}) error {
|
||||
if !ok {
|
||||
return error(errors.New("scan source was not []byte"))
|
||||
}
|
||||
json.Unmarshal(asBytes, &t)
|
||||
|
||||
return nil
|
||||
return json.Unmarshal(asBytes, &t)
|
||||
}
|
||||
|
||||
type DBLogFilter struct {
|
||||
+19
-17
@@ -1,27 +1,29 @@
|
||||
package postgres_test
|
||||
package repositories_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
|
||||
var _ = Describe("Log Filters Repository", func() {
|
||||
var db *postgres.DB
|
||||
var filterRepository repositories.FilterRepository
|
||||
var filterRepository datastore.FilterRepository
|
||||
var node core.Node
|
||||
BeforeEach(func() {
|
||||
node = core.Node{
|
||||
GenesisBlock: "GENESIS",
|
||||
NetworkId: 1,
|
||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
NetworkID: 1,
|
||||
ID: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||
}
|
||||
db = postgres.NewTestDB(node)
|
||||
filterRepository = postgres.FilterRepository{DB: db}
|
||||
db = test_config.NewTestDB(node)
|
||||
filterRepository = repositories.FilterRepository{DB: db}
|
||||
})
|
||||
|
||||
Describe("LogFilter", func() {
|
||||
@@ -63,7 +65,7 @@ var _ = Describe("Log Filters Repository", func() {
|
||||
|
||||
It("gets a log filter", func() {
|
||||
|
||||
logFilter1 := filters.LogFilter{
|
||||
expectedLogFilter1 := filters.LogFilter{
|
||||
Name: "TestFilter1",
|
||||
FromBlock: 1,
|
||||
ToBlock: 2,
|
||||
@@ -75,9 +77,9 @@ var _ = Describe("Log Filters Repository", func() {
|
||||
"",
|
||||
},
|
||||
}
|
||||
err := filterRepository.CreateFilter(logFilter1)
|
||||
err := filterRepository.CreateFilter(expectedLogFilter1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
logFilter2 := filters.LogFilter{
|
||||
expectedLogFilter2 := filters.LogFilter{
|
||||
Name: "TestFilter2",
|
||||
FromBlock: 10,
|
||||
ToBlock: 20,
|
||||
@@ -89,20 +91,20 @@ var _ = Describe("Log Filters Repository", func() {
|
||||
"",
|
||||
},
|
||||
}
|
||||
err = filterRepository.CreateFilter(logFilter2)
|
||||
err = filterRepository.CreateFilter(expectedLogFilter2)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
logFilter1, err = filterRepository.GetFilter("TestFilter1")
|
||||
logFilter1, err := filterRepository.GetFilter("TestFilter1")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(logFilter1).To(Equal(logFilter1))
|
||||
logFilter1, err = filterRepository.GetFilter("TestFilter1")
|
||||
Expect(logFilter1).To(Equal(expectedLogFilter1))
|
||||
logFilter2, err := filterRepository.GetFilter("TestFilter2")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(logFilter2).To(Equal(logFilter2))
|
||||
Expect(logFilter2).To(Equal(expectedLogFilter2))
|
||||
})
|
||||
|
||||
It("returns ErrFilterDoesNotExist error when log does not exist", func() {
|
||||
_, err := filterRepository.GetFilter("TestFilter1")
|
||||
Expect(err).To(Equal(repositories.ErrFilterDoesNotExist("TestFilter1")))
|
||||
Expect(err).To(Equal(datastore.ErrFilterDoesNotExist("TestFilter1")))
|
||||
})
|
||||
})
|
||||
})
|
||||
+4
-3
@@ -1,4 +1,4 @@
|
||||
package postgres
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,10 +6,11 @@ import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type LogRepository struct {
|
||||
*DB
|
||||
*postgres.DB
|
||||
}
|
||||
|
||||
func (logRepository LogRepository) CreateLogs(lgs []core.Log) error {
|
||||
@@ -23,7 +24,7 @@ func (logRepository LogRepository) CreateLogs(lgs []core.Log) error {
|
||||
)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return ErrDBInsertFailed
|
||||
return postgres.ErrDBInsertFailed
|
||||
}
|
||||
}
|
||||
tx.Commit()
|
||||
+12
-11
@@ -1,4 +1,4 @@
|
||||
package postgres_test
|
||||
package repositories_test
|
||||
|
||||
import (
|
||||
"sort"
|
||||
@@ -6,23 +6,25 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
|
||||
var _ = Describe("Logs Repository", func() {
|
||||
var db *postgres.DB
|
||||
var logsRepository repositories.LogRepository
|
||||
var logsRepository datastore.LogRepository
|
||||
var node core.Node
|
||||
BeforeEach(func() {
|
||||
node = core.Node{
|
||||
GenesisBlock: "GENESIS",
|
||||
NetworkId: 1,
|
||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
NetworkID: 1,
|
||||
ID: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||
}
|
||||
db = postgres.NewTestDB(node)
|
||||
logsRepository = postgres.LogRepository{DB: db}
|
||||
db = test_config.NewTestDB(node)
|
||||
logsRepository = repositories.LogRepository{DB: db}
|
||||
})
|
||||
|
||||
Describe("Saving logs", func() {
|
||||
@@ -115,8 +117,8 @@ var _ = Describe("Logs Repository", func() {
|
||||
})
|
||||
|
||||
It("saves the logs attached to a receipt", func() {
|
||||
var blockRepository repositories.BlockRepository
|
||||
blockRepository = postgres.BlockRepository{DB: db}
|
||||
var blockRepository datastore.BlockRepository
|
||||
blockRepository = repositories.BlockRepository{DB: db}
|
||||
|
||||
logs := []core.Log{{
|
||||
Address: "0x8a4774fe82c63484afef97ca8d89a6ea5e21f973",
|
||||
@@ -176,6 +178,5 @@ var _ = Describe("Logs Repository", func() {
|
||||
expected := logs[1:]
|
||||
Expect(retrievedLogs).To(Equal(expected))
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
+5
-4
@@ -1,14 +1,15 @@
|
||||
package postgres
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type ReceiptRepository struct {
|
||||
*DB
|
||||
*postgres.DB
|
||||
}
|
||||
|
||||
func (receiptRepository ReceiptRepository) GetReceipt(txHash string) (core.Receipt, error) {
|
||||
@@ -25,7 +26,7 @@ func (receiptRepository ReceiptRepository) GetReceipt(txHash string) (core.Recei
|
||||
if err != nil {
|
||||
switch err {
|
||||
case sql.ErrNoRows:
|
||||
return core.Receipt{}, repositories.ErrReceiptDoesNotExist(txHash)
|
||||
return core.Receipt{}, datastore.ErrReceiptDoesNotExist(txHash)
|
||||
default:
|
||||
return core.Receipt{}, err
|
||||
}
|
||||
+16
-14
@@ -1,33 +1,35 @@
|
||||
package postgres_test
|
||||
package repositories_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
|
||||
var _ bool = Describe("Logs Repository", func() {
|
||||
var receiptRepository repositories.ReceiptRepository
|
||||
var receiptRepository datastore.ReceiptRepository
|
||||
var db *postgres.DB
|
||||
var node core.Node
|
||||
BeforeEach(func() {
|
||||
node = core.Node{
|
||||
GenesisBlock: "GENESIS",
|
||||
NetworkId: 1,
|
||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
NetworkID: 1,
|
||||
ID: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||
}
|
||||
db = postgres.NewTestDB(node)
|
||||
receiptRepository = postgres.ReceiptRepository{DB: db}
|
||||
db = test_config.NewTestDB(node)
|
||||
receiptRepository = repositories.ReceiptRepository{DB: db}
|
||||
})
|
||||
|
||||
Describe("Saving receipts", func() {
|
||||
It("returns the receipt when it exists", func() {
|
||||
var blockRepository repositories.BlockRepository
|
||||
db := postgres.NewTestDB(node)
|
||||
blockRepository = postgres.BlockRepository{DB: db}
|
||||
var blockRepository datastore.BlockRepository
|
||||
db := test_config.NewTestDB(node)
|
||||
blockRepository = repositories.BlockRepository{DB: db}
|
||||
expected := core.Receipt{
|
||||
ContractAddress: "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
|
||||
CumulativeGasUsed: 7996119,
|
||||
@@ -64,9 +66,9 @@ var _ bool = Describe("Logs Repository", func() {
|
||||
})
|
||||
|
||||
It("still saves receipts without logs", func() {
|
||||
var blockRepository repositories.BlockRepository
|
||||
db := postgres.NewTestDB(node)
|
||||
blockRepository = postgres.BlockRepository{DB: db}
|
||||
var blockRepository datastore.BlockRepository
|
||||
db := test_config.NewTestDB(node)
|
||||
blockRepository = repositories.BlockRepository{DB: db}
|
||||
receipt := core.Receipt{
|
||||
TxHash: "0x002c4799161d809b23f67884eb6598c9df5894929fe1a9ead97ca175d360f547",
|
||||
}
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
package graphql_server_test
|
||||
package repositories_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestGraphqlServer(t *testing.T) {
|
||||
func TestRepositories(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "GraphqlServer Suite")
|
||||
RunSpecs(t, "Repositories Suite")
|
||||
}
|
||||
+5
-4
@@ -1,15 +1,16 @@
|
||||
package postgres
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
)
|
||||
|
||||
type WatchedEventRepository struct {
|
||||
*DB
|
||||
*postgres.DB
|
||||
}
|
||||
|
||||
func (watchedEventRepository WatchedEventRepository) GetWatchedEvents(name string) ([]*core.WatchedEvent, error) {
|
||||
rows, err := watchedEventRepository.DB.Queryx(`SELECT name, block_number, address, tx_hash, index, topic0, topic1, topic2, topic3, data FROM watched_event_logs where name=$1`, name)
|
||||
rows, err := watchedEventRepository.DB.Queryx(`SELECT id, name, block_number, address, tx_hash, index, topic0, topic1, topic2, topic3, data FROM watched_event_logs where name=$1`, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -18,7 +19,7 @@ func (watchedEventRepository WatchedEventRepository) GetWatchedEvents(name strin
|
||||
lgs := make([]*core.WatchedEvent, 0)
|
||||
for rows.Next() {
|
||||
lg := new(core.WatchedEvent)
|
||||
err := rows.StructScan(lg)
|
||||
err = rows.StructScan(lg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
+30
-12
@@ -1,24 +1,27 @@
|
||||
package postgres_test
|
||||
package repositories_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
|
||||
var _ = Describe("Watched Events Repository", func() {
|
||||
var db *postgres.DB
|
||||
var logRepository postgres.LogRepository
|
||||
var filterRepository postgres.FilterRepository
|
||||
var watchedEventRepository postgres.WatchedEventRepository
|
||||
var logRepository datastore.LogRepository
|
||||
var filterRepository datastore.FilterRepository
|
||||
var watchedEventRepository datastore.WatchedEventRepository
|
||||
|
||||
BeforeEach(func() {
|
||||
db = postgres.NewTestDB(core.Node{})
|
||||
logRepository = postgres.LogRepository{DB: db}
|
||||
filterRepository = postgres.FilterRepository{DB: db}
|
||||
watchedEventRepository = postgres.WatchedEventRepository{DB: db}
|
||||
db = test_config.NewTestDB(core.Node{})
|
||||
logRepository = repositories.LogRepository{DB: db}
|
||||
filterRepository = repositories.FilterRepository{DB: db}
|
||||
watchedEventRepository = repositories.WatchedEventRepository{DB: db}
|
||||
})
|
||||
|
||||
It("retrieves watched event logs that match the event filter", func() {
|
||||
@@ -57,7 +60,15 @@ var _ = Describe("Watched Events Repository", func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
matchingLogs, err := watchedEventRepository.GetWatchedEvents("Filter1")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(matchingLogs).To(Equal(expectedWatchedEventLog))
|
||||
Expect(len(matchingLogs)).To(Equal(1))
|
||||
Expect(matchingLogs[0].Name).To(Equal(expectedWatchedEventLog[0].Name))
|
||||
Expect(matchingLogs[0].BlockNumber).To(Equal(expectedWatchedEventLog[0].BlockNumber))
|
||||
Expect(matchingLogs[0].TxHash).To(Equal(expectedWatchedEventLog[0].TxHash))
|
||||
Expect(matchingLogs[0].Address).To(Equal(expectedWatchedEventLog[0].Address))
|
||||
Expect(matchingLogs[0].Topic0).To(Equal(expectedWatchedEventLog[0].Topic0))
|
||||
Expect(matchingLogs[0].Topic1).To(Equal(expectedWatchedEventLog[0].Topic1))
|
||||
Expect(matchingLogs[0].Topic2).To(Equal(expectedWatchedEventLog[0].Topic2))
|
||||
Expect(matchingLogs[0].Data).To(Equal(expectedWatchedEventLog[0].Data))
|
||||
|
||||
})
|
||||
|
||||
@@ -103,7 +114,14 @@ var _ = Describe("Watched Events Repository", func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
matchingLogs, err := watchedEventRepository.GetWatchedEvents("Filter1")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(matchingLogs).To(Equal(expectedWatchedEventLog))
|
||||
|
||||
Expect(len(matchingLogs)).To(Equal(1))
|
||||
Expect(matchingLogs[0].Name).To(Equal(expectedWatchedEventLog[0].Name))
|
||||
Expect(matchingLogs[0].BlockNumber).To(Equal(expectedWatchedEventLog[0].BlockNumber))
|
||||
Expect(matchingLogs[0].TxHash).To(Equal(expectedWatchedEventLog[0].TxHash))
|
||||
Expect(matchingLogs[0].Address).To(Equal(expectedWatchedEventLog[0].Address))
|
||||
Expect(matchingLogs[0].Topic0).To(Equal(expectedWatchedEventLog[0].Topic0))
|
||||
Expect(matchingLogs[0].Topic1).To(Equal(expectedWatchedEventLog[0].Topic1))
|
||||
Expect(matchingLogs[0].Topic2).To(Equal(expectedWatchedEventLog[0].Topic2))
|
||||
Expect(matchingLogs[0].Data).To(Equal(expectedWatchedEventLog[0].Data))
|
||||
})
|
||||
})
|
||||
@@ -1,7 +1,6 @@
|
||||
package repositories
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
@@ -9,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
var ErrBlockDoesNotExist = func(blockNumber int64) error {
|
||||
return errors.New(fmt.Sprintf("Block number %d does not exist", blockNumber))
|
||||
return fmt.Errorf("Block number %d does not exist", blockNumber)
|
||||
}
|
||||
|
||||
type BlockRepository interface {
|
||||
@@ -20,7 +19,7 @@ type BlockRepository interface {
|
||||
}
|
||||
|
||||
var ErrContractDoesNotExist = func(contractHash string) error {
|
||||
return errors.New(fmt.Sprintf("Contract %v does not exist", contractHash))
|
||||
return fmt.Errorf("Contract %v does not exist", contractHash)
|
||||
}
|
||||
|
||||
type ContractRepository interface {
|
||||
@@ -30,7 +29,7 @@ type ContractRepository interface {
|
||||
}
|
||||
|
||||
var ErrFilterDoesNotExist = func(name string) error {
|
||||
return errors.New(fmt.Sprintf("filter %s does not exist", name))
|
||||
return fmt.Errorf("filter %s does not exist", name)
|
||||
}
|
||||
|
||||
type FilterRepository interface {
|
||||
@@ -44,7 +43,7 @@ type LogRepository interface {
|
||||
}
|
||||
|
||||
var ErrReceiptDoesNotExist = func(txHash string) error {
|
||||
return errors.New(fmt.Sprintf("Receipt for tx: %v does not exist", txHash))
|
||||
return fmt.Errorf("Receipt for tx: %v does not exist", txHash)
|
||||
}
|
||||
|
||||
type ReceiptRepository interface {
|
||||
+13
-8
@@ -9,12 +9,17 @@ import (
|
||||
)
|
||||
|
||||
type Blockchain struct {
|
||||
logs map[string][]core.Log
|
||||
blocks map[int64]core.Block
|
||||
contractAttributes map[string]map[string]string
|
||||
blocksChannel chan core.Block
|
||||
WasToldToStop bool
|
||||
node core.Node
|
||||
logs map[string][]core.Log
|
||||
blocks map[int64]core.Block
|
||||
contractAttributes map[string]map[string]string
|
||||
blocksChannel chan core.Block
|
||||
WasToldToStop bool
|
||||
node core.Node
|
||||
ContractReturnValue []byte
|
||||
}
|
||||
|
||||
func (blockchain *Blockchain) CallContract(contractHash string, input []byte, blockNumber *big.Int) ([]byte, error) {
|
||||
return blockchain.ContractReturnValue, nil
|
||||
}
|
||||
|
||||
func (blockchain *Blockchain) LastBlock() *big.Int {
|
||||
@@ -50,7 +55,7 @@ func NewBlockchain() *Blockchain {
|
||||
blocks: make(map[int64]core.Block),
|
||||
logs: make(map[string][]core.Log),
|
||||
contractAttributes: make(map[string]map[string]string),
|
||||
node: core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "Geth"},
|
||||
node: core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "Geth"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +96,7 @@ func (blockchain *Blockchain) GetAttributes(contract core.Contract) (core.Contra
|
||||
var contractAttributes core.ContractAttributes
|
||||
attributes, ok := blockchain.contractAttributes[contract.Hash+"-1"]
|
||||
if ok {
|
||||
for key, _ := range attributes {
|
||||
for key := range attributes {
|
||||
contractAttributes = append(contractAttributes, core.ContractAttribute{Name: key, Type: "string"})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func (filterQuery *LogFilter) UnmarshalJSON(input []byte) error {
|
||||
}{
|
||||
Alias: (*Alias)(filterQuery),
|
||||
}
|
||||
if err := json.Unmarshal(input, &aux); err != nil {
|
||||
if err = json.Unmarshal(input, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
if filterQuery.Name == "" {
|
||||
|
||||
+7
-8
@@ -25,20 +25,19 @@ type Response struct {
|
||||
Result string
|
||||
}
|
||||
|
||||
type EtherScanApi struct {
|
||||
type EtherScanAPI struct {
|
||||
client *http.Client
|
||||
url string
|
||||
}
|
||||
|
||||
func NewEtherScanClient(url string) *EtherScanApi {
|
||||
return &EtherScanApi{
|
||||
func NewEtherScanClient(url string) *EtherScanAPI {
|
||||
return &EtherScanAPI{
|
||||
client: &http.Client{Timeout: 10 * time.Second},
|
||||
url: url,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func GenUrl(network string) string {
|
||||
func GenURL(network string) string {
|
||||
switch network {
|
||||
case "ropsten":
|
||||
return "https://ropsten.etherscan.io"
|
||||
@@ -52,7 +51,7 @@ func GenUrl(network string) string {
|
||||
}
|
||||
|
||||
//https://api.etherscan.io/api?module=contract&action=getabi&address=%s
|
||||
func (e *EtherScanApi) GetAbi(contractHash string) (string, error) {
|
||||
func (e *EtherScanAPI) GetAbi(contractHash string) (string, error) {
|
||||
target := new(Response)
|
||||
request := fmt.Sprintf("%s/api?module=contract&action=getabi&address=%s", e.url, contractHash)
|
||||
r, err := e.client.Get(request)
|
||||
@@ -60,8 +59,8 @@ func (e *EtherScanApi) GetAbi(contractHash string) (string, error) {
|
||||
return "", ErrApiRequestFailed
|
||||
}
|
||||
defer r.Body.Close()
|
||||
json.NewDecoder(r.Body).Decode(&target)
|
||||
return target.Result, nil
|
||||
err = json.NewDecoder(r.Body).Decode(&target)
|
||||
return target.Result, err
|
||||
}
|
||||
|
||||
func ParseAbiFile(abiFilePath string) (abi.ABI, error) {
|
||||
|
||||
+16
-19
@@ -1,20 +1,16 @@
|
||||
package geth_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"net/http"
|
||||
|
||||
"fmt"
|
||||
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/ghttp"
|
||||
cfg "github.com/vulcanize/vulcanizedb/pkg/config"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
|
||||
var _ = Describe("ABI files", func() {
|
||||
@@ -22,7 +18,7 @@ var _ = Describe("ABI files", func() {
|
||||
Describe("Reading ABI files", func() {
|
||||
|
||||
It("loads a valid ABI file", func() {
|
||||
path := filepath.Join(cfg.ProjectRoot(), "pkg", "geth", "testing", "valid_abi.json")
|
||||
path := test_config.ABIFilePath + "valid_abi.json"
|
||||
|
||||
contractAbi, err := geth.ParseAbiFile(path)
|
||||
|
||||
@@ -31,7 +27,7 @@ var _ = Describe("ABI files", func() {
|
||||
})
|
||||
|
||||
It("reads the contents of a valid ABI file", func() {
|
||||
path := filepath.Join(cfg.ProjectRoot(), "pkg", "geth", "testing", "valid_abi.json")
|
||||
path := test_config.ABIFilePath + "valid_abi.json"
|
||||
|
||||
contractAbi, err := geth.ReadAbiFile(path)
|
||||
|
||||
@@ -40,7 +36,7 @@ var _ = Describe("ABI files", func() {
|
||||
})
|
||||
|
||||
It("returns an error when the file does not exist", func() {
|
||||
path := filepath.Join(cfg.ProjectRoot(), "pkg", "geth", "testing", "missing_abi.json")
|
||||
path := test_config.ABIFilePath + "missing_abi.json"
|
||||
|
||||
contractAbi, err := geth.ParseAbiFile(path)
|
||||
|
||||
@@ -49,7 +45,7 @@ var _ = Describe("ABI files", func() {
|
||||
})
|
||||
|
||||
It("returns an error when the file has invalid contents", func() {
|
||||
path := filepath.Join(cfg.ProjectRoot(), "pkg", "geth", "testing", "invalid_abi.json")
|
||||
path := test_config.ABIFilePath + "invalid_abi.json"
|
||||
|
||||
contractAbi, err := geth.ParseAbiFile(path)
|
||||
|
||||
@@ -61,19 +57,20 @@ var _ = Describe("ABI files", func() {
|
||||
|
||||
var (
|
||||
server *ghttp.Server
|
||||
client *geth.EtherScanApi
|
||||
client *geth.EtherScanAPI
|
||||
abiString string
|
||||
err error
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
server = ghttp.NewServer()
|
||||
client = geth.NewEtherScanClient(server.URL())
|
||||
path := filepath.Join(cfg.ProjectRoot(), "pkg", "geth", "testing", "sample_abi.json")
|
||||
abiString, err := geth.ReadAbiFile(path)
|
||||
path := test_config.ABIFilePath + "sample_abi.json"
|
||||
abiString, err = geth.ReadAbiFile(path)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
_, err = geth.ParseAbi(abiString)
|
||||
if err != nil {
|
||||
log.Fatalln("Could not parse ABI")
|
||||
}
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
@@ -104,14 +101,14 @@ var _ = Describe("ABI files", func() {
|
||||
|
||||
Describe("Generating etherscan endpoints based on network", func() {
|
||||
It("should return the main endpoint as the default", func() {
|
||||
url := geth.GenUrl("")
|
||||
url := geth.GenURL("")
|
||||
Expect(url).To(Equal("https://api.etherscan.io"))
|
||||
})
|
||||
|
||||
It("generates various test network endpoint if test network is supplied", func() {
|
||||
ropstenUrl := geth.GenUrl("ropsten")
|
||||
rinkebyUrl := geth.GenUrl("rinkeby")
|
||||
kovanUrl := geth.GenUrl("kovan")
|
||||
ropstenUrl := geth.GenURL("ropsten")
|
||||
rinkebyUrl := geth.GenURL("rinkeby")
|
||||
kovanUrl := geth.GenURL("kovan")
|
||||
|
||||
Expect(ropstenUrl).To(Equal("https://ropsten.etherscan.io"))
|
||||
Expect(kovanUrl).To(Equal("https://kovan.etherscan.io"))
|
||||
|
||||
@@ -12,12 +12,12 @@ import (
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type GethClient interface {
|
||||
type Client interface {
|
||||
TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error)
|
||||
TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
|
||||
}
|
||||
|
||||
func ToCoreBlock(gethBlock *types.Block, client GethClient) core.Block {
|
||||
func ToCoreBlock(gethBlock *types.Block, client Client) core.Block {
|
||||
transactions := convertTransactionsToCore(gethBlock, client)
|
||||
coreBlock := core.Block{
|
||||
Difficulty: gethBlock.Difficulty().Int64(),
|
||||
@@ -39,7 +39,7 @@ func ToCoreBlock(gethBlock *types.Block, client GethClient) core.Block {
|
||||
return coreBlock
|
||||
}
|
||||
|
||||
func convertTransactionsToCore(gethBlock *types.Block, client GethClient) []core.Transaction {
|
||||
func convertTransactionsToCore(gethBlock *types.Block, client Client) []core.Transaction {
|
||||
transactions := make([]core.Transaction, 0)
|
||||
for i, gethTransaction := range gethBlock.Transactions() {
|
||||
from, err := client.TransactionSender(context.Background(), gethTransaction, gethBlock.Hash(), uint(i))
|
||||
@@ -56,7 +56,7 @@ func convertTransactionsToCore(gethBlock *types.Block, client GethClient) []core
|
||||
return transactions
|
||||
}
|
||||
|
||||
func appendReceiptToTransaction(client GethClient, transaction core.Transaction) (core.Transaction, error) {
|
||||
func appendReceiptToTransaction(client Client, transaction core.Transaction) (core.Transaction, error) {
|
||||
gethReceipt, err := client.TransactionReceipt(context.Background(), common.HexToHash(transaction.Hash))
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
@@ -84,7 +84,6 @@ func transToCoreTrans(transaction *types.Transaction, from *common.Address) core
|
||||
func addressToHex(to *common.Address) string {
|
||||
if to == nil {
|
||||
return ""
|
||||
} else {
|
||||
return to.Hex()
|
||||
}
|
||||
return to.Hex()
|
||||
}
|
||||
|
||||
@@ -29,12 +29,13 @@ func NewBlockchain(ipcPath string) *Blockchain {
|
||||
blockchain := Blockchain{}
|
||||
rpcClient, err := rpc.Dial(ipcPath)
|
||||
if err != nil {
|
||||
log.Println("Unable to connect to node")
|
||||
log.Fatal(err)
|
||||
}
|
||||
client := ethclient.NewClient(rpcClient)
|
||||
blockchain.node = node.Info(rpcClient)
|
||||
if infura := isInfuraNode(ipcPath); infura {
|
||||
blockchain.node.Id = "infura"
|
||||
blockchain.node.ID = "infura"
|
||||
blockchain.node.ClientName = "infura"
|
||||
}
|
||||
blockchain.client = client
|
||||
|
||||
+18
-2
@@ -27,7 +27,7 @@ func (blockchain *Blockchain) GetAttribute(contract core.Contract, attributeName
|
||||
if err != nil {
|
||||
return nil, ErrInvalidStateAttribute
|
||||
}
|
||||
output, err := callContract(contract.Hash, input, blockchain, blockNumber)
|
||||
output, err := blockchain.callContract(contract.Hash, input, blockNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -38,7 +38,23 @@ func (blockchain *Blockchain) GetAttribute(contract core.Contract, attributeName
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func callContract(contractHash string, input []byte, blockchain *Blockchain, blockNumber *big.Int) ([]byte, error) {
|
||||
func (blockchain *Blockchain) FetchContractData(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) error {
|
||||
parsed, err := ParseAbi(abiJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
input, err := parsed.Pack(method, methodArg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
output, err := blockchain.callContract(address, input, big.NewInt(blockNumber))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return parsed.Unpack(result, method, output)
|
||||
}
|
||||
|
||||
func (blockchain *Blockchain) callContract(contractHash string, input []byte, blockNumber *big.Int) ([]byte, error) {
|
||||
to := common.HexToAddress(contractHash)
|
||||
msg := ethereum.CallMsg{To: &to, Data: input}
|
||||
return blockchain.client.CallContract(context.Background(), msg, blockNumber)
|
||||
|
||||
@@ -13,13 +13,13 @@ import (
|
||||
|
||||
func Info(client *rpc.Client) core.Node {
|
||||
node := core.Node{}
|
||||
node.NetworkId = NetworkId(client)
|
||||
node.NetworkID = NetworkID(client)
|
||||
node.GenesisBlock = GenesisBlock(client)
|
||||
node.Id, node.ClientName = IdClientName(client)
|
||||
node.ID, node.ClientName = IDClientName(client)
|
||||
return node
|
||||
}
|
||||
|
||||
func IdClientName(client *rpc.Client) (string, string) {
|
||||
func IDClientName(client *rpc.Client) (string, string) {
|
||||
var info p2p.NodeInfo
|
||||
modules, _ := client.SupportedModules()
|
||||
if _, ok := modules["admin"]; ok {
|
||||
@@ -29,7 +29,7 @@ func IdClientName(client *rpc.Client) (string, string) {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
func NetworkId(client *rpc.Client) float64 {
|
||||
func NetworkID(client *rpc.Client) float64 {
|
||||
var version string
|
||||
client.CallContext(context.Background(), &version, "net_version")
|
||||
networkId, _ := strconv.ParseFloat(version, 64)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"log"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
|
||||
func FindAttribute(contractAttributes core.ContractAttributes, attributeName string) *core.ContractAttribute {
|
||||
@@ -25,7 +25,9 @@ func SampleContract() core.Contract {
|
||||
}
|
||||
|
||||
func sampleAbiFileContents() string {
|
||||
abiFilepath := filepath.Join(config.ProjectRoot(), "pkg", "geth", "testing", "sample_abi.json")
|
||||
abiFileContents, _ := geth.ReadAbiFile(abiFilepath)
|
||||
abiFileContents, err := geth.ReadAbiFile(test_config.ABIFilePath + "sample_abi.json")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return abiFileContents
|
||||
}
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
package graphql_server
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
)
|
||||
|
||||
var Schema = `
|
||||
schema {
|
||||
query: Query
|
||||
}
|
||||
type Query {
|
||||
logFilter(name: String!): LogFilter
|
||||
watchedEvents(name: String!): WatchedEventList
|
||||
}
|
||||
|
||||
type LogFilter {
|
||||
name: String!
|
||||
fromBlock: Int
|
||||
toBlock: Int
|
||||
address: String!
|
||||
topics: [String]!
|
||||
}
|
||||
|
||||
type WatchedEventList{
|
||||
total: Int!
|
||||
watchedEvents: [WatchedEvent]!
|
||||
}
|
||||
|
||||
type WatchedEvent {
|
||||
name: String!
|
||||
blockNumber: Int!
|
||||
address: String!
|
||||
tx_hash: String!
|
||||
topic0: String!
|
||||
topic1: String!
|
||||
topic2: String!
|
||||
topic3: String!
|
||||
data: String!
|
||||
}
|
||||
`
|
||||
|
||||
type GraphQLRepositories struct {
|
||||
repositories.BlockRepository
|
||||
repositories.LogRepository
|
||||
repositories.WatchedEventRepository
|
||||
repositories.FilterRepository
|
||||
}
|
||||
|
||||
type Resolver struct {
|
||||
graphQLRepositories GraphQLRepositories
|
||||
}
|
||||
|
||||
func NewResolver(repositories GraphQLRepositories) *Resolver {
|
||||
return &Resolver{graphQLRepositories: repositories}
|
||||
}
|
||||
|
||||
func (r *Resolver) LogFilter(args struct {
|
||||
Name string
|
||||
}) (*logFilterResolver, error) {
|
||||
logFilter, err := r.graphQLRepositories.GetFilter(args.Name)
|
||||
if err != nil {
|
||||
return &logFilterResolver{}, err
|
||||
}
|
||||
return &logFilterResolver{&logFilter}, nil
|
||||
}
|
||||
|
||||
type logFilterResolver struct {
|
||||
lf *filters.LogFilter
|
||||
}
|
||||
|
||||
func (lfr *logFilterResolver) Name() string {
|
||||
return lfr.lf.Name
|
||||
}
|
||||
|
||||
func (lfr *logFilterResolver) FromBlock() *int32 {
|
||||
fromBlock := int32(lfr.lf.FromBlock)
|
||||
return &fromBlock
|
||||
}
|
||||
|
||||
func (lfr *logFilterResolver) ToBlock() *int32 {
|
||||
toBlock := int32(lfr.lf.ToBlock)
|
||||
return &toBlock
|
||||
}
|
||||
|
||||
func (lfr *logFilterResolver) Address() string {
|
||||
return lfr.lf.Address
|
||||
}
|
||||
|
||||
func (lfr *logFilterResolver) Topics() []*string {
|
||||
var topics = make([]*string, 4)
|
||||
for i := range topics {
|
||||
if lfr.lf.Topics[i] != "" {
|
||||
topics[i] = &lfr.lf.Topics[i]
|
||||
}
|
||||
}
|
||||
return topics
|
||||
}
|
||||
|
||||
func (r *Resolver) WatchedEvents(args struct {
|
||||
Name string
|
||||
}) (*watchedEventsResolver, error) {
|
||||
watchedEvents, err := r.graphQLRepositories.GetWatchedEvents(args.Name)
|
||||
if err != nil {
|
||||
return &watchedEventsResolver{}, err
|
||||
}
|
||||
return &watchedEventsResolver{watchedEvents: watchedEvents}, err
|
||||
}
|
||||
|
||||
type watchedEventsResolver struct {
|
||||
watchedEvents []*core.WatchedEvent
|
||||
}
|
||||
|
||||
func (wesr watchedEventsResolver) WatchedEvents() []*watchedEventResolver {
|
||||
return resolveWatchedEvents(wesr.watchedEvents)
|
||||
}
|
||||
|
||||
func (wesr watchedEventsResolver) Total() int32 {
|
||||
return int32(len(wesr.watchedEvents))
|
||||
}
|
||||
|
||||
func resolveWatchedEvents(watchedEvents []*core.WatchedEvent) []*watchedEventResolver {
|
||||
watchedEventResolvers := make([]*watchedEventResolver, 0)
|
||||
for _, watchedEvent := range watchedEvents {
|
||||
watchedEventResolvers = append(watchedEventResolvers, &watchedEventResolver{watchedEvent})
|
||||
}
|
||||
return watchedEventResolvers
|
||||
}
|
||||
|
||||
type watchedEventResolver struct {
|
||||
we *core.WatchedEvent
|
||||
}
|
||||
|
||||
func (wer watchedEventResolver) Name() string {
|
||||
return wer.we.Name
|
||||
}
|
||||
|
||||
func (wer watchedEventResolver) BlockNumber() int32 {
|
||||
return int32(wer.we.BlockNumber)
|
||||
}
|
||||
|
||||
func (wer watchedEventResolver) Address() string {
|
||||
return wer.we.Address
|
||||
}
|
||||
|
||||
func (wer watchedEventResolver) TxHash() string {
|
||||
return wer.we.TxHash
|
||||
}
|
||||
|
||||
func (wer watchedEventResolver) Topic0() string {
|
||||
return wer.we.Topic0
|
||||
}
|
||||
|
||||
func (wer watchedEventResolver) Topic1() string {
|
||||
return wer.we.Topic1
|
||||
}
|
||||
|
||||
func (wer watchedEventResolver) Topic2() string {
|
||||
return wer.we.Topic2
|
||||
}
|
||||
|
||||
func (wer watchedEventResolver) Topic3() string {
|
||||
return wer.we.Topic3
|
||||
}
|
||||
|
||||
func (wer watchedEventResolver) Data() string {
|
||||
return wer.we.Data
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
package graphql_server_test
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"encoding/json"
|
||||
|
||||
"context"
|
||||
|
||||
"github.com/neelance/graphql-go"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/graphql_server"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||
)
|
||||
|
||||
func formatJSON(data []byte) []byte {
|
||||
var v interface{}
|
||||
if err := json.Unmarshal(data, &v); err != nil {
|
||||
log.Fatalf("invalid JSON: %s", err)
|
||||
}
|
||||
formatted, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return formatted
|
||||
}
|
||||
|
||||
var _ = Describe("GraphQL", func() {
|
||||
var cfg config.Config
|
||||
var graphQLRepositories graphql_server.GraphQLRepositories
|
||||
|
||||
BeforeEach(func() {
|
||||
|
||||
cfg, _ = config.NewConfig("private")
|
||||
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
||||
db := postgres.NewTestDB(node)
|
||||
blockRepository := &postgres.BlockRepository{DB: db}
|
||||
logRepository := &postgres.LogRepository{DB: db}
|
||||
filterRepository := &postgres.FilterRepository{DB: db}
|
||||
watchedEventRepository := &postgres.WatchedEventRepository{DB: db}
|
||||
graphQLRepositories = graphql_server.GraphQLRepositories{
|
||||
WatchedEventRepository: watchedEventRepository,
|
||||
BlockRepository: blockRepository,
|
||||
LogRepository: logRepository,
|
||||
FilterRepository: filterRepository,
|
||||
}
|
||||
|
||||
err := graphQLRepositories.CreateFilter(filters.LogFilter{
|
||||
Name: "TestFilter1",
|
||||
FromBlock: 1,
|
||||
ToBlock: 10,
|
||||
Address: "0x123456789",
|
||||
Topics: core.Topics{0: "topic=1", 2: "topic=2"},
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
filter, err := graphQLRepositories.GetFilter("TestFilter1")
|
||||
if err != nil {
|
||||
log.Println(filter)
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
matchingEvent := core.Log{
|
||||
BlockNumber: 5,
|
||||
TxHash: "0xTX1",
|
||||
Address: "0x123456789",
|
||||
Topics: core.Topics{0: "topic=1", 2: "topic=2"},
|
||||
Index: 0,
|
||||
Data: "0xDATADATADATA",
|
||||
}
|
||||
nonMatchingEvent := core.Log{
|
||||
BlockNumber: 5,
|
||||
TxHash: "0xTX2",
|
||||
Address: "0xOTHERADDRESS",
|
||||
Topics: core.Topics{0: "topic=1", 2: "topic=2"},
|
||||
Index: 0,
|
||||
Data: "0xDATADATADATA",
|
||||
}
|
||||
err = graphQLRepositories.CreateLogs([]core.Log{matchingEvent, nonMatchingEvent})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
It("Queries example schema for specific log filter", func() {
|
||||
var variables map[string]interface{}
|
||||
resolver := graphql_server.NewResolver(graphQLRepositories)
|
||||
var schema = graphql.MustParseSchema(graphql_server.Schema, resolver)
|
||||
response := schema.Exec(context.Background(),
|
||||
`{
|
||||
logFilter(name: "TestFilter1") {
|
||||
name
|
||||
fromBlock
|
||||
toBlock
|
||||
address
|
||||
topics
|
||||
}
|
||||
}`,
|
||||
"",
|
||||
variables)
|
||||
expected := `{
|
||||
"logFilter": {
|
||||
"name": "TestFilter1",
|
||||
"fromBlock": 1,
|
||||
"toBlock": 10,
|
||||
"address": "0x123456789",
|
||||
"topics": ["topic=1", null, "topic=2", null]
|
||||
}
|
||||
}`
|
||||
var v interface{}
|
||||
if len(response.Errors) != 0 {
|
||||
log.Fatal(response.Errors)
|
||||
}
|
||||
err := json.Unmarshal(response.Data, &v)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
actualJSON := formatJSON(response.Data)
|
||||
expectedJSON := formatJSON([]byte(expected))
|
||||
Expect(actualJSON).To(Equal(expectedJSON))
|
||||
})
|
||||
|
||||
It("Queries example schema for specific watched event log", func() {
|
||||
var variables map[string]interface{}
|
||||
|
||||
resolver := graphql_server.NewResolver(graphQLRepositories)
|
||||
var schema = graphql.MustParseSchema(graphql_server.Schema, resolver)
|
||||
response := schema.Exec(context.Background(),
|
||||
`{
|
||||
watchedEvents(name: "TestFilter1") {
|
||||
total
|
||||
watchedEvents{
|
||||
name
|
||||
blockNumber
|
||||
address
|
||||
tx_hash
|
||||
topic0
|
||||
topic1
|
||||
topic2
|
||||
topic3
|
||||
data
|
||||
}
|
||||
}
|
||||
}`,
|
||||
"",
|
||||
variables)
|
||||
expected := `{
|
||||
"watchedEvents":
|
||||
{
|
||||
"total": 1,
|
||||
"watchedEvents": [
|
||||
{"name":"TestFilter1",
|
||||
"blockNumber": 5,
|
||||
"address": "0x123456789",
|
||||
"tx_hash": "0xTX1",
|
||||
"topic0": "topic=1",
|
||||
"topic1": "",
|
||||
"topic2": "topic=2",
|
||||
"topic3": "",
|
||||
"data": "0xDATADATADATA"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
var v interface{}
|
||||
if len(response.Errors) != 0 {
|
||||
log.Fatal(response.Errors)
|
||||
}
|
||||
err := json.Unmarshal(response.Data, &v)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
actualJSON := formatJSON(response.Data)
|
||||
expectedJSON := formatJSON([]byte(expected))
|
||||
Expect(actualJSON).To(Equal(expectedJSON))
|
||||
})
|
||||
})
|
||||
@@ -4,10 +4,10 @@ import (
|
||||
"log"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
)
|
||||
|
||||
func PopulateMissingBlocks(blockchain core.Blockchain, blockRepository repositories.BlockRepository, startingBlockNumber int64) int {
|
||||
func PopulateMissingBlocks(blockchain core.Blockchain, blockRepository datastore.BlockRepository, startingBlockNumber int64) int {
|
||||
lastBlock := blockchain.LastBlock().Int64()
|
||||
blockRange := blockRepository.MissingBlockNumbers(startingBlockNumber, lastBlock-1)
|
||||
log.SetPrefix("")
|
||||
@@ -16,7 +16,7 @@ func PopulateMissingBlocks(blockchain core.Blockchain, blockRepository repositor
|
||||
return len(blockRange)
|
||||
}
|
||||
|
||||
func RetrieveAndUpdateBlocks(blockchain core.Blockchain, blockRepository repositories.BlockRepository, blockNumbers []int64) int {
|
||||
func RetrieveAndUpdateBlocks(blockchain core.Blockchain, blockRepository datastore.BlockRepository, blockNumbers []int64) int {
|
||||
for _, blockNumber := range blockNumbers {
|
||||
block := blockchain.GetBlockByNumber(blockNumber)
|
||||
blockRepository.CreateOrUpdateBlock(block)
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/inmemory"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/history"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/inmemory"
|
||||
)
|
||||
|
||||
var _ = Describe("Populating blocks", func() {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"text/template"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
)
|
||||
|
||||
const WindowTemplate = `Validating Blocks
|
||||
@@ -17,12 +17,12 @@ var ParsedWindowTemplate = *template.Must(template.New("window").Parse(WindowTem
|
||||
|
||||
type BlockValidator struct {
|
||||
blockchain core.Blockchain
|
||||
blockRepository repositories.BlockRepository
|
||||
blockRepository datastore.BlockRepository
|
||||
windowSize int
|
||||
parsedLoggingTemplate template.Template
|
||||
}
|
||||
|
||||
func NewBlockValidator(blockchain core.Blockchain, blockRepository repositories.BlockRepository, windowSize int) *BlockValidator {
|
||||
func NewBlockValidator(blockchain core.Blockchain, blockRepository datastore.BlockRepository, windowSize int) *BlockValidator {
|
||||
return &BlockValidator{
|
||||
blockchain,
|
||||
blockRepository,
|
||||
|
||||
@@ -9,9 +9,9 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/inmemory"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/history"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/inmemory"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
func (db *DB) clearData() {
|
||||
db.MustExec("DELETE FROM watched_contracts")
|
||||
db.MustExec("DELETE FROM transactions")
|
||||
db.MustExec("DELETE FROM blocks")
|
||||
db.MustExec("DELETE FROM logs")
|
||||
db.MustExec("DELETE FROM receipts")
|
||||
db.MustExec("DELETE FROM log_filters")
|
||||
}
|
||||
|
||||
func NewTestDB(node core.Node) *DB {
|
||||
cfg, _ := config.NewConfig("private")
|
||||
db, _ := NewDB(cfg.Database, node)
|
||||
db.clearData()
|
||||
return db
|
||||
}
|
||||
Reference in New Issue
Block a user