forked from cerc-io/ipld-eth-server
Get logs for a contract (#99)
* Add ability to fetch logs for a contract and a block * Test contract related code against Infura, so can run on Travis * Add godo task for getLogs
This commit is contained in:
parent
921bde1089
commit
5e64283a12
@ -36,6 +36,22 @@ func tasks(p *do.Project) {
|
||||
do.M{"environment": environment, "startingNumber": startingNumber, "$in": "cmd/populate_blocks"})
|
||||
})
|
||||
|
||||
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}}`,
|
||||
do.M{
|
||||
"environment": environment,
|
||||
"contractHash": contractHash,
|
||||
"blockNumber": blockNumber,
|
||||
"$in": "cmd/get_logs",
|
||||
})
|
||||
})
|
||||
|
||||
p.Task("watchContract", nil, func(context *do.Context) {
|
||||
environment := parseEnvironment(context)
|
||||
contractHash := context.Args.MayString("", "contract-hash", "c")
|
||||
|
@ -86,6 +86,12 @@ The name of the JSON file should correspond the contract's address.
|
||||
2. Start watching the contract `godo watchContract -- --environment=<some-environment> --contract-hash=<contract-address>`
|
||||
3. Request summary data `godo showContractSummary -- --environment=<some-environment> --contract-hash=<contract-address>`
|
||||
|
||||
|
||||
## Retrieving Contract Logs
|
||||
|
||||
1. Get the logs
|
||||
- `godo getLogs -- --environment=<some-environment> --contract-hash=<contract-address> --starting-number=<starting-block-number>`
|
||||
|
||||
### Configuring Additional Environments
|
||||
|
||||
You can create configuration files for additional environments.
|
||||
|
40
cmd/get_logs/main.go
Normal file
40
cmd/get_logs/main.go
Normal file
@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"flag"
|
||||
|
||||
"github.com/8thlight/vulcanizedb/cmd"
|
||||
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||
"github.com/8thlight/vulcanizedb/pkg/geth"
|
||||
)
|
||||
|
||||
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")
|
||||
flag.Parse()
|
||||
config := cmd.LoadConfig(*environment)
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
blockNumber := cmd.RequestedBlockNumber(_blockNumber)
|
||||
|
||||
logs, err := blockchain.GetLogs(core.Contract{Hash: *contractHash}, blockNumber)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
for _, l := range logs {
|
||||
fmt.Println("\tAddress: ", l.Address)
|
||||
fmt.Println("\tTxHash: ", l.TxHash)
|
||||
fmt.Println("\tBlockNumber ", l.BlockNumber)
|
||||
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")
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -7,8 +7,6 @@ import (
|
||||
|
||||
"fmt"
|
||||
|
||||
"math/big"
|
||||
|
||||
"github.com/8thlight/vulcanizedb/cmd"
|
||||
"github.com/8thlight/vulcanizedb/pkg/contract_summary"
|
||||
"github.com/8thlight/vulcanizedb/pkg/geth"
|
||||
@ -22,7 +20,7 @@ func main() {
|
||||
config := cmd.LoadConfig(*environment)
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
repository := cmd.LoadPostgres(config.Database, blockchain.Node())
|
||||
blockNumber := requestedBlockNumber(_blockNumber)
|
||||
blockNumber := cmd.RequestedBlockNumber(_blockNumber)
|
||||
|
||||
contractSummary, err := contract_summary.NewSummary(blockchain, repository, *contractHash, blockNumber)
|
||||
if err != nil {
|
||||
@ -31,13 +29,3 @@ func main() {
|
||||
output := contract_summary.GenerateConsoleOutput(contractSummary)
|
||||
fmt.Println(output)
|
||||
}
|
||||
|
||||
func requestedBlockNumber(blockNumber *int64) *big.Int {
|
||||
var _blockNumber *big.Int
|
||||
if *blockNumber == -1 {
|
||||
_blockNumber = nil
|
||||
} else {
|
||||
_blockNumber = big.NewInt(*blockNumber)
|
||||
}
|
||||
return _blockNumber
|
||||
}
|
||||
|
12
cmd/utils.go
12
cmd/utils.go
@ -7,6 +7,8 @@ import (
|
||||
|
||||
"fmt"
|
||||
|
||||
"math/big"
|
||||
|
||||
"github.com/8thlight/vulcanizedb/pkg/config"
|
||||
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||
"github.com/8thlight/vulcanizedb/pkg/geth"
|
||||
@ -55,3 +57,13 @@ func GetAbi(abiFilepath string, contractHash string) string {
|
||||
}
|
||||
return contractAbiString
|
||||
}
|
||||
|
||||
func RequestedBlockNumber(blockNumber *int64) *big.Int {
|
||||
var _blockNumber *big.Int
|
||||
if *blockNumber == -1 {
|
||||
_blockNumber = nil
|
||||
} else {
|
||||
_blockNumber = big.NewInt(*blockNumber)
|
||||
}
|
||||
return _blockNumber
|
||||
}
|
||||
|
7
environments/infura.toml
Normal file
7
environments/infura.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[database]
|
||||
name = "vulcanize_private"
|
||||
hostname = "localhost"
|
||||
port = 5432
|
||||
|
||||
[client]
|
||||
ipcPath = "https://mainnet.infura.io/J5Vd2fRtGsw0zZ0Ov3BL"
|
142
integration_test/contract_test.go
Normal file
142
integration_test/contract_test.go
Normal file
@ -0,0 +1,142 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"log"
|
||||
|
||||
cfg "github.com/8thlight/vulcanizedb/pkg/config"
|
||||
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||
"github.com/8thlight/vulcanizedb/pkg/geth"
|
||||
"github.com/8thlight/vulcanizedb/pkg/geth/testing"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Reading contracts", func() {
|
||||
|
||||
Describe("Reading the list of attributes", func() {
|
||||
It("returns a string attribute for a real contract", func() {
|
||||
config, err := cfg.NewConfig("infura")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
contract := testing.SampleContract()
|
||||
|
||||
contractAttributes, err := blockchain.GetAttributes(contract)
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
Expect(len(contractAttributes)).NotTo(Equal(0))
|
||||
symbolAttribute := *testing.FindAttribute(contractAttributes, "symbol")
|
||||
Expect(symbolAttribute.Name).To(Equal("symbol"))
|
||||
Expect(symbolAttribute.Type).To(Equal("string"))
|
||||
})
|
||||
|
||||
It("does not return an attribute that takes an input", func() {
|
||||
config, err := cfg.NewConfig("infura")
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
contract := testing.SampleContract()
|
||||
|
||||
contractAttributes, err := blockchain.GetAttributes(contract)
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
attribute := testing.FindAttribute(contractAttributes, "balanceOf")
|
||||
Expect(attribute).To(BeNil())
|
||||
})
|
||||
|
||||
It("does not return an attribute that is not constant", func() {
|
||||
config, _ := cfg.NewConfig("infura")
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
contract := testing.SampleContract()
|
||||
|
||||
contractAttributes, err := blockchain.GetAttributes(contract)
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
attribute := testing.FindAttribute(contractAttributes, "unpause")
|
||||
Expect(attribute).To(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Getting a contract attribute", func() {
|
||||
It("returns the correct attribute for a real contract", func() {
|
||||
config, _ := cfg.NewConfig("infura")
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
|
||||
contract := testing.SampleContract()
|
||||
name, err := blockchain.GetAttribute(contract, "name", nil)
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
Expect(name).To(Equal("OMGToken"))
|
||||
})
|
||||
|
||||
It("returns the correct attribute for a real contract", func() {
|
||||
config, _ := cfg.NewConfig("infura")
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
contract := testing.SampleContract()
|
||||
|
||||
name, err := blockchain.GetAttribute(contract, "name", nil)
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
Expect(name).To(Equal("OMGToken"))
|
||||
})
|
||||
|
||||
It("returns the correct attribute for a real contract at a specific block height", func() {
|
||||
config, _ := cfg.NewConfig("infura")
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
contract := testing.SampleContract()
|
||||
|
||||
name, err := blockchain.GetAttribute(contract, "name", big.NewInt(4701536))
|
||||
|
||||
Expect(name).To(Equal("OMGToken"))
|
||||
Expect(err).To(BeNil())
|
||||
})
|
||||
|
||||
It("returns an error when asking for an attribute that does not exist", func() {
|
||||
config, _ := cfg.NewConfig("infura")
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
contract := testing.SampleContract()
|
||||
|
||||
name, err := blockchain.GetAttribute(contract, "missing_attribute", nil)
|
||||
|
||||
Expect(err).To(Equal(geth.ErrInvalidStateAttribute))
|
||||
Expect(name).To(BeNil())
|
||||
})
|
||||
|
||||
It("retrieves the event log for a specific block and contract", func() {
|
||||
expectedLogZero := core.Log{
|
||||
BlockNumber: 4703824,
|
||||
TxHash: "0xf896bfd1eb539d881a1a31102b78de9f25cd591bf1fe1924b86148c0b205fd5d",
|
||||
Address: "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07",
|
||||
Topics: []string{
|
||||
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
|
||||
"0x000000000000000000000000fbb1b73c4f0bda4f67dca266ce6ef42f520fbb98",
|
||||
"0x000000000000000000000000d26114cd6ee289accf82350c8d8487fedb8a0c07",
|
||||
},
|
||||
Data: "0x0000000000000000000000000000000000000000000000000c7d713b49da0000"}
|
||||
config, _ := cfg.NewConfig("infura")
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
contract := testing.SampleContract()
|
||||
|
||||
logs, err := blockchain.GetLogs(contract, big.NewInt(4703824))
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
Expect(len(logs)).To(Equal(3))
|
||||
Expect(logs[0]).To(Equal(expectedLogZero))
|
||||
|
||||
})
|
||||
|
||||
It("returns and empty log array when no events for a given block / contract combo", func() {
|
||||
config, _ := cfg.NewConfig("infura")
|
||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
|
||||
logs, err := blockchain.GetLogs(core.Contract{Hash: "x123"}, big.NewInt(4703824))
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
Expect(len(logs)).To(Equal(0))
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
@ -12,6 +12,8 @@ import (
|
||||
|
||||
"errors"
|
||||
|
||||
"net/url"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
@ -24,6 +26,10 @@ var NewErrConfigFileNotFound = func(environment string) error {
|
||||
return errors.New(fmt.Sprintf("No configuration found for environment: %v", environment))
|
||||
}
|
||||
|
||||
var NewErrBadConnectionString = func(connectionString string) error {
|
||||
return errors.New(fmt.Sprintf("connection string is invalid: %v", connectionString))
|
||||
}
|
||||
|
||||
func NewConfig(environment string) (Config, error) {
|
||||
filenameWithExtension := fmt.Sprintf("%s.toml", environment)
|
||||
absolutePath := filepath.Join(ProjectRoot(), "environments", filenameWithExtension)
|
||||
@ -31,7 +37,7 @@ func NewConfig(environment string) (Config, error) {
|
||||
if err != nil {
|
||||
return Config{}, NewErrConfigFileNotFound(environment)
|
||||
} else {
|
||||
if !filepath.IsAbs(config.Client.IPCPath) {
|
||||
if !filepath.IsAbs(config.Client.IPCPath) && !isUrl(config.Client.IPCPath) {
|
||||
config.Client.IPCPath = filepath.Join(ProjectRoot(), config.Client.IPCPath)
|
||||
}
|
||||
return config, nil
|
||||
@ -43,16 +49,31 @@ func ProjectRoot() string {
|
||||
return path.Join(path.Dir(filename), "..", "..")
|
||||
}
|
||||
|
||||
func isUrl(s string) bool {
|
||||
_, err := url.ParseRequestURI(s)
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func fileExists(s string) bool {
|
||||
_, err := os.Stat(s)
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func parseConfigFile(filePath string) (Config, error) {
|
||||
var cfg Config
|
||||
_, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
if !isUrl(filePath) && !fileExists(filePath) {
|
||||
return Config{}, NewErrBadConnectionString(filePath)
|
||||
} else {
|
||||
_, err := toml.DecodeFile(filePath, &cfg)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
return cfg, err
|
||||
return cfg, nil
|
||||
}
|
||||
}
|
||||
|
@ -28,4 +28,14 @@ var _ = Describe("Loading the config", func() {
|
||||
Expect(err).NotTo(BeNil())
|
||||
})
|
||||
|
||||
It("reads the infura config using the environment", func() {
|
||||
infuraConfig, err := cfg.NewConfig("infura")
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
Expect(infuraConfig.Database.Hostname).To(Equal("localhost"))
|
||||
Expect(infuraConfig.Database.Name).To(Equal("vulcanize_private"))
|
||||
Expect(infuraConfig.Database.Port).To(Equal(5432))
|
||||
Expect(infuraConfig.Client.IPCPath).To(Equal("https://mainnet.infura.io/J5Vd2fRtGsw0zZ0Ov3BL"))
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -10,4 +10,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)
|
||||
}
|
||||
|
9
pkg/core/log.go
Normal file
9
pkg/core/log.go
Normal file
@ -0,0 +1,9 @@
|
||||
package core
|
||||
|
||||
type Log struct {
|
||||
BlockNumber int64
|
||||
TxHash string
|
||||
Address string
|
||||
Topics []string
|
||||
Data string
|
||||
}
|
@ -9,6 +9,7 @@ import (
|
||||
)
|
||||
|
||||
type Blockchain struct {
|
||||
logs map[string][]core.Log
|
||||
blocks map[int64]core.Block
|
||||
contractAttributes map[string]map[string]string
|
||||
blocksChannel chan core.Block
|
||||
@ -16,6 +17,10 @@ type Blockchain struct {
|
||||
node core.Node
|
||||
}
|
||||
|
||||
func (blockchain *Blockchain) GetLogs(contract core.Contract, blockNumber *big.Int) ([]core.Log, error) {
|
||||
return blockchain.logs[contract.Hash], nil
|
||||
}
|
||||
|
||||
func (blockchain *Blockchain) Node() core.Node {
|
||||
return blockchain.node
|
||||
}
|
||||
@ -33,6 +38,7 @@ func (blockchain *Blockchain) GetAttribute(contract core.Contract, attributeName
|
||||
func NewBlockchain() *Blockchain {
|
||||
return &Blockchain{
|
||||
blocks: make(map[int64]core.Block),
|
||||
logs: make(map[string][]core.Log),
|
||||
contractAttributes: make(map[string]map[string]string),
|
||||
node: core.Node{GenesisBlock: "GENESIS"},
|
||||
}
|
||||
|
@ -1,101 +0,0 @@
|
||||
package geth_test
|
||||
|
||||
//import (
|
||||
// "math/big"
|
||||
//
|
||||
// cfg "github.com/8thlight/vulcanizedb/pkg/config"
|
||||
// "github.com/8thlight/vulcanizedb/pkg/geth"
|
||||
// "github.com/8thlight/vulcanizedb/pkg/geth/testing"
|
||||
// . "github.com/onsi/ginkgo"
|
||||
// . "github.com/onsi/gomega"
|
||||
//)
|
||||
//
|
||||
//var _ = Describe("Reading contracts", func() {
|
||||
//
|
||||
// Describe("Reading the list of attributes", func() {
|
||||
// It("returns a string attribute for a real contract", func() {
|
||||
// config, _ := cfg.NewConfig("public")
|
||||
// blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
// contract := testing.SampleContract()
|
||||
//
|
||||
// contractAttributes, err := blockchain.GetAttributes(contract)
|
||||
//
|
||||
// Expect(err).To(BeNil())
|
||||
// Expect(len(contractAttributes)).NotTo(Equal(0))
|
||||
// symbolAttribute := *testing.FindAttribute(contractAttributes, "symbol")
|
||||
// Expect(symbolAttribute.Name).To(Equal("symbol"))
|
||||
// Expect(symbolAttribute.Type).To(Equal("string"))
|
||||
// })
|
||||
//
|
||||
// It("does not return an attribute that takes an input", func() {
|
||||
// config, _ := cfg.NewConfig("public")
|
||||
// blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
// contract := testing.SampleContract()
|
||||
//
|
||||
// contractAttributes, err := blockchain.GetAttributes(contract)
|
||||
//
|
||||
// Expect(err).To(BeNil())
|
||||
// attribute := testing.FindAttribute(contractAttributes, "balanceOf")
|
||||
// Expect(attribute).To(BeNil())
|
||||
// })
|
||||
//
|
||||
// It("does not return an attribute that is not constant", func() {
|
||||
// config, _ := cfg.NewConfig("public")
|
||||
// blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
// contract := testing.SampleContract()
|
||||
//
|
||||
// contractAttributes, err := blockchain.GetAttributes(contract)
|
||||
//
|
||||
// Expect(err).To(BeNil())
|
||||
// attribute := testing.FindAttribute(contractAttributes, "unpause")
|
||||
// Expect(attribute).To(BeNil())
|
||||
// })
|
||||
// })
|
||||
//
|
||||
// Describe("Getting a contract attribute", func() {
|
||||
// It("returns the correct attribute for a real contract", func() {
|
||||
// config, _ := cfg.NewConfig("public")
|
||||
// blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
//
|
||||
// contract := testing.SampleContract()
|
||||
// name, err := blockchain.GetAttribute(contract, "name", nil)
|
||||
//
|
||||
// Expect(err).To(BeNil())
|
||||
// Expect(name).To(Equal("OMGToken"))
|
||||
// })
|
||||
//
|
||||
// It("returns the correct attribute for a real contract", func() {
|
||||
// config, _ := cfg.NewConfig("public")
|
||||
// blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
// contract := testing.SampleContract()
|
||||
//
|
||||
// name, err := blockchain.GetAttribute(contract, "name", nil)
|
||||
//
|
||||
// Expect(err).To(BeNil())
|
||||
// Expect(name).To(Equal("OMGToken"))
|
||||
// })
|
||||
//
|
||||
// It("returns the correct attribute for a real contract at a specific block height", func() {
|
||||
// config, _ := cfg.NewConfig("public")
|
||||
// blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
// contract := testing.SampleContract()
|
||||
//
|
||||
// name, err := blockchain.GetAttribute(contract, "name", big.NewInt(4652791))
|
||||
//
|
||||
// Expect(name).To(Equal("OMGToken"))
|
||||
// Expect(err).To(BeNil())
|
||||
// })
|
||||
//
|
||||
// It("returns an error when asking for an attribute that does not exist", func() {
|
||||
// config, _ := cfg.NewConfig("public")
|
||||
// blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||
// contract := testing.SampleContract()
|
||||
//
|
||||
// name, err := blockchain.GetAttribute(contract, "missing_attribute", nil)
|
||||
//
|
||||
// Expect(err).To(Equal(geth.ErrInvalidStateAttribute))
|
||||
// Expect(name).To(BeNil())
|
||||
// })
|
||||
// })
|
||||
//
|
||||
//})
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||
"github.com/8thlight/vulcanizedb/pkg/geth/node"
|
||||
"github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
@ -22,6 +23,21 @@ type GethBlockchain struct {
|
||||
node core.Node
|
||||
}
|
||||
|
||||
func (blockchain *GethBlockchain) GetLogs(contract core.Contract, blockNumber *big.Int) ([]core.Log, error) {
|
||||
contractAddress := common.HexToAddress(contract.Hash)
|
||||
fc := ethereum.FilterQuery{
|
||||
FromBlock: blockNumber,
|
||||
ToBlock: blockNumber,
|
||||
Addresses: []common.Address{contractAddress},
|
||||
}
|
||||
gethLogs, err := blockchain.client.FilterLogs(context.Background(), fc)
|
||||
if err != nil {
|
||||
return []core.Log{}, err
|
||||
}
|
||||
logs := GethLogsToCoreLogs(gethLogs)
|
||||
return logs, nil
|
||||
}
|
||||
|
||||
func (blockchain *GethBlockchain) Node() core.Node {
|
||||
return blockchain.node
|
||||
}
|
||||
@ -60,3 +76,8 @@ func (blockchain *GethBlockchain) StartListening() {
|
||||
func (blockchain *GethBlockchain) StopListening() {
|
||||
blockchain.newHeadSubscription.Unsubscribe()
|
||||
}
|
||||
|
||||
func (blockchain *GethBlockchain) latestBlock() *big.Int {
|
||||
block, _ := blockchain.client.HeaderByNumber(context.Background(), nil)
|
||||
return block.Number
|
||||
}
|
||||
|
32
pkg/geth/geth_log_to_core_log.go
Normal file
32
pkg/geth/geth_log_to_core_log.go
Normal file
@ -0,0 +1,32 @@
|
||||
package geth
|
||||
|
||||
import (
|
||||
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
func GethLogToCoreLog(gethLog types.Log) core.Log {
|
||||
topics := gethLog.Topics
|
||||
var hexTopics []string
|
||||
for _, topic := range topics {
|
||||
hexTopics = append(hexTopics, topic.Hex())
|
||||
}
|
||||
return core.Log{
|
||||
Address: gethLog.Address.Hex(),
|
||||
|
||||
BlockNumber: int64(gethLog.BlockNumber),
|
||||
Topics: hexTopics,
|
||||
TxHash: gethLog.TxHash.Hex(),
|
||||
Data: hexutil.Encode(gethLog.Data),
|
||||
}
|
||||
}
|
||||
|
||||
func GethLogsToCoreLogs(gethLogs []types.Log) []core.Log {
|
||||
var logs []core.Log
|
||||
for _, log := range gethLogs {
|
||||
log := GethLogToCoreLog(log)
|
||||
logs = append(logs, log)
|
||||
}
|
||||
return logs
|
||||
}
|
91
pkg/geth/geth_log_to_core_log_test.go
Normal file
91
pkg/geth/geth_log_to_core_log_test.go
Normal file
@ -0,0 +1,91 @@
|
||||
package geth_test
|
||||
|
||||
import (
|
||||
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||
"github.com/8thlight/vulcanizedb/pkg/geth"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Conversion of GethLog to core.Log", func() {
|
||||
|
||||
It("converts geth log to internal log format", func() {
|
||||
gethLog := types.Log{
|
||||
Address: common.HexToAddress("0xecf8f87f810ecf450940c9f60066b4a7a501d6a7"),
|
||||
BlockHash: common.HexToHash("0x656c34545f90a730a19008c0e7a7cd4fb3895064b48d6d69761bd5abad681056"),
|
||||
BlockNumber: 2019236,
|
||||
Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000001a055690d9db80000"),
|
||||
Index: 2,
|
||||
TxIndex: 3,
|
||||
TxHash: common.HexToHash("0x3b198bfd5d2907285af009e9ae84a0ecd63677110d89d7e030251acb87f6487e"),
|
||||
Topics: []common.Hash{
|
||||
common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
|
||||
common.HexToHash("0x00000000000000000000000080b2c9d7cbbf30a1b0fc8983c647d754c6525615"),
|
||||
},
|
||||
}
|
||||
|
||||
expected := core.Log{
|
||||
Address: gethLog.Address.Hex(),
|
||||
BlockNumber: int64(gethLog.BlockNumber),
|
||||
Data: hexutil.Encode(gethLog.Data),
|
||||
TxHash: gethLog.TxHash.Hex(),
|
||||
Topics: []string{
|
||||
common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef").Hex(),
|
||||
common.HexToHash("0x00000000000000000000000080b2c9d7cbbf30a1b0fc8983c647d754c6525615").Hex(),
|
||||
},
|
||||
}
|
||||
|
||||
coreLog := geth.GethLogToCoreLog(gethLog)
|
||||
|
||||
Expect(coreLog.Address).To(Equal(expected.Address))
|
||||
Expect(coreLog.BlockNumber).To(Equal(expected.BlockNumber))
|
||||
Expect(coreLog.Data).To(Equal(expected.Data))
|
||||
Expect(coreLog.Topics[0]).To(Equal(expected.Topics[0]))
|
||||
Expect(coreLog.Topics[1]).To(Equal(expected.Topics[1]))
|
||||
Expect(coreLog.TxHash).To(Equal(expected.TxHash))
|
||||
})
|
||||
|
||||
It("converts geth log array to array of internal logs", func() {
|
||||
gethLogOne := types.Log{
|
||||
Address: common.HexToAddress("0xecf8f87f810ecf450940c9f60066b4a7a501d6a7"),
|
||||
BlockHash: common.HexToHash("0x656c34545f90a730a19008c0e7a7cd4fb3895064b48d6d69761bd5abad681056"),
|
||||
BlockNumber: 2019236,
|
||||
Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000001a055690d9db80000"),
|
||||
Index: 2,
|
||||
TxIndex: 3,
|
||||
TxHash: common.HexToHash("0x3b198bfd5d2907285af009e9ae84a0ecd63677110d89d7e030251acb87f6487e"),
|
||||
Topics: []common.Hash{
|
||||
common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
|
||||
common.HexToHash("0x00000000000000000000000080b2c9d7cbbf30a1b0fc8983c647d754c6525615"),
|
||||
},
|
||||
}
|
||||
|
||||
gethLogTwo := types.Log{
|
||||
Address: common.HexToAddress("0x123"),
|
||||
BlockHash: common.HexToHash("0x576"),
|
||||
BlockNumber: 2019236,
|
||||
Data: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000001"),
|
||||
Index: 3,
|
||||
TxIndex: 4,
|
||||
TxHash: common.HexToHash("0x134"),
|
||||
Topics: []common.Hash{
|
||||
common.HexToHash("0xaaa"),
|
||||
common.HexToHash("0xbbb"),
|
||||
},
|
||||
}
|
||||
|
||||
expectedOne := geth.GethLogToCoreLog(gethLogOne)
|
||||
expectedTwo := geth.GethLogToCoreLog(gethLogTwo)
|
||||
|
||||
coreLogs := geth.GethLogsToCoreLogs([]types.Log{gethLogOne, gethLogTwo})
|
||||
|
||||
Expect(len(coreLogs)).To(Equal(2))
|
||||
Expect(coreLogs[0]).To(Equal(expectedOne))
|
||||
Expect(coreLogs[1]).To(Equal(expectedTwo))
|
||||
|
||||
})
|
||||
|
||||
})
|
Loading…
Reference in New Issue
Block a user