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) {
environment := parseEnvironment(context)
blockNumber := context.Args.MayInt(-1, "block-number", "b")
contractHash := context.Args.MayString("", "contract-hash", "c")
if contractHash == "" {
log.Fatalln("--contract-hash required")
}
context.Start(`go run main.go --environment={{.environment}} --contract-hash={{.contractHash}} --block-number={{.blockNumber}}`,
context.Start(`go run main.go --environment={{.environment}} --contract-hash={{.contractHash}}`,
do.M{
"environment": environment,
"contractHash": contractHash,
"blockNumber": blockNumber,
"$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
1. Get the logs
- `godo getLogs -- --environment=<some-environment> --contract-hash=<contract-address> --starting-number=<starting-block-number>`
1. Get the logs for a specific contract
- `godo getLogs -- --environment=<some-environment> --contract-hash=<contract-address>`
### Configuring Additional Environments

View File

@ -1,45 +1,71 @@
package main
import (
"fmt"
"log"
"flag"
"math/big"
"time"
"github.com/8thlight/vulcanizedb/cmd"
"github.com/8thlight/vulcanizedb/pkg/core"
"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() {
environment := flag.String("environment", "", "Environment name")
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()
config := cmd.LoadConfig(*environment)
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
repository := cmd.LoadPostgres(config.Database, blockchain.Node())
blockNumber := cmd.RequestedBlockNumber(_blockNumber)
logs, err := blockchain.GetLogs(core.Contract{Hash: *contractHash}, blockNumber)
if err != nil {
log.Fatalln(err)
}
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)
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 {
log.Println(err)
}
repository.CreateLogs(logs)
}
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)
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(len(logs)).To(Equal(3))
@ -131,7 +131,7 @@ var _ = Describe("Reading contracts", func() {
config, _ := cfg.NewConfig("infura")
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(len(logs)).To(Equal(0))

View File

@ -11,5 +11,5 @@ type Blockchain interface {
StopListening()
GetAttributes(contract Contract) (ContractAttributes, 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)
}
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
}

View File

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