Backfill/listen for contract logs (#113)

This commit is contained in:
Matt K 2017-12-22 11:42:35 -06:00 committed by GitHub
parent a786241c8c
commit 7e5e12f488
7 changed files with 57 additions and 33 deletions

View File

@ -44,16 +44,14 @@ func tasks(p *do.Project) {
p.Task("getLogs", nil, func(context *do.Context) { p.Task("getLogs", nil, func(context *do.Context) {
environment := parseEnvironment(context) environment := parseEnvironment(context)
blockNumber := context.Args.MayInt(-1, "block-number", "b")
contractHash := context.Args.MayString("", "contract-hash", "c") contractHash := context.Args.MayString("", "contract-hash", "c")
if contractHash == "" { if contractHash == "" {
log.Fatalln("--contract-hash required") log.Fatalln("--contract-hash required")
} }
context.Start(`go run main.go --environment={{.environment}} --contract-hash={{.contractHash}} --block-number={{.blockNumber}}`, context.Start(`go run main.go --environment={{.environment}} --contract-hash={{.contractHash}}`,
do.M{ do.M{
"environment": environment, "environment": environment,
"contractHash": contractHash, "contractHash": contractHash,
"blockNumber": blockNumber,
"$in": "cmd/get_logs", "$in": "cmd/get_logs",
}) })
}) })

View File

@ -93,8 +93,8 @@ The name of the JSON file should correspond the contract's address.
## Retrieving Contract Logs ## Retrieving Contract Logs
1. Get the logs 1. Get the logs for a specific contract
- `godo getLogs -- --environment=<some-environment> --contract-hash=<contract-address> --starting-number=<starting-block-number>` - `godo getLogs -- --environment=<some-environment> --contract-hash=<contract-address>`
### Configuring Additional Environments ### Configuring Additional Environments

View File

@ -1,45 +1,71 @@
package main package main
import ( import (
"fmt"
"log" "log"
"flag" "flag"
"math/big"
"time"
"github.com/8thlight/vulcanizedb/cmd" "github.com/8thlight/vulcanizedb/cmd"
"github.com/8thlight/vulcanizedb/pkg/core" "github.com/8thlight/vulcanizedb/pkg/core"
"github.com/8thlight/vulcanizedb/pkg/geth" "github.com/8thlight/vulcanizedb/pkg/geth"
) )
func min(a, b int64) int64 {
if a < b {
return a
}
return b
}
const (
windowSize = 24
pollingInterval = 10 * time.Second
)
func main() { func main() {
environment := flag.String("environment", "", "Environment name") environment := flag.String("environment", "", "Environment name")
contractHash := flag.String("contract-hash", "", "Contract hash to show summary") contractHash := flag.String("contract-hash", "", "Contract hash to show summary")
_blockNumber := flag.Int64("block-number", -1, "Block number of summary") ticker := time.NewTicker(pollingInterval)
defer ticker.Stop()
flag.Parse() flag.Parse()
config := cmd.LoadConfig(*environment) config := cmd.LoadConfig(*environment)
blockchain := geth.NewGethBlockchain(config.Client.IPCPath) blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
repository := cmd.LoadPostgres(config.Database, blockchain.Node()) repository := cmd.LoadPostgres(config.Database, blockchain.Node())
blockNumber := cmd.RequestedBlockNumber(_blockNumber)
logs, err := blockchain.GetLogs(core.Contract{Hash: *contractHash}, blockNumber) lastBlockNumber := blockchain.LastBlock().Int64()
stepSize := int64(1000)
go func() {
for i := int64(0); i < lastBlockNumber; i = min(i+stepSize, lastBlockNumber) {
logs, err := blockchain.GetLogs(core.Contract{Hash: *contractHash}, big.NewInt(i), big.NewInt(i+stepSize))
log.Println("Backfilling Logs:", i)
if err != nil { if err != nil {
log.Fatalln(err) log.Println(err)
} }
repository.CreateLogs(logs) repository.CreateLogs(logs)
for _, l := range logs {
fmt.Println("\tAddress: ", l.Address)
fmt.Println("\tTxHash: ", l.TxHash)
fmt.Println("\tBlockNumber ", l.BlockNumber)
fmt.Println("\tIndex ", l.Index)
fmt.Println("\tTopics: ")
for i, topic := range l.Topics {
fmt.Printf("\t\tTopic %d: %s\n", i, topic)
} }
fmt.Printf("\tData: %s", l.Data) }()
fmt.Print("\n\n")
done := make(chan struct{})
go func() { done <- struct{}{} }()
for range ticker.C {
select {
case <-done:
go func() {
z := &big.Int{}
z.Sub(blockchain.LastBlock(), big.NewInt(25))
log.Printf("Logs Window: %d - %d", z.Int64(), blockchain.LastBlock().Int64())
logs, _ := blockchain.GetLogs(core.Contract{Hash: *contractHash}, z, blockchain.LastBlock())
repository.CreateLogs(logs)
done <- struct{}{}
}()
default:
}
} }
} }

View File

@ -119,7 +119,7 @@ var _ = Describe("Reading contracts", func() {
blockchain := geth.NewGethBlockchain(config.Client.IPCPath) blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
contract := testing.SampleContract() contract := testing.SampleContract()
logs, err := blockchain.GetLogs(contract, big.NewInt(4703824)) logs, err := blockchain.GetLogs(contract, big.NewInt(4703824), nil)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(len(logs)).To(Equal(3)) Expect(len(logs)).To(Equal(3))
@ -131,7 +131,7 @@ var _ = Describe("Reading contracts", func() {
config, _ := cfg.NewConfig("infura") config, _ := cfg.NewConfig("infura")
blockchain := geth.NewGethBlockchain(config.Client.IPCPath) blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
logs, err := blockchain.GetLogs(core.Contract{Hash: "x123"}, big.NewInt(4703824)) logs, err := blockchain.GetLogs(core.Contract{Hash: "x123"}, big.NewInt(4703824), nil)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(len(logs)).To(Equal(0)) Expect(len(logs)).To(Equal(0))

View File

@ -11,5 +11,5 @@ type Blockchain interface {
StopListening() StopListening()
GetAttributes(contract Contract) (ContractAttributes, error) GetAttributes(contract Contract) (ContractAttributes, error)
GetAttribute(contract Contract, attributeName string, blockNumber *big.Int) (interface{}, error) GetAttribute(contract Contract, attributeName string, blockNumber *big.Int) (interface{}, error)
GetLogs(contract Contract, blockNumber *big.Int) ([]Log, error) GetLogs(contract Contract, startingBlockNumber *big.Int, endingBlockNumber *big.Int) ([]Log, error)
} }

View File

@ -27,7 +27,7 @@ func (blockchain *Blockchain) LastBlock() *big.Int {
return big.NewInt(max) return big.NewInt(max)
} }
func (blockchain *Blockchain) GetLogs(contract core.Contract, blockNumber *big.Int) ([]core.Log, error) { func (blockchain *Blockchain) GetLogs(contract core.Contract, startingBlock *big.Int, endingBlock *big.Int) ([]core.Log, error) {
return blockchain.logs[contract.Hash], nil return blockchain.logs[contract.Hash], nil
} }

View File

@ -23,14 +23,14 @@ type GethBlockchain struct {
node core.Node node core.Node
} }
func (blockchain *GethBlockchain) GetLogs(contract core.Contract, blockNumber *big.Int) ([]core.Log, error) { func (blockchain *GethBlockchain) GetLogs(contract core.Contract, startingBlockNumber *big.Int, endingBlockNumber *big.Int) ([]core.Log, error) {
if blockNumber == nil { if endingBlockNumber == nil {
blockNumber = blockchain.LastBlock() endingBlockNumber = startingBlockNumber
} }
contractAddress := common.HexToAddress(contract.Hash) contractAddress := common.HexToAddress(contract.Hash)
fc := ethereum.FilterQuery{ fc := ethereum.FilterQuery{
FromBlock: blockNumber, FromBlock: startingBlockNumber,
ToBlock: blockNumber, ToBlock: endingBlockNumber,
Addresses: []common.Address{contractAddress}, Addresses: []common.Address{contractAddress},
} }
gethLogs, err := blockchain.client.FilterLogs(context.Background(), fc) gethLogs, err := blockchain.client.FilterLogs(context.Background(), fc)