forked from cerc-io/ipld-eth-server
Separate DB access into several repos (#28)
* Separate files for InMemory * Start using separate repos for collaborating objects * Before Updating schema * Separate various repos
This commit is contained in:
parent
605b0a96ae
commit
ed907535e3
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||||
"github.com/vulcanize/vulcanizedb/utils"
|
"github.com/vulcanize/vulcanizedb/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -56,7 +57,8 @@ func addFilter() {
|
|||||||
}
|
}
|
||||||
var logFilters filters.LogFilters
|
var logFilters filters.LogFilters
|
||||||
blockchain := geth.NewBlockchain(ipc)
|
blockchain := geth.NewBlockchain(ipc)
|
||||||
repository := utils.LoadPostgres(databaseConfig, blockchain.Node())
|
db := utils.LoadPostgres(databaseConfig, blockchain.Node())
|
||||||
|
filterRepository := postgres.FilterRepository{DB: &db}
|
||||||
absFilePath := utils.AbsFilePath(filterFilepath)
|
absFilePath := utils.AbsFilePath(filterFilepath)
|
||||||
logFilterBytes, err := ioutil.ReadFile(absFilePath)
|
logFilterBytes, err := ioutil.ReadFile(absFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -67,7 +69,7 @@ func addFilter() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
for _, filter := range logFilters {
|
for _, filter := range logFilters {
|
||||||
err = repository.CreateFilter(filter)
|
err = filterRepository.CreateFilter(filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/graphql_server"
|
"github.com/vulcanize/vulcanizedb/pkg/graphql_server"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||||
"github.com/vulcanize/vulcanizedb/utils"
|
"github.com/vulcanize/vulcanizedb/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,8 +44,18 @@ func init() {
|
|||||||
func parseSchema() *graphql.Schema {
|
func parseSchema() *graphql.Schema {
|
||||||
|
|
||||||
blockchain := geth.NewBlockchain(ipc)
|
blockchain := geth.NewBlockchain(ipc)
|
||||||
repository := utils.LoadPostgres(databaseConfig, blockchain.Node())
|
db := utils.LoadPostgres(databaseConfig, blockchain.Node())
|
||||||
schema := graphql.MustParseSchema(graphql_server.Schema, graphql_server.NewResolver(repository))
|
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,
|
||||||
|
}
|
||||||
|
schema := graphql.MustParseSchema(graphql_server.Schema, graphql_server.NewResolver(graphQLRepositories))
|
||||||
return schema
|
return schema
|
||||||
|
|
||||||
}
|
}
|
||||||
|
14
cmd/sync.go
14
cmd/sync.go
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/history"
|
"github.com/vulcanize/vulcanizedb/pkg/history"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||||
"github.com/vulcanize/vulcanizedb/utils"
|
"github.com/vulcanize/vulcanizedb/utils"
|
||||||
)
|
)
|
||||||
@ -49,9 +50,9 @@ func init() {
|
|||||||
syncCmd.Flags().IntVarP(&startingBlockNumber, "starting-block-number", "s", 0, "Block number to start syncing from")
|
syncCmd.Flags().IntVarP(&startingBlockNumber, "starting-block-number", "s", 0, "Block number to start syncing from")
|
||||||
}
|
}
|
||||||
|
|
||||||
func backFillAllBlocks(blockchain core.Blockchain, repository postgres.DB, missingBlocksPopulated chan int, startingBlockNumber int64) {
|
func backFillAllBlocks(blockchain core.Blockchain, blockRepository repositories.BlockRepository, missingBlocksPopulated chan int, startingBlockNumber int64) {
|
||||||
go func() {
|
go func() {
|
||||||
missingBlocksPopulated <- history.PopulateMissingBlocks(blockchain, repository, startingBlockNumber)
|
missingBlocksPopulated <- history.PopulateMissingBlocks(blockchain, blockRepository, startingBlockNumber)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,12 +64,13 @@ func sync() {
|
|||||||
if blockchain.LastBlock().Int64() == 0 {
|
if blockchain.LastBlock().Int64() == 0 {
|
||||||
log.Fatal("geth initial: state sync not finished")
|
log.Fatal("geth initial: state sync not finished")
|
||||||
}
|
}
|
||||||
repository := utils.LoadPostgres(databaseConfig, blockchain.Node())
|
db := utils.LoadPostgres(databaseConfig, blockchain.Node())
|
||||||
validator := history.NewBlockValidator(blockchain, repository, 15)
|
blockRepository := postgres.BlockRepository{DB: &db}
|
||||||
|
validator := history.NewBlockValidator(blockchain, blockRepository, 15)
|
||||||
|
|
||||||
missingBlocksPopulated := make(chan int)
|
missingBlocksPopulated := make(chan int)
|
||||||
_startingBlockNumber := int64(startingBlockNumber)
|
_startingBlockNumber := int64(startingBlockNumber)
|
||||||
go backFillAllBlocks(blockchain, repository, missingBlocksPopulated, _startingBlockNumber)
|
go backFillAllBlocks(blockchain, blockRepository, missingBlocksPopulated, _startingBlockNumber)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@ -76,7 +78,7 @@ func sync() {
|
|||||||
window := validator.ValidateBlocks()
|
window := validator.ValidateBlocks()
|
||||||
validator.Log(os.Stdout, window)
|
validator.Log(os.Stdout, window)
|
||||||
case <-missingBlocksPopulated:
|
case <-missingBlocksPopulated:
|
||||||
go backFillAllBlocks(blockchain, repository, missingBlocksPopulated, _startingBlockNumber)
|
go backFillAllBlocks(blockchain, blockRepository, missingBlocksPopulated, _startingBlockNumber)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
[{
|
[
|
||||||
"name": "TransferFilter",
|
{
|
||||||
"fromBlock": "0x488290",
|
"name": "TransferFilter",
|
||||||
"toBlock": "0x488678",
|
"fromBlock": "0x488290",
|
||||||
"address": "0x06012c8cf97bead5deae237070f9587f8e7a266d",
|
"toBlock": "0x488678",
|
||||||
"topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]
|
"address": "0x06012c8cf97bead5deae237070f9587f8e7a266d",
|
||||||
},
|
"topics": [
|
||||||
{
|
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
"name": "NewFilter",
|
"name": "NewFilter",
|
||||||
"fromBlock": "0x4B34AD",
|
"fromBlock": "0x4B34AD",
|
||||||
"address": "0x06012c8cf97bead5deae237070f9587f8e7a266d",
|
"address": "0x06012c8cf97bead5deae237070f9587f8e7a266d",
|
||||||
"topics": ["0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80"]
|
"topics": [
|
||||||
}]
|
"0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
@ -19,18 +19,19 @@ func init() {
|
|||||||
var _ = Describe("Reading from the Geth blockchain", func() {
|
var _ = Describe("Reading from the Geth blockchain", func() {
|
||||||
|
|
||||||
var blockchain *geth.Blockchain
|
var blockchain *geth.Blockchain
|
||||||
var repository *inmemory.InMemory
|
var inMemory *inmemory.InMemory
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
cfg, _ := config.NewConfig("private")
|
cfg, _ := config.NewConfig("private")
|
||||||
blockchain = geth.NewBlockchain(cfg.Client.IPCPath)
|
blockchain = geth.NewBlockchain(cfg.Client.IPCPath)
|
||||||
repository = inmemory.NewInMemory()
|
inMemory = inmemory.NewInMemory()
|
||||||
})
|
})
|
||||||
|
|
||||||
It("reads two blocks", func(done Done) {
|
It("reads two blocks", func(done Done) {
|
||||||
validator := history.NewBlockValidator(blockchain, repository, 2)
|
blocks := &inmemory.BlockRepository{InMemory: inMemory}
|
||||||
|
validator := history.NewBlockValidator(blockchain, blocks, 2)
|
||||||
validator.ValidateBlocks()
|
validator.ValidateBlocks()
|
||||||
Expect(repository.BlockCount()).To(Equal(2))
|
Expect(blocks.BlockCount()).To(Equal(2))
|
||||||
close(done)
|
close(done)
|
||||||
}, 15)
|
}, 15)
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ type ContractSummary struct {
|
|||||||
blockChain core.Blockchain
|
blockChain core.Blockchain
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSummary(blockchain core.Blockchain, repository repositories.Repository, contractHash string, blockNumber *big.Int) (ContractSummary, error) {
|
func NewSummary(blockchain core.Blockchain, contractRepository repositories.ContractRepository, contractHash string, blockNumber *big.Int) (ContractSummary, error) {
|
||||||
contract, err := repository.GetContract(contractHash)
|
contract, err := contractRepository.GetContract(contractHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ContractSummary{}, err
|
return ContractSummary{}, err
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,18 +12,26 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/inmemory"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories/inmemory"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCurrentContractSummary(blockchain core.Blockchain, repository repositories.Repository, contractHash string) (contract_summary.ContractSummary, error) {
|
func NewCurrentContractSummary(blockchain core.Blockchain, contractRepository repositories.ContractRepository, contractHash string) (contract_summary.ContractSummary, error) {
|
||||||
return contract_summary.NewSummary(blockchain, repository, contractHash, nil)
|
return contract_summary.NewSummary(blockchain, contractRepository, contractHash, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = Describe("The contract summary", func() {
|
var _ = Describe("The contract summary", func() {
|
||||||
|
|
||||||
|
var inMemoryDB *inmemory.InMemory
|
||||||
|
var contractRepostiory *inmemory.ContractRepostiory
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
inMemoryDB = inmemory.NewInMemory()
|
||||||
|
contractRepostiory = &inmemory.ContractRepostiory{InMemory: inMemoryDB}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
Context("when the given contract does not exist", func() {
|
Context("when the given contract does not exist", func() {
|
||||||
It("returns an error", func() {
|
It("returns an error", func() {
|
||||||
repository := inmemory.NewInMemory()
|
|
||||||
blockchain := fakes.NewBlockchain()
|
blockchain := fakes.NewBlockchain()
|
||||||
|
|
||||||
contractSummary, err := NewCurrentContractSummary(blockchain, repository, "0x123")
|
contractSummary, err := NewCurrentContractSummary(blockchain, contractRepostiory, "0x123")
|
||||||
|
|
||||||
Expect(contractSummary).To(Equal(contract_summary.ContractSummary{}))
|
Expect(contractSummary).To(Equal(contract_summary.ContractSummary{}))
|
||||||
Expect(err).NotTo(BeNil())
|
Expect(err).NotTo(BeNil())
|
||||||
@ -32,101 +40,101 @@ var _ = Describe("The contract summary", func() {
|
|||||||
|
|
||||||
Context("when the given contract exists", func() {
|
Context("when the given contract exists", func() {
|
||||||
It("returns the summary", func() {
|
It("returns the summary", func() {
|
||||||
repository := inmemory.NewInMemory()
|
|
||||||
contract := core.Contract{Hash: "0x123"}
|
contract := core.Contract{Hash: "0x123"}
|
||||||
repository.CreateContract(contract)
|
contractRepostiory.CreateContract(contract)
|
||||||
blockchain := fakes.NewBlockchain()
|
blockchain := fakes.NewBlockchain()
|
||||||
|
|
||||||
contractSummary, err := NewCurrentContractSummary(blockchain, repository, "0x123")
|
contractSummary, err := NewCurrentContractSummary(blockchain, contractRepostiory, "0x123")
|
||||||
|
|
||||||
Expect(contractSummary).NotTo(Equal(contract_summary.ContractSummary{}))
|
Expect(contractSummary).NotTo(Equal(contract_summary.ContractSummary{}))
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("includes the contract hash in the summary", func() {
|
It("includes the contract hash in the summary", func() {
|
||||||
repository := inmemory.NewInMemory()
|
|
||||||
contract := core.Contract{Hash: "0x123"}
|
contract := core.Contract{Hash: "0x123"}
|
||||||
repository.CreateContract(contract)
|
contractRepostiory.CreateContract(contract)
|
||||||
blockchain := fakes.NewBlockchain()
|
blockchain := fakes.NewBlockchain()
|
||||||
|
|
||||||
contractSummary, _ := NewCurrentContractSummary(blockchain, repository, "0x123")
|
contractSummary, _ := NewCurrentContractSummary(blockchain, contractRepostiory, "0x123")
|
||||||
|
|
||||||
Expect(contractSummary.ContractHash).To(Equal("0x123"))
|
Expect(contractSummary.ContractHash).To(Equal("0x123"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("sets the number of transactions", func() {
|
It("sets the number of transactions", func() {
|
||||||
repository := inmemory.NewInMemory()
|
blocks := &inmemory.BlockRepository{InMemory: inMemoryDB}
|
||||||
|
blockchain := fakes.NewBlockchain()
|
||||||
|
|
||||||
contract := core.Contract{Hash: "0x123"}
|
contract := core.Contract{Hash: "0x123"}
|
||||||
repository.CreateContract(contract)
|
contractRepostiory.CreateContract(contract)
|
||||||
block := core.Block{
|
block := core.Block{
|
||||||
Transactions: []core.Transaction{
|
Transactions: []core.Transaction{
|
||||||
{To: "0x123"},
|
{To: "0x123"},
|
||||||
{To: "0x123"},
|
{To: "0x123"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
repository.CreateOrUpdateBlock(block)
|
blocks.CreateOrUpdateBlock(block)
|
||||||
blockchain := fakes.NewBlockchain()
|
|
||||||
|
|
||||||
contractSummary, _ := NewCurrentContractSummary(blockchain, repository, "0x123")
|
contractSummary, _ := NewCurrentContractSummary(blockchain, contractRepostiory, "0x123")
|
||||||
|
|
||||||
Expect(contractSummary.NumberOfTransactions).To(Equal(2))
|
Expect(contractSummary.NumberOfTransactions).To(Equal(2))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("sets the last transaction", func() {
|
It("sets the last transaction", func() {
|
||||||
repository := inmemory.NewInMemory()
|
blocks := &inmemory.BlockRepository{InMemory: inMemoryDB}
|
||||||
|
blockchain := fakes.NewBlockchain()
|
||||||
|
|
||||||
contract := core.Contract{Hash: "0x123"}
|
contract := core.Contract{Hash: "0x123"}
|
||||||
repository.CreateContract(contract)
|
contractRepostiory.CreateContract(contract)
|
||||||
block := core.Block{
|
block := core.Block{
|
||||||
Transactions: []core.Transaction{
|
Transactions: []core.Transaction{
|
||||||
{Hash: "TRANSACTION2", To: "0x123"},
|
{Hash: "TRANSACTION2", To: "0x123"},
|
||||||
{Hash: "TRANSACTION1", To: "0x123"},
|
{Hash: "TRANSACTION1", To: "0x123"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
repository.CreateOrUpdateBlock(block)
|
blocks.CreateOrUpdateBlock(block)
|
||||||
blockchain := fakes.NewBlockchain()
|
|
||||||
|
|
||||||
contractSummary, _ := NewCurrentContractSummary(blockchain, repository, "0x123")
|
contractSummary, _ := NewCurrentContractSummary(blockchain, contractRepostiory, "0x123")
|
||||||
|
|
||||||
Expect(contractSummary.LastTransaction.Hash).To(Equal("TRANSACTION2"))
|
Expect(contractSummary.LastTransaction.Hash).To(Equal("TRANSACTION2"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets contract state attribute for the contract from the blockchain", func() {
|
It("gets contract state attribute for the contract from the blockchain", func() {
|
||||||
repository := inmemory.NewInMemory()
|
|
||||||
contract := core.Contract{Hash: "0x123"}
|
|
||||||
repository.CreateContract(contract)
|
|
||||||
blockchain := fakes.NewBlockchain()
|
blockchain := fakes.NewBlockchain()
|
||||||
|
|
||||||
|
contract := core.Contract{Hash: "0x123"}
|
||||||
|
contractRepostiory.CreateContract(contract)
|
||||||
blockchain.SetContractStateAttribute("0x123", nil, "foo", "bar")
|
blockchain.SetContractStateAttribute("0x123", nil, "foo", "bar")
|
||||||
|
|
||||||
contractSummary, _ := NewCurrentContractSummary(blockchain, repository, "0x123")
|
contractSummary, _ := NewCurrentContractSummary(blockchain, contractRepostiory, "0x123")
|
||||||
attribute := contractSummary.GetStateAttribute("foo")
|
attribute := contractSummary.GetStateAttribute("foo")
|
||||||
|
|
||||||
Expect(attribute).To(Equal("bar"))
|
Expect(attribute).To(Equal("bar"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets contract state attribute for the contract from the blockchain at specific block height", func() {
|
It("gets contract state attribute for the contract from the blockchain at specific block height", func() {
|
||||||
repository := inmemory.NewInMemory()
|
|
||||||
contract := core.Contract{Hash: "0x123"}
|
|
||||||
repository.CreateContract(contract)
|
|
||||||
blockchain := fakes.NewBlockchain()
|
blockchain := fakes.NewBlockchain()
|
||||||
|
|
||||||
|
contract := core.Contract{Hash: "0x123"}
|
||||||
|
contractRepostiory.CreateContract(contract)
|
||||||
blockNumber := big.NewInt(1000)
|
blockNumber := big.NewInt(1000)
|
||||||
blockchain.SetContractStateAttribute("0x123", nil, "foo", "bar")
|
blockchain.SetContractStateAttribute("0x123", nil, "foo", "bar")
|
||||||
blockchain.SetContractStateAttribute("0x123", blockNumber, "foo", "baz")
|
blockchain.SetContractStateAttribute("0x123", blockNumber, "foo", "baz")
|
||||||
|
|
||||||
contractSummary, _ := contract_summary.NewSummary(blockchain, repository, "0x123", blockNumber)
|
contractSummary, _ := contract_summary.NewSummary(blockchain, contractRepostiory, "0x123", blockNumber)
|
||||||
attribute := contractSummary.GetStateAttribute("foo")
|
attribute := contractSummary.GetStateAttribute("foo")
|
||||||
|
|
||||||
Expect(attribute).To(Equal("baz"))
|
Expect(attribute).To(Equal("baz"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets attributes for the contract from the blockchain", func() {
|
It("gets attributes for the contract from the blockchain", func() {
|
||||||
repository := inmemory.NewInMemory()
|
|
||||||
contract := core.Contract{Hash: "0x123"}
|
|
||||||
repository.CreateContract(contract)
|
|
||||||
blockchain := fakes.NewBlockchain()
|
blockchain := fakes.NewBlockchain()
|
||||||
|
|
||||||
|
contract := core.Contract{Hash: "0x123"}
|
||||||
|
contractRepostiory.CreateContract(contract)
|
||||||
blockchain.SetContractStateAttribute("0x123", nil, "foo", "bar")
|
blockchain.SetContractStateAttribute("0x123", nil, "foo", "bar")
|
||||||
blockchain.SetContractStateAttribute("0x123", nil, "baz", "bar")
|
blockchain.SetContractStateAttribute("0x123", nil, "baz", "bar")
|
||||||
|
|
||||||
contractSummary, _ := NewCurrentContractSummary(blockchain, repository, "0x123")
|
contractSummary, _ := NewCurrentContractSummary(blockchain, contractRepostiory, "0x123")
|
||||||
|
|
||||||
Expect(contractSummary.Attributes).To(Equal(
|
Expect(contractSummary.Attributes).To(Equal(
|
||||||
core.ContractAttributes{
|
core.ContractAttributes{
|
||||||
|
@ -41,18 +41,25 @@ var Schema = `
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
type Resolver struct {
|
type GraphQLRepositories struct {
|
||||||
repository repositories.Repository
|
repositories.BlockRepository
|
||||||
|
repositories.LogRepository
|
||||||
|
repositories.WatchedEventRepository
|
||||||
|
repositories.FilterRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewResolver(repository repositories.Repository) *Resolver {
|
type Resolver struct {
|
||||||
return &Resolver{repository: repository}
|
graphQLRepositories GraphQLRepositories
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewResolver(repositories GraphQLRepositories) *Resolver {
|
||||||
|
return &Resolver{graphQLRepositories: repositories}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) LogFilter(args struct {
|
func (r *Resolver) LogFilter(args struct {
|
||||||
Name string
|
Name string
|
||||||
}) (*logFilterResolver, error) {
|
}) (*logFilterResolver, error) {
|
||||||
logFilter, err := r.repository.GetFilter(args.Name)
|
logFilter, err := r.graphQLRepositories.GetFilter(args.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &logFilterResolver{}, err
|
return &logFilterResolver{}, err
|
||||||
}
|
}
|
||||||
@ -94,7 +101,7 @@ func (lfr *logFilterResolver) Topics() []*string {
|
|||||||
func (r *Resolver) WatchedEvents(args struct {
|
func (r *Resolver) WatchedEvents(args struct {
|
||||||
Name string
|
Name string
|
||||||
}) (*watchedEventsResolver, error) {
|
}) (*watchedEventsResolver, error) {
|
||||||
watchedEvents, err := r.repository.GetWatchedEvents(args.Name)
|
watchedEvents, err := r.graphQLRepositories.GetWatchedEvents(args.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &watchedEventsResolver{}, err
|
return &watchedEventsResolver{}, err
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/graphql_server"
|
"github.com/vulcanize/vulcanizedb/pkg/graphql_server"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,27 +31,38 @@ func formatJSON(data []byte) []byte {
|
|||||||
|
|
||||||
var _ = Describe("GraphQL", func() {
|
var _ = Describe("GraphQL", func() {
|
||||||
var cfg config.Config
|
var cfg config.Config
|
||||||
var repository repositories.Repository
|
var graphQLRepositories graphql_server.GraphQLRepositories
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
|
|
||||||
cfg, _ = config.NewConfig("private")
|
cfg, _ = config.NewConfig("private")
|
||||||
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
||||||
repository = postgres.BuildRepository(node)
|
db := postgres.NewTestDB(node)
|
||||||
e := repository.CreateFilter(filters.LogFilter{
|
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",
|
Name: "TestFilter1",
|
||||||
FromBlock: 1,
|
FromBlock: 1,
|
||||||
ToBlock: 10,
|
ToBlock: 10,
|
||||||
Address: "0x123456789",
|
Address: "0x123456789",
|
||||||
Topics: core.Topics{0: "topic=1", 2: "topic=2"},
|
Topics: core.Topics{0: "topic=1", 2: "topic=2"},
|
||||||
})
|
})
|
||||||
if e != nil {
|
if err != nil {
|
||||||
log.Fatal(e)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
f, e := repository.GetFilter("TestFilter1")
|
filter, err := graphQLRepositories.GetFilter("TestFilter1")
|
||||||
if e != nil {
|
if err != nil {
|
||||||
log.Println(f)
|
log.Println(filter)
|
||||||
log.Fatal(e)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
matchingEvent := core.Log{
|
matchingEvent := core.Log{
|
||||||
@ -71,16 +81,16 @@ var _ = Describe("GraphQL", func() {
|
|||||||
Index: 0,
|
Index: 0,
|
||||||
Data: "0xDATADATADATA",
|
Data: "0xDATADATADATA",
|
||||||
}
|
}
|
||||||
e = repository.CreateLogs([]core.Log{matchingEvent, nonMatchingEvent})
|
err = graphQLRepositories.CreateLogs([]core.Log{matchingEvent, nonMatchingEvent})
|
||||||
if e != nil {
|
if err != nil {
|
||||||
log.Fatal(e)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Queries example schema for specific log filter", func() {
|
It("Queries example schema for specific log filter", func() {
|
||||||
var variables map[string]interface{}
|
var variables map[string]interface{}
|
||||||
r := graphql_server.NewResolver(repository)
|
resolver := graphql_server.NewResolver(graphQLRepositories)
|
||||||
var schema = graphql.MustParseSchema(graphql_server.Schema, r)
|
var schema = graphql.MustParseSchema(graphql_server.Schema, resolver)
|
||||||
response := schema.Exec(context.Background(),
|
response := schema.Exec(context.Background(),
|
||||||
`{
|
`{
|
||||||
logFilter(name: "TestFilter1") {
|
logFilter(name: "TestFilter1") {
|
||||||
@ -108,16 +118,16 @@ var _ = Describe("GraphQL", func() {
|
|||||||
}
|
}
|
||||||
err := json.Unmarshal(response.Data, &v)
|
err := json.Unmarshal(response.Data, &v)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
a := formatJSON(response.Data)
|
actualJSON := formatJSON(response.Data)
|
||||||
e := formatJSON([]byte(expected))
|
expectedJSON := formatJSON([]byte(expected))
|
||||||
Expect(a).To(Equal(e))
|
Expect(actualJSON).To(Equal(expectedJSON))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Queries example schema for specific watched event log", func() {
|
It("Queries example schema for specific watched event log", func() {
|
||||||
var variables map[string]interface{}
|
var variables map[string]interface{}
|
||||||
|
|
||||||
r := graphql_server.NewResolver(repository)
|
resolver := graphql_server.NewResolver(graphQLRepositories)
|
||||||
var schema = graphql.MustParseSchema(graphql_server.Schema, r)
|
var schema = graphql.MustParseSchema(graphql_server.Schema, resolver)
|
||||||
response := schema.Exec(context.Background(),
|
response := schema.Exec(context.Background(),
|
||||||
`{
|
`{
|
||||||
watchedEvents(name: "TestFilter1") {
|
watchedEvents(name: "TestFilter1") {
|
||||||
@ -161,8 +171,8 @@ var _ = Describe("GraphQL", func() {
|
|||||||
}
|
}
|
||||||
err := json.Unmarshal(response.Data, &v)
|
err := json.Unmarshal(response.Data, &v)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
a := formatJSON(response.Data)
|
actualJSON := formatJSON(response.Data)
|
||||||
e := formatJSON([]byte(expected))
|
expectedJSON := formatJSON([]byte(expected))
|
||||||
Expect(a).To(Equal(e))
|
Expect(actualJSON).To(Equal(expectedJSON))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -7,19 +7,19 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PopulateMissingBlocks(blockchain core.Blockchain, repository repositories.Repository, startingBlockNumber int64) int {
|
func PopulateMissingBlocks(blockchain core.Blockchain, blockRepository repositories.BlockRepository, startingBlockNumber int64) int {
|
||||||
lastBlock := blockchain.LastBlock().Int64()
|
lastBlock := blockchain.LastBlock().Int64()
|
||||||
blockRange := repository.MissingBlockNumbers(startingBlockNumber, lastBlock-1)
|
blockRange := blockRepository.MissingBlockNumbers(startingBlockNumber, lastBlock-1)
|
||||||
log.SetPrefix("")
|
log.SetPrefix("")
|
||||||
log.Printf("Backfilling %d blocks\n\n", len(blockRange))
|
log.Printf("Backfilling %d blocks\n\n", len(blockRange))
|
||||||
RetrieveAndUpdateBlocks(blockchain, repository, blockRange)
|
RetrieveAndUpdateBlocks(blockchain, blockRepository, blockRange)
|
||||||
return len(blockRange)
|
return len(blockRange)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RetrieveAndUpdateBlocks(blockchain core.Blockchain, repository repositories.Repository, blockNumbers []int64) int {
|
func RetrieveAndUpdateBlocks(blockchain core.Blockchain, blockRepository repositories.BlockRepository, blockNumbers []int64) int {
|
||||||
for _, blockNumber := range blockNumbers {
|
for _, blockNumber := range blockNumbers {
|
||||||
block := blockchain.GetBlockByNumber(blockNumber)
|
block := blockchain.GetBlockByNumber(blockNumber)
|
||||||
repository.CreateOrUpdateBlock(block)
|
blockRepository.CreateOrUpdateBlock(block)
|
||||||
}
|
}
|
||||||
return len(blockNumbers)
|
return len(blockNumbers)
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Populating blocks", func() {
|
var _ = Describe("Populating blocks", func() {
|
||||||
|
var inMemory *inmemory.InMemory
|
||||||
|
var blockRepository *inmemory.BlockRepository
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
inMemory = inmemory.NewInMemory()
|
||||||
|
blockRepository = &inmemory.BlockRepository{InMemory: inMemory}
|
||||||
|
})
|
||||||
|
|
||||||
It("fills in the only missing block (Number 1)", func() {
|
It("fills in the only missing block (Number 1)", func() {
|
||||||
blocks := []core.Block{
|
blocks := []core.Block{
|
||||||
@ -17,11 +24,11 @@ var _ = Describe("Populating blocks", func() {
|
|||||||
{Number: 2},
|
{Number: 2},
|
||||||
}
|
}
|
||||||
blockchain := fakes.NewBlockchainWithBlocks(blocks)
|
blockchain := fakes.NewBlockchainWithBlocks(blocks)
|
||||||
repository := inmemory.NewInMemory()
|
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 2})
|
|
||||||
|
|
||||||
blocksAdded := history.PopulateMissingBlocks(blockchain, repository, 1)
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 2})
|
||||||
_, err := repository.GetBlock(1)
|
|
||||||
|
blocksAdded := history.PopulateMissingBlocks(blockchain, blockRepository, 1)
|
||||||
|
_, err := blockRepository.GetBlock(1)
|
||||||
|
|
||||||
Expect(blocksAdded).To(Equal(1))
|
Expect(blocksAdded).To(Equal(1))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@ -40,29 +47,28 @@ var _ = Describe("Populating blocks", func() {
|
|||||||
{Number: 12},
|
{Number: 12},
|
||||||
{Number: 13},
|
{Number: 13},
|
||||||
})
|
})
|
||||||
repository := inmemory.NewInMemory()
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 1})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 1})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 2})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 2})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 3})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 3})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 6})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 6})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 7})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 7})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 9})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 9})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 11})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 11})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 12})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 12})
|
|
||||||
|
|
||||||
blocksAdded := history.PopulateMissingBlocks(blockchain, repository, 5)
|
blocksAdded := history.PopulateMissingBlocks(blockchain, blockRepository, 5)
|
||||||
|
|
||||||
Expect(blocksAdded).To(Equal(3))
|
Expect(blocksAdded).To(Equal(3))
|
||||||
Expect(repository.BlockCount()).To(Equal(11))
|
Expect(blockRepository.BlockCount()).To(Equal(11))
|
||||||
_, err := repository.GetBlock(4)
|
_, err := blockRepository.GetBlock(4)
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
_, err = repository.GetBlock(5)
|
_, err = blockRepository.GetBlock(5)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
_, err = repository.GetBlock(8)
|
_, err = blockRepository.GetBlock(8)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
_, err = repository.GetBlock(10)
|
_, err = blockRepository.GetBlock(10)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
_, err = repository.GetBlock(13)
|
_, err = blockRepository.GetBlock(13)
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -72,11 +78,10 @@ var _ = Describe("Populating blocks", func() {
|
|||||||
{Number: 5},
|
{Number: 5},
|
||||||
{Number: 6},
|
{Number: 6},
|
||||||
})
|
})
|
||||||
repository := inmemory.NewInMemory()
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 3})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 3})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 6})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 6})
|
|
||||||
|
|
||||||
numberOfBlocksCreated := history.PopulateMissingBlocks(blockchain, repository, 3)
|
numberOfBlocksCreated := history.PopulateMissingBlocks(blockchain, blockRepository, 3)
|
||||||
|
|
||||||
Expect(numberOfBlocksCreated).To(Equal(2))
|
Expect(numberOfBlocksCreated).To(Equal(2))
|
||||||
})
|
})
|
||||||
@ -89,11 +94,10 @@ var _ = Describe("Populating blocks", func() {
|
|||||||
{Number: 4},
|
{Number: 4},
|
||||||
{Number: 5},
|
{Number: 5},
|
||||||
})
|
})
|
||||||
repository := inmemory.NewInMemory()
|
|
||||||
|
|
||||||
history.RetrieveAndUpdateBlocks(blockchain, repository, history.MakeRange(2, 5))
|
history.RetrieveAndUpdateBlocks(blockchain, blockRepository, history.MakeRange(2, 5))
|
||||||
Expect(repository.BlockCount()).To(Equal(3))
|
Expect(blockRepository.BlockCount()).To(Equal(3))
|
||||||
Expect(repository.CreateOrUpdateBlockCallCount).To(Equal(3))
|
Expect(blockRepository.CreateOrUpdateBlockCallCount).To(Equal(3))
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -17,15 +17,15 @@ var ParsedWindowTemplate = *template.Must(template.New("window").Parse(WindowTem
|
|||||||
|
|
||||||
type BlockValidator struct {
|
type BlockValidator struct {
|
||||||
blockchain core.Blockchain
|
blockchain core.Blockchain
|
||||||
repository repositories.Repository
|
blockRepository repositories.BlockRepository
|
||||||
windowSize int
|
windowSize int
|
||||||
parsedLoggingTemplate template.Template
|
parsedLoggingTemplate template.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBlockValidator(blockchain core.Blockchain, repository repositories.Repository, windowSize int) *BlockValidator {
|
func NewBlockValidator(blockchain core.Blockchain, blockRepository repositories.BlockRepository, windowSize int) *BlockValidator {
|
||||||
return &BlockValidator{
|
return &BlockValidator{
|
||||||
blockchain,
|
blockchain,
|
||||||
repository,
|
blockRepository,
|
||||||
windowSize,
|
windowSize,
|
||||||
ParsedWindowTemplate,
|
ParsedWindowTemplate,
|
||||||
}
|
}
|
||||||
@ -34,9 +34,9 @@ func NewBlockValidator(blockchain core.Blockchain, repository repositories.Repos
|
|||||||
func (bv BlockValidator) ValidateBlocks() ValidationWindow {
|
func (bv BlockValidator) ValidateBlocks() ValidationWindow {
|
||||||
window := MakeValidationWindow(bv.blockchain, bv.windowSize)
|
window := MakeValidationWindow(bv.blockchain, bv.windowSize)
|
||||||
blockNumbers := MakeRange(window.LowerBound, window.UpperBound)
|
blockNumbers := MakeRange(window.LowerBound, window.UpperBound)
|
||||||
RetrieveAndUpdateBlocks(bv.blockchain, bv.repository, blockNumbers)
|
RetrieveAndUpdateBlocks(bv.blockchain, bv.blockRepository, blockNumbers)
|
||||||
lastBlock := bv.blockchain.LastBlock().Int64()
|
lastBlock := bv.blockchain.LastBlock().Int64()
|
||||||
bv.repository.SetBlocksStatus(lastBlock)
|
bv.blockRepository.SetBlocksStatus(lastBlock)
|
||||||
return window
|
return window
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,23 +47,26 @@ var _ = Describe("Blocks validator", func() {
|
|||||||
{Number: 6},
|
{Number: 6},
|
||||||
{Number: 7},
|
{Number: 7},
|
||||||
})
|
})
|
||||||
repository := inmemory.NewInMemory()
|
inMemoryDB := inmemory.NewInMemory()
|
||||||
|
blocksRepository := &inmemory.BlockRepository{InMemory: inMemoryDB}
|
||||||
|
|
||||||
validator := history.NewBlockValidator(blockchain, repository, 2)
|
validator := history.NewBlockValidator(blockchain, blocksRepository, 2)
|
||||||
window := validator.ValidateBlocks()
|
window := validator.ValidateBlocks()
|
||||||
Expect(window).To(Equal(history.ValidationWindow{LowerBound: 5, UpperBound: 7}))
|
Expect(window).To(Equal(history.ValidationWindow{LowerBound: 5, UpperBound: 7}))
|
||||||
Expect(repository.BlockCount()).To(Equal(2))
|
Expect(blocksRepository.BlockCount()).To(Equal(2))
|
||||||
Expect(repository.CreateOrUpdateBlockCallCount).To(Equal(2))
|
Expect(blocksRepository.CreateOrUpdateBlockCallCount).To(Equal(2))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("logs window message", func() {
|
It("logs window message", func() {
|
||||||
|
inMemoryDB := inmemory.NewInMemory()
|
||||||
|
blockRepository := &inmemory.BlockRepository{InMemory: inMemoryDB}
|
||||||
|
|
||||||
expectedMessage := &bytes.Buffer{}
|
expectedMessage := &bytes.Buffer{}
|
||||||
window := history.ValidationWindow{LowerBound: 5, UpperBound: 7}
|
window := history.ValidationWindow{LowerBound: 5, UpperBound: 7}
|
||||||
history.ParsedWindowTemplate.Execute(expectedMessage, history.ValidationWindow{LowerBound: 5, UpperBound: 7})
|
history.ParsedWindowTemplate.Execute(expectedMessage, history.ValidationWindow{LowerBound: 5, UpperBound: 7})
|
||||||
|
|
||||||
blockchain := fakes.NewBlockchainWithBlocks([]core.Block{})
|
blockchain := fakes.NewBlockchainWithBlocks([]core.Block{})
|
||||||
repository := inmemory.NewInMemory()
|
validator := history.NewBlockValidator(blockchain, blockRepository, 2)
|
||||||
validator := history.NewBlockValidator(blockchain, repository, 2)
|
|
||||||
actualMessage := &bytes.Buffer{}
|
actualMessage := &bytes.Buffer{}
|
||||||
validator.Log(actualMessage, window)
|
validator.Log(actualMessage, window)
|
||||||
Expect(actualMessage).To(Equal(expectedMessage))
|
Expect(actualMessage).To(Equal(expectedMessage))
|
||||||
|
51
pkg/repositories/inmemory/block_repository.go
Normal file
51
pkg/repositories/inmemory/block_repository.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package inmemory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BlockRepository struct {
|
||||||
|
*InMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blockRepository *BlockRepository) CreateOrUpdateBlock(block core.Block) error {
|
||||||
|
blockRepository.CreateOrUpdateBlockCallCount++
|
||||||
|
blockRepository.blocks[block.Number] = block
|
||||||
|
for _, transaction := range block.Transactions {
|
||||||
|
blockRepository.receipts[transaction.Hash] = transaction.Receipt
|
||||||
|
blockRepository.logs[transaction.TxHash] = transaction.Logs
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blockRepository *BlockRepository) GetBlock(blockNumber int64) (core.Block, error) {
|
||||||
|
if block, ok := blockRepository.blocks[blockNumber]; ok {
|
||||||
|
return block, nil
|
||||||
|
}
|
||||||
|
return core.Block{}, repositories.ErrBlockDoesNotExist(blockNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blockRepository *BlockRepository) MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64) []int64 {
|
||||||
|
missingNumbers := []int64{}
|
||||||
|
for blockNumber := int64(startingBlockNumber); blockNumber <= endingBlockNumber; blockNumber++ {
|
||||||
|
if _, ok := blockRepository.blocks[blockNumber]; !ok {
|
||||||
|
missingNumbers = append(missingNumbers, blockNumber)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return missingNumbers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blockRepository *BlockRepository) SetBlocksStatus(chainHead int64) {
|
||||||
|
for key, block := range blockRepository.blocks {
|
||||||
|
if key < (chainHead - blocksFromHeadBeforeFinal) {
|
||||||
|
tmp := block
|
||||||
|
tmp.IsFinal = true
|
||||||
|
blockRepository.blocks[key] = tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blockRepository *BlockRepository) BlockCount() int {
|
||||||
|
return len(blockRepository.blocks)
|
||||||
|
}
|
35
pkg/repositories/inmemory/contract_repository.go
Normal file
35
pkg/repositories/inmemory/contract_repository.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package inmemory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ContractRepostiory struct {
|
||||||
|
*InMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
func (contractRepository *ContractRepostiory) ContractExists(contractHash string) bool {
|
||||||
|
_, present := contractRepository.contracts[contractHash]
|
||||||
|
return present
|
||||||
|
}
|
||||||
|
|
||||||
|
func (contractRepository *ContractRepostiory) GetContract(contractHash string) (core.Contract, error) {
|
||||||
|
contract, ok := contractRepository.contracts[contractHash]
|
||||||
|
if !ok {
|
||||||
|
return core.Contract{}, repositories.ErrContractDoesNotExist(contractHash)
|
||||||
|
}
|
||||||
|
for _, block := range contractRepository.blocks {
|
||||||
|
for _, transaction := range block.Transactions {
|
||||||
|
if transaction.To == contractHash {
|
||||||
|
contract.Transactions = append(contract.Transactions, transaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contract, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (contractRepository *ContractRepostiory) CreateContract(contract core.Contract) error {
|
||||||
|
contractRepository.contracts[contract.Hash] = contract
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,13 +1,8 @@
|
|||||||
package inmemory
|
package inmemory
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -23,23 +18,6 @@ type InMemory struct {
|
|||||||
CreateOrUpdateBlockCallCount int
|
CreateOrUpdateBlockCallCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repository *InMemory) GetWatchedEvents(name string) ([]*core.WatchedEvent, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) GetFilter(name string) (filters.LogFilter, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) CreateFilter(filter filters.LogFilter) error {
|
|
||||||
key := filter.Name
|
|
||||||
if _, ok := repository.logFilters[key]; ok || key == "" {
|
|
||||||
return errors.New("filter name not unique")
|
|
||||||
}
|
|
||||||
repository.logFilters[key] = filter
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewInMemory() *InMemory {
|
func NewInMemory() *InMemory {
|
||||||
return &InMemory{
|
return &InMemory{
|
||||||
CreateOrUpdateBlockCallCount: 0,
|
CreateOrUpdateBlockCallCount: 0,
|
||||||
@ -50,107 +28,3 @@ func NewInMemory() *InMemory {
|
|||||||
logFilters: make(map[string]filters.LogFilter),
|
logFilters: make(map[string]filters.LogFilter),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repository *InMemory) GetReceipt(txHash string) (core.Receipt, error) {
|
|
||||||
if receipt, ok := repository.receipts[txHash]; ok {
|
|
||||||
return receipt, nil
|
|
||||||
}
|
|
||||||
return core.Receipt{}, repositories.ErrReceiptDoesNotExist(txHash)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) SetBlocksStatus(chainHead int64) {
|
|
||||||
for key, block := range repository.blocks {
|
|
||||||
if key < (chainHead - blocksFromHeadBeforeFinal) {
|
|
||||||
tmp := block
|
|
||||||
tmp.IsFinal = true
|
|
||||||
repository.blocks[key] = tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) CreateLogs(logs []core.Log) error {
|
|
||||||
for _, log := range logs {
|
|
||||||
key := fmt.Sprintf("%d%d", log.BlockNumber, log.Index)
|
|
||||||
var logs []core.Log
|
|
||||||
repository.logs[key] = append(logs, log)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) GetLogs(address string, blockNumber int64) []core.Log {
|
|
||||||
var matchingLogs []core.Log
|
|
||||||
for _, logs := range repository.logs {
|
|
||||||
for _, log := range logs {
|
|
||||||
if log.Address == address && log.BlockNumber == blockNumber {
|
|
||||||
matchingLogs = append(matchingLogs, log)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matchingLogs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) CreateContract(contract core.Contract) error {
|
|
||||||
repository.contracts[contract.Hash] = contract
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) ContractExists(contractHash string) bool {
|
|
||||||
_, present := repository.contracts[contractHash]
|
|
||||||
return present
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) GetContract(contractHash string) (core.Contract, error) {
|
|
||||||
contract, ok := repository.contracts[contractHash]
|
|
||||||
if !ok {
|
|
||||||
return core.Contract{}, repositories.ErrContractDoesNotExist(contractHash)
|
|
||||||
}
|
|
||||||
for _, block := range repository.blocks {
|
|
||||||
for _, transaction := range block.Transactions {
|
|
||||||
if transaction.To == contractHash {
|
|
||||||
contract.Transactions = append(contract.Transactions, transaction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contract, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64) []int64 {
|
|
||||||
missingNumbers := []int64{}
|
|
||||||
for blockNumber := int64(startingBlockNumber); blockNumber <= endingBlockNumber; blockNumber++ {
|
|
||||||
if _, ok := repository.blocks[blockNumber]; !ok {
|
|
||||||
missingNumbers = append(missingNumbers, blockNumber)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return missingNumbers
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) CreateOrUpdateBlock(block core.Block) error {
|
|
||||||
repository.CreateOrUpdateBlockCallCount++
|
|
||||||
repository.blocks[block.Number] = block
|
|
||||||
for _, transaction := range block.Transactions {
|
|
||||||
repository.receipts[transaction.Hash] = transaction.Receipt
|
|
||||||
repository.logs[transaction.TxHash] = transaction.Logs
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) BlockCount() int {
|
|
||||||
return len(repository.blocks)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) GetBlock(blockNumber int64) (core.Block, error) {
|
|
||||||
if block, ok := repository.blocks[blockNumber]; ok {
|
|
||||||
return block, nil
|
|
||||||
}
|
|
||||||
return core.Block{}, repositories.ErrBlockDoesNotExist(blockNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repository *InMemory) MaxBlockNumber() int64 {
|
|
||||||
highestBlockNumber := int64(-1)
|
|
||||||
for key := range repository.blocks {
|
|
||||||
if key > highestBlockNumber {
|
|
||||||
highestBlockNumber = key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return highestBlockNumber
|
|
||||||
}
|
|
||||||
|
@ -16,35 +16,39 @@ const (
|
|||||||
blocksFromHeadBeforeFinal = 20
|
blocksFromHeadBeforeFinal = 20
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db DB) SetBlocksStatus(chainHead int64) {
|
type BlockRepository struct {
|
||||||
|
*DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blockRepository BlockRepository) SetBlocksStatus(chainHead int64) {
|
||||||
cutoff := chainHead - blocksFromHeadBeforeFinal
|
cutoff := chainHead - blocksFromHeadBeforeFinal
|
||||||
db.DB.Exec(`
|
blockRepository.DB.Exec(`
|
||||||
UPDATE blocks SET is_final = TRUE
|
UPDATE blocks SET is_final = TRUE
|
||||||
WHERE is_final = FALSE AND number < $1`,
|
WHERE is_final = FALSE AND number < $1`,
|
||||||
cutoff)
|
cutoff)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) CreateOrUpdateBlock(block core.Block) error {
|
func (blockRepository BlockRepository) CreateOrUpdateBlock(block core.Block) error {
|
||||||
var err error
|
var err error
|
||||||
retrievedBlockHash, ok := db.getBlockHash(block)
|
retrievedBlockHash, ok := blockRepository.getBlockHash(block)
|
||||||
if !ok {
|
if !ok {
|
||||||
err = db.insertBlock(block)
|
err = blockRepository.insertBlock(block)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if ok && retrievedBlockHash != block.Hash {
|
if ok && retrievedBlockHash != block.Hash {
|
||||||
err = db.removeBlock(block.Number)
|
err = blockRepository.removeBlock(block.Number)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = db.insertBlock(block)
|
err = blockRepository.insertBlock(block)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) MissingBlockNumbers(startingBlockNumber int64, highestBlockNumber int64) []int64 {
|
func (blockRepository BlockRepository) MissingBlockNumbers(startingBlockNumber int64, highestBlockNumber int64) []int64 {
|
||||||
numbers := make([]int64, 0)
|
numbers := make([]int64, 0)
|
||||||
db.DB.Select(&numbers,
|
blockRepository.DB.Select(&numbers,
|
||||||
`SELECT all_block_numbers
|
`SELECT all_block_numbers
|
||||||
FROM (
|
FROM (
|
||||||
SELECT generate_series($1::INT, $2::INT) AS all_block_numbers) series
|
SELECT generate_series($1::INT, $2::INT) AS all_block_numbers) series
|
||||||
@ -56,8 +60,8 @@ func (db DB) MissingBlockNumbers(startingBlockNumber int64, highestBlockNumber i
|
|||||||
return numbers
|
return numbers
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) GetBlock(blockNumber int64) (core.Block, error) {
|
func (blockRepository BlockRepository) GetBlock(blockNumber int64) (core.Block, error) {
|
||||||
blockRows := db.DB.QueryRowx(
|
blockRows := blockRepository.DB.QueryRowx(
|
||||||
`SELECT id,
|
`SELECT id,
|
||||||
number,
|
number,
|
||||||
gaslimit,
|
gaslimit,
|
||||||
@ -75,8 +79,8 @@ func (db DB) GetBlock(blockNumber int64) (core.Block, error) {
|
|||||||
reward,
|
reward,
|
||||||
uncles_reward
|
uncles_reward
|
||||||
FROM blocks
|
FROM blocks
|
||||||
WHERE node_id = $1 AND number = $2`, db.nodeId, blockNumber)
|
WHERE node_id = $1 AND number = $2`, blockRepository.nodeId, blockNumber)
|
||||||
savedBlock, err := db.loadBlock(blockRows)
|
savedBlock, err := blockRepository.loadBlock(blockRows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err {
|
switch err {
|
||||||
case sql.ErrNoRows:
|
case sql.ErrNoRows:
|
||||||
@ -88,21 +92,21 @@ func (db DB) GetBlock(blockNumber int64) (core.Block, error) {
|
|||||||
return savedBlock, nil
|
return savedBlock, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) insertBlock(block core.Block) error {
|
func (blockRepository BlockRepository) insertBlock(block core.Block) error {
|
||||||
var blockId int64
|
var blockId int64
|
||||||
tx, _ := db.DB.BeginTx(context.Background(), nil)
|
tx, _ := blockRepository.DB.BeginTx(context.Background(), nil)
|
||||||
err := tx.QueryRow(
|
err := tx.QueryRow(
|
||||||
`INSERT INTO blocks
|
`INSERT INTO blocks
|
||||||
(node_id, number, gaslimit, gasused, time, difficulty, hash, nonce, parenthash, size, uncle_hash, is_final, miner, extra_data, reward, uncles_reward)
|
(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)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||||
RETURNING id `,
|
RETURNING id `,
|
||||||
db.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)
|
Scan(&blockId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return ErrDBInsertFailed
|
return ErrDBInsertFailed
|
||||||
}
|
}
|
||||||
err = db.createTransactions(tx, blockId, block.Transactions)
|
err = blockRepository.createTransactions(tx, blockId, block.Transactions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return ErrDBInsertFailed
|
return ErrDBInsertFailed
|
||||||
@ -111,9 +115,9 @@ func (db DB) insertBlock(block core.Block) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) createTransactions(tx *sql.Tx, blockId int64, transactions []core.Transaction) error {
|
func (blockRepository BlockRepository) createTransactions(tx *sql.Tx, blockId int64, transactions []core.Transaction) error {
|
||||||
for _, transaction := range transactions {
|
for _, transaction := range transactions {
|
||||||
err := db.createTransaction(tx, blockId, transaction)
|
err := blockRepository.createTransaction(tx, blockId, transaction)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -131,7 +135,7 @@ func nullStringToZero(s string) string {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) createTransaction(tx *sql.Tx, blockId int64, transaction core.Transaction) error {
|
func (blockRepository BlockRepository) createTransaction(tx *sql.Tx, blockId int64, transaction core.Transaction) error {
|
||||||
var transactionId int
|
var transactionId int
|
||||||
err := tx.QueryRow(
|
err := tx.QueryRow(
|
||||||
`INSERT INTO transactions
|
`INSERT INTO transactions
|
||||||
@ -144,12 +148,12 @@ func (db DB) createTransaction(tx *sql.Tx, blockId int64, transaction core.Trans
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if hasReceipt(transaction) {
|
if hasReceipt(transaction) {
|
||||||
receiptId, err := db.createReceipt(tx, transactionId, transaction.Receipt)
|
receiptId, err := blockRepository.createReceipt(tx, transactionId, transaction.Receipt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if hasLogs(transaction) {
|
if hasLogs(transaction) {
|
||||||
err = db.createLogs(tx, transaction.Receipt.Logs, receiptId)
|
err = blockRepository.createLogs(tx, transaction.Receipt.Logs, receiptId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -166,7 +170,7 @@ func hasReceipt(transaction core.Transaction) bool {
|
|||||||
return transaction.Receipt.TxHash != ""
|
return transaction.Receipt.TxHash != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) createReceipt(tx *sql.Tx, transactionId int, receipt core.Receipt) (int, error) {
|
func (blockRepository BlockRepository) createReceipt(tx *sql.Tx, transactionId int, receipt core.Receipt) (int, error) {
|
||||||
//Not currently persisting log bloom filters
|
//Not currently persisting log bloom filters
|
||||||
var receiptId int
|
var receiptId int
|
||||||
err := tx.QueryRow(
|
err := tx.QueryRow(
|
||||||
@ -181,17 +185,17 @@ func (db DB) createReceipt(tx *sql.Tx, transactionId int, receipt core.Receipt)
|
|||||||
return receiptId, nil
|
return receiptId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) getBlockHash(block core.Block) (string, bool) {
|
func (blockRepository BlockRepository) getBlockHash(block core.Block) (string, bool) {
|
||||||
var retrievedBlockHash string
|
var retrievedBlockHash string
|
||||||
db.DB.Get(&retrievedBlockHash,
|
blockRepository.DB.Get(&retrievedBlockHash,
|
||||||
`SELECT hash
|
`SELECT hash
|
||||||
FROM blocks
|
FROM blocks
|
||||||
WHERE number = $1 AND node_id = $2`,
|
WHERE number = $1 AND node_id = $2`,
|
||||||
block.Number, db.nodeId)
|
block.Number, blockRepository.nodeId)
|
||||||
return retrievedBlockHash, blockExists(retrievedBlockHash)
|
return retrievedBlockHash, blockExists(retrievedBlockHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) createLogs(tx *sql.Tx, logs []core.Log, receiptId int) error {
|
func (blockRepository BlockRepository) createLogs(tx *sql.Tx, logs []core.Log, receiptId int) error {
|
||||||
for _, tlog := range logs {
|
for _, tlog := range logs {
|
||||||
_, err := tx.Exec(
|
_, err := tx.Exec(
|
||||||
`INSERT INTO logs (block_number, address, tx_hash, index, topic0, topic1, topic2, topic3, data, receipt_id)
|
`INSERT INTO logs (block_number, address, tx_hash, index, topic0, topic1, topic2, topic3, data, receipt_id)
|
||||||
@ -210,19 +214,19 @@ func blockExists(retrievedBlockHash string) bool {
|
|||||||
return retrievedBlockHash != ""
|
return retrievedBlockHash != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) removeBlock(blockNumber int64) error {
|
func (blockRepository BlockRepository) removeBlock(blockNumber int64) error {
|
||||||
_, err := db.DB.Exec(
|
_, err := blockRepository.DB.Exec(
|
||||||
`DELETE FROM
|
`DELETE FROM
|
||||||
blocks
|
blocks
|
||||||
WHERE number=$1 AND node_id=$2`,
|
WHERE number=$1 AND node_id=$2`,
|
||||||
blockNumber, db.nodeId)
|
blockNumber, blockRepository.nodeId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrDBDeleteFailed
|
return ErrDBDeleteFailed
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) loadBlock(blockRows *sqlx.Row) (core.Block, error) {
|
func (blockRepository BlockRepository) loadBlock(blockRows *sqlx.Row) (core.Block, error) {
|
||||||
type b struct {
|
type b struct {
|
||||||
ID int
|
ID int
|
||||||
core.Block
|
core.Block
|
||||||
@ -232,7 +236,7 @@ func (db DB) loadBlock(blockRows *sqlx.Row) (core.Block, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return core.Block{}, err
|
return core.Block{}, err
|
||||||
}
|
}
|
||||||
transactionRows, err := db.DB.Queryx(`
|
transactionRows, err := blockRepository.DB.Queryx(`
|
||||||
SELECT hash,
|
SELECT hash,
|
||||||
nonce,
|
nonce,
|
||||||
tx_to,
|
tx_to,
|
||||||
@ -247,11 +251,11 @@ func (db DB) loadBlock(blockRows *sqlx.Row) (core.Block, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return core.Block{}, err
|
return core.Block{}, err
|
||||||
}
|
}
|
||||||
block.Transactions = db.loadTransactions(transactionRows)
|
block.Transactions = blockRepository.LoadTransactions(transactionRows)
|
||||||
return block.Block, nil
|
return block.Block, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) loadTransactions(transactionRows *sqlx.Rows) []core.Transaction {
|
func (blockRepository BlockRepository) LoadTransactions(transactionRows *sqlx.Rows) []core.Transaction {
|
||||||
var transactions []core.Transaction
|
var transactions []core.Transaction
|
||||||
for transactionRows.Next() {
|
for transactionRows.Next() {
|
||||||
var transaction core.Transaction
|
var transaction core.Transaction
|
||||||
|
@ -12,7 +12,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Saving blocks", func() {
|
var _ = Describe("Saving blocks", func() {
|
||||||
var repository repositories.BlockRepository
|
var db *postgres.DB
|
||||||
|
var blockRepository repositories.BlockRepository
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
node := core.Node{
|
node := core.Node{
|
||||||
GenesisBlock: "GENESIS",
|
GenesisBlock: "GENESIS",
|
||||||
@ -20,21 +21,24 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
repository = postgres.BuildRepository(node)
|
db = postgres.NewTestDB(node)
|
||||||
|
blockRepository = postgres.BlockRepository{DB: db}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("associates blocks to a node", func() {
|
It("associates blocks to a node", func() {
|
||||||
block := core.Block{
|
block := core.Block{
|
||||||
Number: 123,
|
Number: 123,
|
||||||
}
|
}
|
||||||
repository.CreateOrUpdateBlock(block)
|
blockRepository.CreateOrUpdateBlock(block)
|
||||||
nodeTwo := core.Node{
|
nodeTwo := core.Node{
|
||||||
GenesisBlock: "0x456",
|
GenesisBlock: "0x456",
|
||||||
NetworkId: 1,
|
NetworkId: 1,
|
||||||
Id: "x123456",
|
Id: "x123456",
|
||||||
ClientName: "Geth",
|
ClientName: "Geth",
|
||||||
}
|
}
|
||||||
repositoryTwo := postgres.BuildRepository(nodeTwo)
|
dbTwo := postgres.NewTestDB(nodeTwo)
|
||||||
|
repositoryTwo := postgres.BlockRepository{DB: dbTwo}
|
||||||
|
|
||||||
_, err := repositoryTwo.GetBlock(123)
|
_, err := repositoryTwo.GetBlock(123)
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
@ -72,9 +76,9 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
UnclesReward: unclesReward,
|
UnclesReward: unclesReward,
|
||||||
}
|
}
|
||||||
|
|
||||||
repository.CreateOrUpdateBlock(block)
|
blockRepository.CreateOrUpdateBlock(block)
|
||||||
|
|
||||||
savedBlock, err := repository.GetBlock(blockNumber)
|
savedBlock, err := blockRepository.GetBlock(blockNumber)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(savedBlock.Reward).To(Equal(blockReward))
|
Expect(savedBlock.Reward).To(Equal(blockReward))
|
||||||
Expect(savedBlock.Difficulty).To(Equal(difficulty))
|
Expect(savedBlock.Difficulty).To(Equal(difficulty))
|
||||||
@ -93,7 +97,7 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("does not find a block when searching for a number that does not exist", func() {
|
It("does not find a block when searching for a number that does not exist", func() {
|
||||||
_, err := repository.GetBlock(111)
|
_, err := blockRepository.GetBlock(111)
|
||||||
|
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
})
|
})
|
||||||
@ -104,9 +108,9 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
Transactions: []core.Transaction{{}},
|
Transactions: []core.Transaction{{}},
|
||||||
}
|
}
|
||||||
|
|
||||||
repository.CreateOrUpdateBlock(block)
|
blockRepository.CreateOrUpdateBlock(block)
|
||||||
|
|
||||||
savedBlock, _ := repository.GetBlock(123)
|
savedBlock, _ := blockRepository.GetBlock(123)
|
||||||
Expect(len(savedBlock.Transactions)).To(Equal(1))
|
Expect(len(savedBlock.Transactions)).To(Equal(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -116,9 +120,9 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
Transactions: []core.Transaction{{}, {}},
|
Transactions: []core.Transaction{{}, {}},
|
||||||
}
|
}
|
||||||
|
|
||||||
repository.CreateOrUpdateBlock(block)
|
blockRepository.CreateOrUpdateBlock(block)
|
||||||
|
|
||||||
savedBlock, _ := repository.GetBlock(123)
|
savedBlock, _ := blockRepository.GetBlock(123)
|
||||||
Expect(len(savedBlock.Transactions)).To(Equal(2))
|
Expect(len(savedBlock.Transactions)).To(Equal(2))
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -135,10 +139,10 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
Transactions: []core.Transaction{{Hash: "x678"}, {Hash: "x9ab"}},
|
Transactions: []core.Transaction{{Hash: "x678"}, {Hash: "x9ab"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
repository.CreateOrUpdateBlock(blockOne)
|
blockRepository.CreateOrUpdateBlock(blockOne)
|
||||||
repository.CreateOrUpdateBlock(blockTwo)
|
blockRepository.CreateOrUpdateBlock(blockTwo)
|
||||||
|
|
||||||
savedBlock, _ := repository.GetBlock(123)
|
savedBlock, _ := blockRepository.GetBlock(123)
|
||||||
Expect(len(savedBlock.Transactions)).To(Equal(2))
|
Expect(len(savedBlock.Transactions)).To(Equal(2))
|
||||||
Expect(savedBlock.Transactions[0].Hash).To(Equal("x678"))
|
Expect(savedBlock.Transactions[0].Hash).To(Equal("x678"))
|
||||||
Expect(savedBlock.Transactions[1].Hash).To(Equal("x9ab"))
|
Expect(savedBlock.Transactions[1].Hash).To(Equal("x9ab"))
|
||||||
@ -154,16 +158,17 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
Number: 123,
|
Number: 123,
|
||||||
Transactions: []core.Transaction{{Hash: "x678"}, {Hash: "x9ab"}},
|
Transactions: []core.Transaction{{Hash: "x678"}, {Hash: "x9ab"}},
|
||||||
}
|
}
|
||||||
repository.CreateOrUpdateBlock(blockOne)
|
blockRepository.CreateOrUpdateBlock(blockOne)
|
||||||
nodeTwo := core.Node{
|
nodeTwo := core.Node{
|
||||||
GenesisBlock: "0x456",
|
GenesisBlock: "0x456",
|
||||||
NetworkId: 1,
|
NetworkId: 1,
|
||||||
}
|
}
|
||||||
repositoryTwo := postgres.BuildRepository(nodeTwo)
|
dbTwo := postgres.NewTestDB(nodeTwo)
|
||||||
|
repositoryTwo := postgres.BlockRepository{DB: dbTwo}
|
||||||
|
|
||||||
repository.CreateOrUpdateBlock(blockOne)
|
blockRepository.CreateOrUpdateBlock(blockOne)
|
||||||
repositoryTwo.CreateOrUpdateBlock(blockTwo)
|
repositoryTwo.CreateOrUpdateBlock(blockTwo)
|
||||||
retrievedBlockOne, _ := repository.GetBlock(123)
|
retrievedBlockOne, _ := blockRepository.GetBlock(123)
|
||||||
retrievedBlockTwo, _ := repositoryTwo.GetBlock(123)
|
retrievedBlockTwo, _ := repositoryTwo.GetBlock(123)
|
||||||
|
|
||||||
Expect(retrievedBlockOne.Transactions[0].Hash).To(Equal("x123"))
|
Expect(retrievedBlockOne.Transactions[0].Hash).To(Equal("x123"))
|
||||||
@ -194,9 +199,9 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
Transactions: []core.Transaction{transaction},
|
Transactions: []core.Transaction{transaction},
|
||||||
}
|
}
|
||||||
|
|
||||||
repository.CreateOrUpdateBlock(block)
|
blockRepository.CreateOrUpdateBlock(block)
|
||||||
|
|
||||||
savedBlock, _ := repository.GetBlock(123)
|
savedBlock, _ := blockRepository.GetBlock(123)
|
||||||
Expect(len(savedBlock.Transactions)).To(Equal(1))
|
Expect(len(savedBlock.Transactions)).To(Equal(1))
|
||||||
savedTransaction := savedBlock.Transactions[0]
|
savedTransaction := savedBlock.Transactions[0]
|
||||||
Expect(savedTransaction.Data).To(Equal(transaction.Data))
|
Expect(savedTransaction.Data).To(Equal(transaction.Data))
|
||||||
@ -211,54 +216,54 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
|
|
||||||
Describe("The missing block numbers", func() {
|
Describe("The missing block numbers", func() {
|
||||||
It("is empty the starting block number is the highest known block number", func() {
|
It("is empty the starting block number is the highest known block number", func() {
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 1})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 1})
|
||||||
|
|
||||||
Expect(len(repository.MissingBlockNumbers(1, 1))).To(Equal(0))
|
Expect(len(blockRepository.MissingBlockNumbers(1, 1))).To(Equal(0))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("is the only missing block number", func() {
|
It("is the only missing block number", func() {
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 2})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 2})
|
||||||
|
|
||||||
Expect(repository.MissingBlockNumbers(1, 2)).To(Equal([]int64{1}))
|
Expect(blockRepository.MissingBlockNumbers(1, 2)).To(Equal([]int64{1}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("is both missing block numbers", func() {
|
It("is both missing block numbers", func() {
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 3})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 3})
|
||||||
|
|
||||||
Expect(repository.MissingBlockNumbers(1, 3)).To(Equal([]int64{1, 2}))
|
Expect(blockRepository.MissingBlockNumbers(1, 3)).To(Equal([]int64{1, 2}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("goes back to the starting block number", func() {
|
It("goes back to the starting block number", func() {
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 6})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 6})
|
||||||
|
|
||||||
Expect(repository.MissingBlockNumbers(4, 6)).To(Equal([]int64{4, 5}))
|
Expect(blockRepository.MissingBlockNumbers(4, 6)).To(Equal([]int64{4, 5}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("only includes missing block numbers", func() {
|
It("only includes missing block numbers", func() {
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 4})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 4})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 6})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 6})
|
||||||
|
|
||||||
Expect(repository.MissingBlockNumbers(4, 6)).To(Equal([]int64{5}))
|
Expect(blockRepository.MissingBlockNumbers(4, 6)).To(Equal([]int64{5}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("is a list with multiple gaps", func() {
|
It("is a list with multiple gaps", func() {
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 4})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 4})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 5})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 5})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 8})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 8})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 10})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 10})
|
||||||
|
|
||||||
Expect(repository.MissingBlockNumbers(3, 10)).To(Equal([]int64{3, 6, 7, 9}))
|
Expect(blockRepository.MissingBlockNumbers(3, 10)).To(Equal([]int64{3, 6, 7, 9}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns empty array when lower bound exceeds upper bound", func() {
|
It("returns empty array when lower bound exceeds upper bound", func() {
|
||||||
Expect(repository.MissingBlockNumbers(10000, 1)).To(Equal([]int64{}))
|
Expect(blockRepository.MissingBlockNumbers(10000, 1)).To(Equal([]int64{}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("only returns requested range even when other gaps exist", func() {
|
It("only returns requested range even when other gaps exist", func() {
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 3})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 3})
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: 8})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: 8})
|
||||||
|
|
||||||
Expect(repository.MissingBlockNumbers(1, 5)).To(Equal([]int64{1, 2, 4, 5}))
|
Expect(blockRepository.MissingBlockNumbers(1, 5)).To(Equal([]int64{1, 2, 4, 5}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -266,15 +271,15 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
It("sets the status of blocks within n-20 of chain HEAD as final", func() {
|
It("sets the status of blocks within n-20 of chain HEAD as final", func() {
|
||||||
blockNumberOfChainHead := 25
|
blockNumberOfChainHead := 25
|
||||||
for i := 0; i < blockNumberOfChainHead; i++ {
|
for i := 0; i < blockNumberOfChainHead; i++ {
|
||||||
repository.CreateOrUpdateBlock(core.Block{Number: int64(i), Hash: strconv.Itoa(i)})
|
blockRepository.CreateOrUpdateBlock(core.Block{Number: int64(i), Hash: strconv.Itoa(i)})
|
||||||
}
|
}
|
||||||
|
|
||||||
repository.SetBlocksStatus(int64(blockNumberOfChainHead))
|
blockRepository.SetBlocksStatus(int64(blockNumberOfChainHead))
|
||||||
|
|
||||||
blockOne, err := repository.GetBlock(1)
|
blockOne, err := blockRepository.GetBlock(1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(blockOne.IsFinal).To(Equal(true))
|
Expect(blockOne.IsFinal).To(Equal(true))
|
||||||
blockTwo, err := repository.GetBlock(24)
|
blockTwo, err := blockRepository.GetBlock(24)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(blockTwo.IsFinal).To(BeFalse())
|
Expect(blockTwo.IsFinal).To(BeFalse())
|
||||||
})
|
})
|
||||||
|
@ -7,13 +7,17 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db DB) CreateContract(contract core.Contract) error {
|
type ContractRepository struct {
|
||||||
|
*DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (contractRepository ContractRepository) CreateContract(contract core.Contract) error {
|
||||||
abi := contract.Abi
|
abi := contract.Abi
|
||||||
var abiToInsert *string
|
var abiToInsert *string
|
||||||
if abi != "" {
|
if abi != "" {
|
||||||
abiToInsert = &abi
|
abiToInsert = &abi
|
||||||
}
|
}
|
||||||
_, err := db.DB.Exec(
|
_, err := contractRepository.DB.Exec(
|
||||||
`INSERT INTO watched_contracts (contract_hash, contract_abi)
|
`INSERT INTO watched_contracts (contract_hash, contract_abi)
|
||||||
VALUES ($1, $2)
|
VALUES ($1, $2)
|
||||||
ON CONFLICT (contract_hash)
|
ON CONFLICT (contract_hash)
|
||||||
@ -26,9 +30,9 @@ func (db DB) CreateContract(contract core.Contract) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) ContractExists(contractHash string) bool {
|
func (contractRepository ContractRepository) ContractExists(contractHash string) bool {
|
||||||
var exists bool
|
var exists bool
|
||||||
db.DB.QueryRow(
|
contractRepository.DB.QueryRow(
|
||||||
`SELECT exists(
|
`SELECT exists(
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM watched_contracts
|
FROM watched_contracts
|
||||||
@ -36,21 +40,21 @@ func (db DB) ContractExists(contractHash string) bool {
|
|||||||
return exists
|
return exists
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) GetContract(contractHash string) (core.Contract, error) {
|
func (contractRepository ContractRepository) GetContract(contractHash string) (core.Contract, error) {
|
||||||
var hash string
|
var hash string
|
||||||
var abi string
|
var abi string
|
||||||
contract := db.DB.QueryRow(
|
contract := contractRepository.DB.QueryRow(
|
||||||
`SELECT contract_hash, contract_abi FROM watched_contracts WHERE contract_hash=$1`, contractHash)
|
`SELECT contract_hash, contract_abi FROM watched_contracts WHERE contract_hash=$1`, contractHash)
|
||||||
err := contract.Scan(&hash, &abi)
|
err := contract.Scan(&hash, &abi)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return core.Contract{}, repositories.ErrContractDoesNotExist(contractHash)
|
return core.Contract{}, repositories.ErrContractDoesNotExist(contractHash)
|
||||||
}
|
}
|
||||||
savedContract := db.addTransactions(core.Contract{Hash: hash, Abi: abi})
|
savedContract := contractRepository.addTransactions(core.Contract{Hash: hash, Abi: abi})
|
||||||
return savedContract, nil
|
return savedContract, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) addTransactions(contract core.Contract) core.Contract {
|
func (contractRepository ContractRepository) addTransactions(contract core.Contract) core.Contract {
|
||||||
transactionRows, _ := db.DB.Queryx(`
|
transactionRows, _ := contractRepository.DB.Queryx(`
|
||||||
SELECT hash,
|
SELECT hash,
|
||||||
nonce,
|
nonce,
|
||||||
tx_to,
|
tx_to,
|
||||||
@ -62,7 +66,8 @@ func (db DB) addTransactions(contract core.Contract) core.Contract {
|
|||||||
FROM transactions
|
FROM transactions
|
||||||
WHERE tx_to = $1
|
WHERE tx_to = $1
|
||||||
ORDER BY block_id DESC`, contract.Hash)
|
ORDER BY block_id DESC`, contract.Hash)
|
||||||
transactions := db.loadTransactions(transactionRows)
|
blockRepository := &BlockRepository{contractRepository.DB}
|
||||||
|
transactions := blockRepository.LoadTransactions(transactionRows)
|
||||||
savedContract := core.Contract{Hash: contract.Hash, Transactions: transactions, Abi: contract.Abi}
|
savedContract := core.Contract{Hash: contract.Hash, Transactions: transactions, Abi: contract.Abi}
|
||||||
return savedContract
|
return savedContract
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package postgres
|
package postgres_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
@ -7,11 +7,14 @@ import (
|
|||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Creating contracts", func() {
|
var _ = Describe("Creating contracts", func() {
|
||||||
var repository repositories.ContractRepository
|
var db *postgres.DB
|
||||||
|
var contractRepository repositories.ContractRepository
|
||||||
var node core.Node
|
var node core.Node
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
node = core.Node{
|
node = core.Node{
|
||||||
GenesisBlock: "GENESIS",
|
GenesisBlock: "GENESIS",
|
||||||
@ -19,35 +22,36 @@ var _ = Describe("Creating contracts", func() {
|
|||||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
repository = BuildRepository(node)
|
db = postgres.NewTestDB(node)
|
||||||
|
contractRepository = postgres.ContractRepository{DB: db}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns the contract when it exists", func() {
|
It("returns the contract when it exists", func() {
|
||||||
repository.CreateContract(core.Contract{Hash: "x123"})
|
contractRepository.CreateContract(core.Contract{Hash: "x123"})
|
||||||
|
|
||||||
contract, err := repository.GetContract("x123")
|
contract, err := contractRepository.GetContract("x123")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(contract.Hash).To(Equal("x123"))
|
Expect(contract.Hash).To(Equal("x123"))
|
||||||
|
|
||||||
Expect(repository.ContractExists("x123")).To(BeTrue())
|
Expect(contractRepository.ContractExists("x123")).To(BeTrue())
|
||||||
Expect(repository.ContractExists("x456")).To(BeFalse())
|
Expect(contractRepository.ContractExists("x456")).To(BeFalse())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns err if contract does not exist", func() {
|
It("returns err if contract does not exist", func() {
|
||||||
_, err := repository.GetContract("x123")
|
_, err := contractRepository.GetContract("x123")
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns empty array when no transactions 'To' a contract", func() {
|
It("returns empty array when no transactions 'To' a contract", func() {
|
||||||
repository.CreateContract(core.Contract{Hash: "x123"})
|
contractRepository.CreateContract(core.Contract{Hash: "x123"})
|
||||||
contract, err := repository.GetContract("x123")
|
contract, err := contractRepository.GetContract("x123")
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(contract.Transactions).To(BeEmpty())
|
Expect(contract.Transactions).To(BeEmpty())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns transactions 'To' a contract", func() {
|
It("returns transactions 'To' a contract", func() {
|
||||||
var blockRepository repositories.BlockRepository
|
var blockRepository repositories.BlockRepository
|
||||||
blockRepository = BuildRepository(node)
|
blockRepository = postgres.BlockRepository{DB: db}
|
||||||
block := core.Block{
|
block := core.Block{
|
||||||
Number: 123,
|
Number: 123,
|
||||||
Transactions: []core.Transaction{
|
Transactions: []core.Transaction{
|
||||||
@ -58,8 +62,8 @@ var _ = Describe("Creating contracts", func() {
|
|||||||
}
|
}
|
||||||
blockRepository.CreateOrUpdateBlock(block)
|
blockRepository.CreateOrUpdateBlock(block)
|
||||||
|
|
||||||
repository.CreateContract(core.Contract{Hash: "x123"})
|
contractRepository.CreateContract(core.Contract{Hash: "x123"})
|
||||||
contract, err := repository.GetContract("x123")
|
contract, err := contractRepository.GetContract("x123")
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
sort.Slice(contract.Transactions, func(i, j int) bool {
|
sort.Slice(contract.Transactions, func(i, j int) bool {
|
||||||
return contract.Transactions[i].Hash < contract.Transactions[j].Hash
|
return contract.Transactions[i].Hash < contract.Transactions[j].Hash
|
||||||
@ -72,25 +76,25 @@ var _ = Describe("Creating contracts", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("stores the ABI of the contract", func() {
|
It("stores the ABI of the contract", func() {
|
||||||
repository.CreateContract(core.Contract{
|
contractRepository.CreateContract(core.Contract{
|
||||||
Abi: "{\"some\": \"json\"}",
|
Abi: "{\"some\": \"json\"}",
|
||||||
Hash: "x123",
|
Hash: "x123",
|
||||||
})
|
})
|
||||||
contract, err := repository.GetContract("x123")
|
contract, err := contractRepository.GetContract("x123")
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(contract.Abi).To(Equal("{\"some\": \"json\"}"))
|
Expect(contract.Abi).To(Equal("{\"some\": \"json\"}"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("updates the ABI of the contract if hash already present", func() {
|
It("updates the ABI of the contract if hash already present", func() {
|
||||||
repository.CreateContract(core.Contract{
|
contractRepository.CreateContract(core.Contract{
|
||||||
Abi: "{\"some\": \"json\"}",
|
Abi: "{\"some\": \"json\"}",
|
||||||
Hash: "x123",
|
Hash: "x123",
|
||||||
})
|
})
|
||||||
repository.CreateContract(core.Contract{
|
contractRepository.CreateContract(core.Contract{
|
||||||
Abi: "{\"some\": \"different json\"}",
|
Abi: "{\"some\": \"different json\"}",
|
||||||
Hash: "x123",
|
Hash: "x123",
|
||||||
})
|
})
|
||||||
contract, err := repository.GetContract("x123")
|
contract, err := contractRepository.GetContract("x123")
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(contract.Abi).To(Equal("{\"some\": \"different json\"}"))
|
Expect(contract.Abi).To(Equal("{\"some\": \"different json\"}"))
|
||||||
})
|
})
|
||||||
|
@ -5,18 +5,18 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ClearData(postgres *DB) {
|
func (db *DB) clearData() {
|
||||||
postgres.DB.MustExec("DELETE FROM watched_contracts")
|
db.MustExec("DELETE FROM watched_contracts")
|
||||||
postgres.DB.MustExec("DELETE FROM transactions")
|
db.MustExec("DELETE FROM transactions")
|
||||||
postgres.DB.MustExec("DELETE FROM blocks")
|
db.MustExec("DELETE FROM blocks")
|
||||||
postgres.DB.MustExec("DELETE FROM logs")
|
db.MustExec("DELETE FROM logs")
|
||||||
postgres.DB.MustExec("DELETE FROM receipts")
|
db.MustExec("DELETE FROM receipts")
|
||||||
postgres.DB.MustExec("DELETE FROM log_filters")
|
db.MustExec("DELETE FROM log_filters")
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildRepository(node core.Node) *DB {
|
func NewTestDB(node core.Node) *DB {
|
||||||
cfg, _ := config.NewConfig("private")
|
cfg, _ := config.NewConfig("private")
|
||||||
repository, _ := NewDB(cfg.Database, node)
|
db, _ := NewDB(cfg.Database, node)
|
||||||
ClearData(repository)
|
db.clearData()
|
||||||
return repository
|
return db
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,12 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db DB) CreateFilter(query filters.LogFilter) error {
|
type FilterRepository struct {
|
||||||
_, err := db.DB.Exec(
|
*DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (filterRepository FilterRepository) CreateFilter(query filters.LogFilter) error {
|
||||||
|
_, err := filterRepository.DB.Exec(
|
||||||
`INSERT INTO log_filters
|
`INSERT INTO log_filters
|
||||||
(name, from_block, to_block, address, topic0, topic1, topic2, topic3)
|
(name, from_block, to_block, address, topic0, topic1, topic2, topic3)
|
||||||
VALUES ($1, NULLIF($2, -1), NULLIF($3, -1), $4, NULLIF($5, ''), NULLIF($6, ''), NULLIF($7, ''), NULLIF($8, ''))`,
|
VALUES ($1, NULLIF($2, -1), NULLIF($3, -1), $4, NULLIF($5, ''), NULLIF($6, ''), NULLIF($7, ''), NULLIF($8, ''))`,
|
||||||
@ -22,9 +26,9 @@ func (db DB) CreateFilter(query filters.LogFilter) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) GetFilter(name string) (filters.LogFilter, error) {
|
func (filterRepository FilterRepository) GetFilter(name string) (filters.LogFilter, error) {
|
||||||
lf := DBLogFilter{}
|
lf := DBLogFilter{}
|
||||||
err := db.DB.Get(&lf,
|
err := filterRepository.DB.Get(&lf,
|
||||||
`SELECT
|
`SELECT
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package postgres
|
package postgres_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
@ -6,10 +6,12 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Logs Repository", func() {
|
var _ = Describe("Log Filters Repository", func() {
|
||||||
var repository repositories.FilterRepository
|
var db *postgres.DB
|
||||||
|
var filterRepository repositories.FilterRepository
|
||||||
var node core.Node
|
var node core.Node
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
node = core.Node{
|
node = core.Node{
|
||||||
@ -18,7 +20,8 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
repository = BuildRepository(node)
|
db = postgres.NewTestDB(node)
|
||||||
|
filterRepository = postgres.FilterRepository{DB: db}
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("LogFilter", func() {
|
Describe("LogFilter", func() {
|
||||||
@ -37,7 +40,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := repository.CreateFilter(logFilter)
|
err := filterRepository.CreateFilter(logFilter)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -54,7 +57,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := repository.CreateFilter(logFilter)
|
err := filterRepository.CreateFilter(logFilter)
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -72,7 +75,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := repository.CreateFilter(logFilter1)
|
err := filterRepository.CreateFilter(logFilter1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
logFilter2 := filters.LogFilter{
|
logFilter2 := filters.LogFilter{
|
||||||
Name: "TestFilter2",
|
Name: "TestFilter2",
|
||||||
@ -86,19 +89,19 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err = repository.CreateFilter(logFilter2)
|
err = filterRepository.CreateFilter(logFilter2)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
logFilter1, err = repository.GetFilter("TestFilter1")
|
logFilter1, err = filterRepository.GetFilter("TestFilter1")
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(logFilter1).To(Equal(logFilter1))
|
Expect(logFilter1).To(Equal(logFilter1))
|
||||||
logFilter1, err = repository.GetFilter("TestFilter1")
|
logFilter1, err = filterRepository.GetFilter("TestFilter1")
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(logFilter2).To(Equal(logFilter2))
|
Expect(logFilter2).To(Equal(logFilter2))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns ErrFilterDoesNotExist error when log does not exist", func() {
|
It("returns ErrFilterDoesNotExist error when log does not exist", func() {
|
||||||
_, err := repository.GetFilter("TestFilter1")
|
_, err := filterRepository.GetFilter("TestFilter1")
|
||||||
Expect(err).To(Equal(repositories.ErrFilterDoesNotExist("TestFilter1")))
|
Expect(err).To(Equal(repositories.ErrFilterDoesNotExist("TestFilter1")))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -8,9 +8,13 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db DB) CreateLogs(logs []core.Log) error {
|
type LogRepository struct {
|
||||||
tx, _ := db.DB.BeginTx(context.Background(), nil)
|
*DB
|
||||||
for _, tlog := range logs {
|
}
|
||||||
|
|
||||||
|
func (logRepository LogRepository) CreateLogs(lgs []core.Log) error {
|
||||||
|
tx, _ := logRepository.DB.BeginTx(context.Background(), nil)
|
||||||
|
for _, tlog := range lgs {
|
||||||
_, err := tx.Exec(
|
_, err := tx.Exec(
|
||||||
`INSERT INTO logs (block_number, address, tx_hash, index, topic0, topic1, topic2, topic3, data)
|
`INSERT INTO logs (block_number, address, tx_hash, index, topic0, topic1, topic2, topic3, data)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||||
@ -26,8 +30,8 @@ func (db DB) CreateLogs(logs []core.Log) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) GetLogs(address string, blockNumber int64) []core.Log {
|
func (logRepository LogRepository) GetLogs(address string, blockNumber int64) []core.Log {
|
||||||
logRows, _ := db.DB.Query(
|
logRows, _ := logRepository.DB.Query(
|
||||||
`SELECT block_number,
|
`SELECT block_number,
|
||||||
address,
|
address,
|
||||||
tx_hash,
|
tx_hash,
|
||||||
@ -40,11 +44,11 @@ func (db DB) GetLogs(address string, blockNumber int64) []core.Log {
|
|||||||
FROM logs
|
FROM logs
|
||||||
WHERE address = $1 AND block_number = $2
|
WHERE address = $1 AND block_number = $2
|
||||||
ORDER BY block_number DESC`, address, blockNumber)
|
ORDER BY block_number DESC`, address, blockNumber)
|
||||||
return db.loadLogs(logRows)
|
return logRepository.loadLogs(logRows)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db DB) loadLogs(logsRows *sql.Rows) []core.Log {
|
func (logRepository LogRepository) loadLogs(logsRows *sql.Rows) []core.Log {
|
||||||
var logs []core.Log
|
var lgs []core.Log
|
||||||
for logsRows.Next() {
|
for logsRows.Next() {
|
||||||
var blockNumber int64
|
var blockNumber int64
|
||||||
var address string
|
var address string
|
||||||
@ -53,7 +57,7 @@ func (db DB) loadLogs(logsRows *sql.Rows) []core.Log {
|
|||||||
var data string
|
var data string
|
||||||
var topics core.Topics
|
var topics core.Topics
|
||||||
logsRows.Scan(&blockNumber, &address, &txHash, &index, &topics[0], &topics[1], &topics[2], &topics[3], &data)
|
logsRows.Scan(&blockNumber, &address, &txHash, &index, &topics[0], &topics[1], &topics[2], &topics[3], &data)
|
||||||
log := core.Log{
|
lg := core.Log{
|
||||||
BlockNumber: blockNumber,
|
BlockNumber: blockNumber,
|
||||||
TxHash: txHash,
|
TxHash: txHash,
|
||||||
Address: address,
|
Address: address,
|
||||||
@ -61,9 +65,9 @@ func (db DB) loadLogs(logsRows *sql.Rows) []core.Log {
|
|||||||
Data: data,
|
Data: data,
|
||||||
}
|
}
|
||||||
for i, topic := range topics {
|
for i, topic := range topics {
|
||||||
log.Topics[i] = topic
|
lg.Topics[i] = topic
|
||||||
}
|
}
|
||||||
logs = append(logs, log)
|
lgs = append(lgs, lg)
|
||||||
}
|
}
|
||||||
return logs
|
return lgs
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Logs Repository", func() {
|
var _ = Describe("Logs Repository", func() {
|
||||||
var repository repositories.LogsRepository
|
var db *postgres.DB
|
||||||
|
var logsRepository repositories.LogRepository
|
||||||
var node core.Node
|
var node core.Node
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
node = core.Node{
|
node = core.Node{
|
||||||
@ -20,12 +21,13 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
repository = postgres.BuildRepository(node)
|
db = postgres.NewTestDB(node)
|
||||||
|
logsRepository = postgres.LogRepository{DB: db}
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("Saving logs", func() {
|
Describe("Saving logs", func() {
|
||||||
It("returns the log when it exists", func() {
|
It("returns the log when it exists", func() {
|
||||||
repository.CreateLogs([]core.Log{{
|
logsRepository.CreateLogs([]core.Log{{
|
||||||
BlockNumber: 1,
|
BlockNumber: 1,
|
||||||
Index: 0,
|
Index: 0,
|
||||||
Address: "x123",
|
Address: "x123",
|
||||||
@ -35,7 +37,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
}},
|
}},
|
||||||
)
|
)
|
||||||
|
|
||||||
log := repository.GetLogs("x123", 1)
|
log := logsRepository.GetLogs("x123", 1)
|
||||||
|
|
||||||
Expect(log).NotTo(BeNil())
|
Expect(log).NotTo(BeNil())
|
||||||
Expect(log[0].BlockNumber).To(Equal(int64(1)))
|
Expect(log[0].BlockNumber).To(Equal(int64(1)))
|
||||||
@ -49,12 +51,12 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("returns nil if log does not exist", func() {
|
It("returns nil if log does not exist", func() {
|
||||||
log := repository.GetLogs("x123", 1)
|
log := logsRepository.GetLogs("x123", 1)
|
||||||
Expect(log).To(BeNil())
|
Expect(log).To(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("filters to the correct block number and address", func() {
|
It("filters to the correct block number and address", func() {
|
||||||
repository.CreateLogs([]core.Log{{
|
logsRepository.CreateLogs([]core.Log{{
|
||||||
BlockNumber: 1,
|
BlockNumber: 1,
|
||||||
Index: 0,
|
Index: 0,
|
||||||
Address: "x123",
|
Address: "x123",
|
||||||
@ -63,7 +65,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
Data: "xabc",
|
Data: "xabc",
|
||||||
}},
|
}},
|
||||||
)
|
)
|
||||||
repository.CreateLogs([]core.Log{{
|
logsRepository.CreateLogs([]core.Log{{
|
||||||
BlockNumber: 1,
|
BlockNumber: 1,
|
||||||
Index: 1,
|
Index: 1,
|
||||||
Address: "x123",
|
Address: "x123",
|
||||||
@ -72,7 +74,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
Data: "xdef",
|
Data: "xdef",
|
||||||
}},
|
}},
|
||||||
)
|
)
|
||||||
repository.CreateLogs([]core.Log{{
|
logsRepository.CreateLogs([]core.Log{{
|
||||||
BlockNumber: 2,
|
BlockNumber: 2,
|
||||||
Index: 0,
|
Index: 0,
|
||||||
Address: "x123",
|
Address: "x123",
|
||||||
@ -82,7 +84,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
}},
|
}},
|
||||||
)
|
)
|
||||||
|
|
||||||
log := repository.GetLogs("x123", 1)
|
log := logsRepository.GetLogs("x123", 1)
|
||||||
|
|
||||||
type logIndex struct {
|
type logIndex struct {
|
||||||
blockNumber int64
|
blockNumber int64
|
||||||
@ -114,7 +116,8 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
|
|
||||||
It("saves the logs attached to a receipt", func() {
|
It("saves the logs attached to a receipt", func() {
|
||||||
var blockRepository repositories.BlockRepository
|
var blockRepository repositories.BlockRepository
|
||||||
blockRepository = postgres.BuildRepository(node)
|
blockRepository = postgres.BlockRepository{DB: db}
|
||||||
|
|
||||||
logs := []core.Log{{
|
logs := []core.Log{{
|
||||||
Address: "0x8a4774fe82c63484afef97ca8d89a6ea5e21f973",
|
Address: "0x8a4774fe82c63484afef97ca8d89a6ea5e21f973",
|
||||||
BlockNumber: 4745407,
|
BlockNumber: 4745407,
|
||||||
@ -168,7 +171,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
block := core.Block{Transactions: []core.Transaction{transaction}}
|
block := core.Block{Transactions: []core.Transaction{transaction}}
|
||||||
err := blockRepository.CreateOrUpdateBlock(block)
|
err := blockRepository.CreateOrUpdateBlock(block)
|
||||||
Expect(err).To(Not(HaveOccurred()))
|
Expect(err).To(Not(HaveOccurred()))
|
||||||
retrievedLogs := repository.GetLogs("0x99041f808d598b782d5a3e498681c2452a31da08", 4745407)
|
retrievedLogs := logsRepository.GetLogs("0x99041f808d598b782d5a3e498681c2452a31da08", 4745407)
|
||||||
|
|
||||||
expected := logs[1:]
|
expected := logs[1:]
|
||||||
Expect(retrievedLogs).To(Equal(expected))
|
Expect(retrievedLogs).To(Equal(expected))
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import "github.com/vulcanize/vulcanizedb/pkg/core"
|
|
||||||
|
|
||||||
type NodeRepository interface {
|
|
||||||
CreateNode(node *core.Node) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *DB) CreateNode(node *core.Node) error {
|
|
||||||
var nodeId int64
|
|
||||||
err := db.DB.QueryRow(
|
|
||||||
`INSERT INTO nodes (genesis_block, network_id, node_id, client_name)
|
|
||||||
VALUES ($1, $2, $3, $4)
|
|
||||||
ON CONFLICT (genesis_block, network_id, node_id)
|
|
||||||
DO UPDATE
|
|
||||||
SET genesis_block = $1,
|
|
||||||
network_id = $2,
|
|
||||||
node_id = $3,
|
|
||||||
client_name = $4
|
|
||||||
RETURNING id`,
|
|
||||||
node.GenesisBlock, node.NetworkId, node.Id, node.ClientName).Scan(&nodeId)
|
|
||||||
if err != nil {
|
|
||||||
return ErrUnableToSetNode
|
|
||||||
}
|
|
||||||
db.nodeId = nodeId
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -35,3 +35,23 @@ func NewDB(databaseConfig config.Database, node core.Node) (*DB, error) {
|
|||||||
}
|
}
|
||||||
return &pg, nil
|
return &pg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) CreateNode(node *core.Node) error {
|
||||||
|
var nodeId int64
|
||||||
|
err := db.QueryRow(
|
||||||
|
`INSERT INTO nodes (genesis_block, network_id, node_id, client_name)
|
||||||
|
VALUES ($1, $2, $3, $4)
|
||||||
|
ON CONFLICT (genesis_block, network_id, node_id)
|
||||||
|
DO UPDATE
|
||||||
|
SET genesis_block = $1,
|
||||||
|
network_id = $2,
|
||||||
|
node_id = $3,
|
||||||
|
client_name = $4
|
||||||
|
RETURNING id`,
|
||||||
|
node.GenesisBlock, node.NetworkId, node.Id, node.ClientName).Scan(&nodeId)
|
||||||
|
if err != nil {
|
||||||
|
return ErrUnableToSetNode
|
||||||
|
}
|
||||||
|
db.nodeId = nodeId
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -22,8 +22,8 @@ func init() {
|
|||||||
log.SetOutput(ioutil.Discard)
|
log.SetOutput(ioutil.Discard)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = Describe("Postgres repository", func() {
|
var _ = Describe("Postgres DB", func() {
|
||||||
var repository *postgres.DB
|
var db *postgres.DB
|
||||||
|
|
||||||
It("connects to the database", func() {
|
It("connects to the database", func() {
|
||||||
cfg, _ := config.NewConfig("private")
|
cfg, _ := config.NewConfig("private")
|
||||||
@ -40,9 +40,7 @@ var _ = Describe("Postgres repository", func() {
|
|||||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
cfg, _ := config.NewConfig("private")
|
db = postgres.NewTestDB(node)
|
||||||
repository, _ = postgres.NewDB(cfg.Database, node)
|
|
||||||
postgres.ClearData(repository)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("serializes big.Int to db", func() {
|
It("serializes big.Int to db", func() {
|
||||||
@ -91,10 +89,11 @@ var _ = Describe("Postgres repository", func() {
|
|||||||
}
|
}
|
||||||
cfg, _ := config.NewConfig("private")
|
cfg, _ := config.NewConfig("private")
|
||||||
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
||||||
repository, _ := postgres.NewDB(cfg.Database, node)
|
db, _ := postgres.NewDB(cfg.Database, node)
|
||||||
|
blocksRepository := postgres.BlockRepository{DB: db}
|
||||||
|
|
||||||
err1 := repository.CreateOrUpdateBlock(badBlock)
|
err1 := blocksRepository.CreateOrUpdateBlock(badBlock)
|
||||||
savedBlock, err2 := repository.GetBlock(123)
|
savedBlock, err2 := blocksRepository.GetBlock(123)
|
||||||
|
|
||||||
Expect(err1).To(HaveOccurred())
|
Expect(err1).To(HaveOccurred())
|
||||||
Expect(err2).To(HaveOccurred())
|
Expect(err2).To(HaveOccurred())
|
||||||
@ -126,10 +125,11 @@ var _ = Describe("Postgres repository", func() {
|
|||||||
}
|
}
|
||||||
cfg, _ := config.NewConfig("private")
|
cfg, _ := config.NewConfig("private")
|
||||||
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
||||||
repository, _ := postgres.NewDB(cfg.Database, node)
|
db, _ := postgres.NewDB(cfg.Database, node)
|
||||||
|
logRepository := postgres.LogRepository{DB: db}
|
||||||
|
|
||||||
err := repository.CreateLogs([]core.Log{badLog})
|
err := logRepository.CreateLogs([]core.Log{badLog})
|
||||||
savedBlock := repository.GetLogs("x123", 1)
|
savedBlock := logRepository.GetLogs("x123", 1)
|
||||||
|
|
||||||
Expect(err).ToNot(BeNil())
|
Expect(err).ToNot(BeNil())
|
||||||
Expect(savedBlock).To(BeNil())
|
Expect(savedBlock).To(BeNil())
|
||||||
@ -145,10 +145,11 @@ var _ = Describe("Postgres repository", func() {
|
|||||||
}
|
}
|
||||||
cfg, _ := config.NewConfig("private")
|
cfg, _ := config.NewConfig("private")
|
||||||
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1, Id: "x123", ClientName: "geth"}
|
||||||
repository, _ := postgres.NewDB(cfg.Database, node)
|
db, _ := postgres.NewDB(cfg.Database, node)
|
||||||
|
blockRepository := postgres.BlockRepository{DB: db}
|
||||||
|
|
||||||
err1 := repository.CreateOrUpdateBlock(block)
|
err1 := blockRepository.CreateOrUpdateBlock(block)
|
||||||
savedBlock, err2 := repository.GetBlock(123)
|
savedBlock, err2 := blockRepository.GetBlock(123)
|
||||||
|
|
||||||
Expect(err1).To(HaveOccurred())
|
Expect(err1).To(HaveOccurred())
|
||||||
Expect(err2).To(HaveOccurred())
|
Expect(err2).To(HaveOccurred())
|
||||||
|
@ -7,8 +7,12 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db DB) GetReceipt(txHash string) (core.Receipt, error) {
|
type ReceiptRepository struct {
|
||||||
row := db.DB.QueryRow(
|
*DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (receiptRepository ReceiptRepository) GetReceipt(txHash string) (core.Receipt, error) {
|
||||||
|
row := receiptRepository.DB.QueryRow(
|
||||||
`SELECT contract_address,
|
`SELECT contract_address,
|
||||||
tx_hash,
|
tx_hash,
|
||||||
cumulative_gas_used,
|
cumulative_gas_used,
|
||||||
|
@ -8,8 +8,9 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Logs Repository", func() {
|
var _ bool = Describe("Logs Repository", func() {
|
||||||
var repository repositories.ReceiptRepository
|
var receiptRepository repositories.ReceiptRepository
|
||||||
|
var db *postgres.DB
|
||||||
var node core.Node
|
var node core.Node
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
node = core.Node{
|
node = core.Node{
|
||||||
@ -18,13 +19,15 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
Id: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
repository = postgres.BuildRepository(node)
|
db = postgres.NewTestDB(node)
|
||||||
|
receiptRepository = postgres.ReceiptRepository{DB: db}
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("Saving receipts", func() {
|
Describe("Saving receipts", func() {
|
||||||
It("returns the receipt when it exists", func() {
|
It("returns the receipt when it exists", func() {
|
||||||
var blockRepository repositories.BlockRepository
|
var blockRepository repositories.BlockRepository
|
||||||
blockRepository = postgres.BuildRepository(node)
|
db := postgres.NewTestDB(node)
|
||||||
|
blockRepository = postgres.BlockRepository{DB: db}
|
||||||
expected := core.Receipt{
|
expected := core.Receipt{
|
||||||
ContractAddress: "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
|
ContractAddress: "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
|
||||||
CumulativeGasUsed: 7996119,
|
CumulativeGasUsed: 7996119,
|
||||||
@ -42,7 +45,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
|
|
||||||
block := core.Block{Transactions: []core.Transaction{transaction}}
|
block := core.Block{Transactions: []core.Transaction{transaction}}
|
||||||
blockRepository.CreateOrUpdateBlock(block)
|
blockRepository.CreateOrUpdateBlock(block)
|
||||||
receipt, err := repository.GetReceipt("0xe340558980f89d5f86045ac11e5cc34e4bcec20f9f1e2a427aa39d87114e8223")
|
receipt, err := receiptRepository.GetReceipt("0xe340558980f89d5f86045ac11e5cc34e4bcec20f9f1e2a427aa39d87114e8223")
|
||||||
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
//Not currently serializing bloom logs
|
//Not currently serializing bloom logs
|
||||||
@ -55,14 +58,15 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("returns ErrReceiptDoesNotExist when receipt does not exist", func() {
|
It("returns ErrReceiptDoesNotExist when receipt does not exist", func() {
|
||||||
receipt, err := repository.GetReceipt("DOES NOT EXIST")
|
receipt, err := receiptRepository.GetReceipt("DOES NOT EXIST")
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
Expect(receipt).To(BeZero())
|
Expect(receipt).To(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("still saves receipts without logs", func() {
|
It("still saves receipts without logs", func() {
|
||||||
var blockRepository repositories.BlockRepository
|
var blockRepository repositories.BlockRepository
|
||||||
blockRepository = postgres.BuildRepository(node)
|
db := postgres.NewTestDB(node)
|
||||||
|
blockRepository = postgres.BlockRepository{DB: db}
|
||||||
receipt := core.Receipt{
|
receipt := core.Receipt{
|
||||||
TxHash: "0x002c4799161d809b23f67884eb6598c9df5894929fe1a9ead97ca175d360f547",
|
TxHash: "0x002c4799161d809b23f67884eb6598c9df5894929fe1a9ead97ca175d360f547",
|
||||||
}
|
}
|
||||||
@ -76,7 +80,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
}
|
}
|
||||||
blockRepository.CreateOrUpdateBlock(block)
|
blockRepository.CreateOrUpdateBlock(block)
|
||||||
|
|
||||||
_, err := repository.GetReceipt(receipt.TxHash)
|
_, err := receiptRepository.GetReceipt(receipt.TxHash)
|
||||||
|
|
||||||
Expect(err).To(Not(HaveOccurred()))
|
Expect(err).To(Not(HaveOccurred()))
|
||||||
})
|
})
|
||||||
|
@ -4,8 +4,12 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db DB) GetWatchedEvents(name string) ([]*core.WatchedEvent, error) {
|
type WatchedEventRepository struct {
|
||||||
rows, err := db.DB.Queryx(`SELECT name, block_number, address, tx_hash, index, topic0, topic1, topic2, topic3, data FROM watched_event_logs where name=$1`, name)
|
*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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,24 @@
|
|||||||
package postgres_test
|
package postgres_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/repositories/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Watched Events Repository", func() {
|
var _ = Describe("Watched Events Repository", func() {
|
||||||
var repository *postgres.DB
|
var db *postgres.DB
|
||||||
|
var logRepository postgres.LogRepository
|
||||||
|
var filterRepository postgres.FilterRepository
|
||||||
|
var watchedEventRepository postgres.WatchedEventRepository
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
|
db = postgres.NewTestDB(core.Node{})
|
||||||
cfg, err := config.NewConfig("private")
|
logRepository = postgres.LogRepository{DB: db}
|
||||||
if err != nil {
|
filterRepository = postgres.FilterRepository{DB: db}
|
||||||
log.Fatal(err)
|
watchedEventRepository = postgres.WatchedEventRepository{DB: db}
|
||||||
}
|
|
||||||
repository, err = postgres.NewDB(cfg.Database, core.Node{})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
postgres.ClearData(repository)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("retrieves watched event logs that match the event filter", func() {
|
It("retrieves watched event logs that match the event filter", func() {
|
||||||
@ -57,11 +51,11 @@ var _ = Describe("Watched Events Repository", func() {
|
|||||||
Data: "",
|
Data: "",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := repository.CreateFilter(filter)
|
err := filterRepository.CreateFilter(filter)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
err = repository.CreateLogs(logs)
|
err = logRepository.CreateLogs(logs)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
matchingLogs, err := repository.GetWatchedEvents("Filter1")
|
matchingLogs, err := watchedEventRepository.GetWatchedEvents("Filter1")
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(matchingLogs).To(Equal(expectedWatchedEventLog))
|
Expect(matchingLogs).To(Equal(expectedWatchedEventLog))
|
||||||
|
|
||||||
@ -103,11 +97,11 @@ var _ = Describe("Watched Events Repository", func() {
|
|||||||
Index: 0,
|
Index: 0,
|
||||||
Data: "",
|
Data: "",
|
||||||
}}
|
}}
|
||||||
err := repository.CreateFilter(filter)
|
err := filterRepository.CreateFilter(filter)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
err = repository.CreateLogs(logs)
|
err = logRepository.CreateLogs(logs)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
matchingLogs, err := repository.GetWatchedEvents("Filter1")
|
matchingLogs, err := watchedEventRepository.GetWatchedEvents("Filter1")
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(matchingLogs).To(Equal(expectedWatchedEventLog))
|
Expect(matchingLogs).To(Equal(expectedWatchedEventLog))
|
||||||
|
|
||||||
|
@ -8,15 +8,6 @@ import (
|
|||||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Repository interface {
|
|
||||||
BlockRepository
|
|
||||||
ContractRepository
|
|
||||||
LogsRepository
|
|
||||||
ReceiptRepository
|
|
||||||
FilterRepository
|
|
||||||
WatchedEventsRepository
|
|
||||||
}
|
|
||||||
|
|
||||||
var ErrBlockDoesNotExist = func(blockNumber int64) error {
|
var ErrBlockDoesNotExist = func(blockNumber int64) error {
|
||||||
return errors.New(fmt.Sprintf("Block number %d does not exist", blockNumber))
|
return errors.New(fmt.Sprintf("Block number %d does not exist", blockNumber))
|
||||||
}
|
}
|
||||||
@ -47,7 +38,7 @@ type FilterRepository interface {
|
|||||||
GetFilter(name string) (filters.LogFilter, error)
|
GetFilter(name string) (filters.LogFilter, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogsRepository interface {
|
type LogRepository interface {
|
||||||
CreateLogs(logs []core.Log) error
|
CreateLogs(logs []core.Log) error
|
||||||
GetLogs(address string, blockNumber int64) []core.Log
|
GetLogs(address string, blockNumber int64) []core.Log
|
||||||
}
|
}
|
||||||
@ -60,6 +51,6 @@ type ReceiptRepository interface {
|
|||||||
GetReceipt(txHash string) (core.Receipt, error)
|
GetReceipt(txHash string) (core.Receipt, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type WatchedEventsRepository interface {
|
type WatchedEventRepository interface {
|
||||||
GetWatchedEvents(name string) ([]*core.WatchedEvent, error)
|
GetWatchedEvents(name string) ([]*core.WatchedEvent, error)
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,11 @@ func LoadConfig(environment string) config.Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LoadPostgres(database config.Database, node core.Node) postgres.DB {
|
func LoadPostgres(database config.Database, node core.Node) postgres.DB {
|
||||||
repository, err := postgres.NewDB(database, node)
|
db, err := postgres.NewDB(database, node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error loading postgres\n%v", err)
|
log.Fatalf("Error loading postgres\n%v", err)
|
||||||
}
|
}
|
||||||
return *repository
|
return *db
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadAbiFile(abiFilepath string) string {
|
func ReadAbiFile(abiFilepath string) string {
|
||||||
|
Loading…
Reference in New Issue
Block a user