forked from cerc-io/ipld-eth-server
Consolidate test doubles
- Migrate various mocks of core namespaces to shared version in `fakes` pkg - Err on the side of making test doubles less sophisticated - Don't pull over mocks of namespaces that are only used in example code
This commit is contained in:
parent
5fe6394406
commit
ba071ef13f
20
cmd/erc20.go
20
cmd/erc20.go
@ -15,18 +15,20 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||
"github.com/vulcanize/vulcanizedb/libraries/shared"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
vRpc "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// erc20Cmd represents the erc20 command
|
||||
@ -54,15 +56,15 @@ Expects an ethereum node to be running and requires a .toml config file:
|
||||
func watchERC20s() {
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
defer ticker.Stop()
|
||||
rpcClient, err := rpc.Dial(ipc)
|
||||
rawRpcClient, err := rpc.Dial(ipc)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ethClient := ethclient.NewClient(rpcClient)
|
||||
client := client.NewClient(ethClient)
|
||||
clientWrapper := node.ClientWrapper{ContextCaller: rpcClient, IPCPath: ipc}
|
||||
node := node.MakeNode(clientWrapper)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, ipc)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
client := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := vRpc.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(client, node, transactionConverter)
|
||||
db, err := postgres.NewDB(databaseConfig, blockChain.Node())
|
||||
if err != nil {
|
||||
|
@ -15,21 +15,23 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
vRpc "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/history"
|
||||
"github.com/vulcanize/vulcanizedb/utils"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// lightSyncCmd represents the lightSync command
|
||||
@ -61,22 +63,22 @@ func init() {
|
||||
lightSyncCmd.Flags().Int64VarP(&startingBlockNumber, "starting-block-number", "s", 0, "Block number to start syncing from")
|
||||
}
|
||||
|
||||
func backFillAllHeaders(blockchain core.Blockchain, headerRepository datastore.HeaderRepository, missingBlocksPopulated chan int, startingBlockNumber int64) {
|
||||
func backFillAllHeaders(blockchain core.BlockChain, headerRepository datastore.HeaderRepository, missingBlocksPopulated chan int, startingBlockNumber int64) {
|
||||
missingBlocksPopulated <- history.PopulateMissingHeaders(blockchain, headerRepository, startingBlockNumber)
|
||||
}
|
||||
|
||||
func lightSync() {
|
||||
ticker := time.NewTicker(pollingInterval)
|
||||
defer ticker.Stop()
|
||||
rpcClient, err := rpc.Dial(ipc)
|
||||
rawRpcClient, err := rpc.Dial(ipc)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ethClient := ethclient.NewClient(rpcClient)
|
||||
client := client.NewClient(ethClient)
|
||||
clientWrapper := node.ClientWrapper{ContextCaller: rpcClient, IPCPath: ipc}
|
||||
node := node.MakeNode(clientWrapper)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, ipc)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
client := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := vRpc.NewRpcTransactionConverter(client)
|
||||
blockChain := geth.NewBlockChain(client, node, transactionConverter)
|
||||
|
||||
lastBlock := blockChain.LastBlock().Int64()
|
||||
|
23
cmd/sync.go
23
cmd/sync.go
@ -15,21 +15,20 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"time"
|
||||
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
vRpc "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/history"
|
||||
"github.com/vulcanize/vulcanizedb/utils"
|
||||
@ -70,22 +69,22 @@ func init() {
|
||||
syncCmd.Flags().Int64VarP(&startingBlockNumber, "starting-block-number", "s", 0, "Block number to start syncing from")
|
||||
}
|
||||
|
||||
func backFillAllBlocks(blockchain core.Blockchain, blockRepository datastore.BlockRepository, missingBlocksPopulated chan int, startingBlockNumber int64) {
|
||||
func backFillAllBlocks(blockchain core.BlockChain, blockRepository datastore.BlockRepository, missingBlocksPopulated chan int, startingBlockNumber int64) {
|
||||
missingBlocksPopulated <- history.PopulateMissingBlocks(blockchain, blockRepository, startingBlockNumber)
|
||||
}
|
||||
|
||||
func sync() {
|
||||
ticker := time.NewTicker(pollingInterval)
|
||||
defer ticker.Stop()
|
||||
rpcClient, err := rpc.Dial(ipc)
|
||||
rawRpcClient, err := rpc.Dial(ipc)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ethClient := ethclient.NewClient(rpcClient)
|
||||
client := client.NewClient(ethClient)
|
||||
clientWrapper := node.ClientWrapper{ContextCaller: rpcClient, IPCPath: ipc}
|
||||
node := node.MakeNode(clientWrapper)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, ipc)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
client := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := vRpc.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(client, node, transactionConverter)
|
||||
|
||||
lastBlock := blockChain.LastBlock().Int64()
|
||||
|
@ -16,24 +16,25 @@ package every_block
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"log"
|
||||
"math/big"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
type ERC20FetcherInterface interface {
|
||||
FetchSupplyOf(contractAbi string, contractAddress string, blockNumber int64) (big.Int, error)
|
||||
GetBlockchain() core.Blockchain
|
||||
GetBlockChain() core.BlockChain
|
||||
}
|
||||
|
||||
func NewFetcher(blockchain core.Blockchain) Fetcher {
|
||||
func NewFetcher(blockchain core.BlockChain) Fetcher {
|
||||
return Fetcher{
|
||||
Blockchain: blockchain,
|
||||
}
|
||||
}
|
||||
|
||||
type Fetcher struct {
|
||||
Blockchain core.Blockchain
|
||||
Blockchain core.BlockChain
|
||||
ContractAbi string
|
||||
ContractAddress string
|
||||
}
|
||||
@ -65,6 +66,6 @@ func (f Fetcher) FetchSupplyOf(contractAbi string, contractAddress string, block
|
||||
return *result, nil
|
||||
}
|
||||
|
||||
func (f Fetcher) GetBlockchain() core.Blockchain {
|
||||
func (f Fetcher) GetBlockChain() core.BlockChain {
|
||||
return f.Blockchain
|
||||
}
|
||||
|
@ -15,68 +15,50 @@
|
||||
package every_block_test
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||
"github.com/vulcanize/vulcanizedb/examples/mocks"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var _ = Describe("ERC20 Fetcher", func() {
|
||||
blockNumber := int64(5502914)
|
||||
infuraIPC := "https://mainnet.infura.io/J5Vd2fRtGsw0zZ0Ov3BL"
|
||||
var errorFetcher every_block.Fetcher
|
||||
var realFetcher every_block.Fetcher
|
||||
var testFetcher every_block.Fetcher
|
||||
var fakeBlockchain *mocks.Blockchain
|
||||
var testAbi string
|
||||
var testContractAddress string
|
||||
|
||||
BeforeEach(func() {
|
||||
rpcClient, err := rpc.Dial(infuraIPC)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
ethClient := ethclient.NewClient(rpcClient)
|
||||
blockChainClient := client.NewClient(ethClient)
|
||||
clientWrapper := node.ClientWrapper{
|
||||
ContextCaller: rpcClient,
|
||||
IPCPath: infuraIPC,
|
||||
}
|
||||
node := node.MakeNode(clientWrapper)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
realBlockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
realFetcher = every_block.NewFetcher(realBlockChain)
|
||||
fakeBlockchain = &mocks.Blockchain{}
|
||||
testFetcher = every_block.NewFetcher(fakeBlockchain)
|
||||
testAbi = "testAbi"
|
||||
testContractAddress = "testContractAddress"
|
||||
|
||||
errorBlockchain := &mocks.FailureBlockchain{}
|
||||
errorFetcher = every_block.NewFetcher(errorBlockchain)
|
||||
})
|
||||
|
||||
Describe("FetchSupplyOf", func() {
|
||||
It("fetches data from the blockchain with the correct arguments", func() {
|
||||
fakeBlockchain := fakes.NewMockBlockChain()
|
||||
testFetcher := every_block.NewFetcher(fakeBlockchain)
|
||||
testAbi := "testAbi"
|
||||
testContractAddress := "testContractAddress"
|
||||
_, err := testFetcher.FetchSupplyOf(testAbi, testContractAddress, blockNumber)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fakeBlockchain.FetchedAbi).To(Equal(testAbi))
|
||||
Expect(fakeBlockchain.FetchedContractAddress).To(Equal(testContractAddress))
|
||||
Expect(fakeBlockchain.FetchedMethod).To(Equal("totalSupply"))
|
||||
Expect(fakeBlockchain.FetchedMethodArg).To(BeNil())
|
||||
expectedResult := big.Int{}
|
||||
expected := &expectedResult
|
||||
Expect(fakeBlockchain.FetchedResult).To(Equal(&expected))
|
||||
Expect(fakeBlockchain.FetchedBlockNumber).To(Equal(blockNumber))
|
||||
fakeBlockchain.AssertFetchContractDataCalledWith(testAbi, testContractAddress, "totalSupply", nil, &expected, blockNumber)
|
||||
})
|
||||
|
||||
It("fetches a token's total supply at the given block height", func() {
|
||||
infuraIPC := "https://mainnet.infura.io/J5Vd2fRtGsw0zZ0Ov3BL"
|
||||
rawRpcClient, err := rpc.Dial(infuraIPC)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, infuraIPC)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
realFetcher := every_block.NewFetcher(blockChain)
|
||||
result, err := realFetcher.FetchSupplyOf(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@ -86,12 +68,15 @@ var _ = Describe("ERC20 Fetcher", func() {
|
||||
})
|
||||
|
||||
It("returns an error if the call to the blockchain fails", func() {
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetFetchContractDataErr(fakes.FakeError)
|
||||
errorFetcher := every_block.NewFetcher(blockChain)
|
||||
result, err := errorFetcher.FetchSupplyOf("", "", 0)
|
||||
|
||||
Expect(result.String()).To(Equal("0"))
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("totalSupply"))
|
||||
Expect(err.Error()).To(ContainSubstring(mocks.TestError.Error()))
|
||||
Expect(err.Error()).To(ContainSubstring(fakes.FakeError.Error()))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -20,34 +20,35 @@ import (
|
||||
"github.com/vulcanize/vulcanizedb/examples/constants"
|
||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher"
|
||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||
"github.com/vulcanize/vulcanizedb/examples/mocks"
|
||||
"github.com/vulcanize/vulcanizedb/examples/test_helpers"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"math/big"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func setLastBlockOnChain(blockchain *mocks.Blockchain, blockNumber int64) {
|
||||
func setLastBlockOnChain(blockChain *fakes.MockBlockChain, blockNumber int64) {
|
||||
blockNumberString := strconv.FormatInt(blockNumber, 10)
|
||||
lastBlockOnChain := big.Int{}
|
||||
lastBlockOnChain.SetString(blockNumberString, 10)
|
||||
blockchain.SetLastBlock(&lastBlockOnChain)
|
||||
blockChain.SetLastBlock(&lastBlockOnChain)
|
||||
}
|
||||
|
||||
var _ = Describe("Everyblock transformers", func() {
|
||||
var db *postgres.DB
|
||||
var blockchain mocks.Blockchain
|
||||
var blockChain *fakes.MockBlockChain
|
||||
var blockNumber int64
|
||||
var blockId int64
|
||||
var err error
|
||||
|
||||
BeforeEach(func() {
|
||||
blockChain = fakes.NewMockBlockChain()
|
||||
blockNumber = erc20_watcher.DaiConfig.FirstBlock
|
||||
lastBlockNumber := blockNumber + 1
|
||||
db = test_helpers.CreateNewDatabase()
|
||||
setLastBlockOnChain(&blockchain, lastBlockNumber)
|
||||
setLastBlockOnChain(blockChain, lastBlockNumber)
|
||||
|
||||
blockRepository := repositories.NewBlockRepository(db)
|
||||
|
||||
@ -59,7 +60,7 @@ var _ = Describe("Everyblock transformers", func() {
|
||||
|
||||
It("creates a token_supply record for each block in the given range", func() {
|
||||
initializer := every_block.TokenSupplyTransformerInitializer{Config: erc20_watcher.DaiConfig}
|
||||
transformer := initializer.NewTokenSupplyTransformer(db, &blockchain)
|
||||
transformer := initializer.NewTokenSupplyTransformer(db, blockChain)
|
||||
transformer.Execute()
|
||||
|
||||
var tokenSupplyCount int
|
||||
|
@ -38,7 +38,7 @@ type TokenSupplyTransformerInitializer struct {
|
||||
Config erc20_watcher.ContractConfig
|
||||
}
|
||||
|
||||
func (i TokenSupplyTransformerInitializer) NewTokenSupplyTransformer(db *postgres.DB, blockchain core.Blockchain) shared.Transformer {
|
||||
func (i TokenSupplyTransformerInitializer) NewTokenSupplyTransformer(db *postgres.DB, blockchain core.BlockChain) shared.Transformer {
|
||||
fetcher := NewFetcher(blockchain)
|
||||
repository := TokenSupplyRepository{DB: db}
|
||||
transformer := Transformer{
|
||||
@ -74,7 +74,7 @@ func newTransformerError(err error, blockNumber int64, msg string) error {
|
||||
|
||||
func (t Transformer) Execute() error {
|
||||
var upperBoundBlock int64
|
||||
blockchain := t.Fetcher.GetBlockchain()
|
||||
blockchain := t.Fetcher.GetBlockChain()
|
||||
lastBlock := blockchain.LastBlock().Int64()
|
||||
|
||||
if t.Config.LastBlock == -1 {
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher"
|
||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||
"github.com/vulcanize/vulcanizedb/examples/mocks"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
@ -40,7 +41,7 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
var fetcher mocks.Fetcher
|
||||
var repository mocks.TotalSupplyRepository
|
||||
var transformer every_block.Transformer
|
||||
var blockchain mocks.Blockchain
|
||||
var blockChain *fakes.MockBlockChain
|
||||
var initialSupply = "27647235749155415536952630"
|
||||
var initialSupplyPlusOne = "27647235749155415536952631"
|
||||
var initialSupplyPlusTwo = "27647235749155415536952632"
|
||||
@ -48,9 +49,9 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
var defaultLastBlock = big.Int{}
|
||||
|
||||
BeforeEach(func() {
|
||||
blockchain = mocks.Blockchain{}
|
||||
blockchain.SetLastBlock(&defaultLastBlock)
|
||||
fetcher = mocks.Fetcher{Blockchain: &blockchain}
|
||||
blockChain = fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(&defaultLastBlock)
|
||||
fetcher = mocks.Fetcher{BlockChain: blockChain}
|
||||
fetcher.SetSupply(initialSupply)
|
||||
repository = mocks.TotalSupplyRepository{}
|
||||
repository.SetMissingBlocks([]int64{config.FirstBlock})
|
||||
@ -132,7 +133,7 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
mostRecentBlock := big.Int{}
|
||||
mostRecentBlock.SetString(numberToString, 10)
|
||||
|
||||
blockchain.SetLastBlock(&mostRecentBlock)
|
||||
blockChain.SetLastBlock(&mostRecentBlock)
|
||||
|
||||
err := transformer.Execute()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@ -149,13 +150,14 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
}
|
||||
err := transformer.Execute()
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("TestError"))
|
||||
Expect(err.Error()).To(ContainSubstring(fakes.FakeError.Error()))
|
||||
Expect(err.Error()).To(ContainSubstring("fetching missing blocks"))
|
||||
})
|
||||
|
||||
It("returns an error if the call to the blockchain fails", func() {
|
||||
failureBlockchain := mocks.FailureBlockchain{}
|
||||
It("returns an error if the call to the blockChain fails", func() {
|
||||
failureBlockchain := fakes.NewMockBlockChain()
|
||||
failureBlockchain.SetLastBlock(&defaultLastBlock)
|
||||
failureBlockchain.SetFetchContractDataErr(fakes.FakeError)
|
||||
fetcher := every_block.NewFetcher(failureBlockchain)
|
||||
transformer = every_block.Transformer{
|
||||
Fetcher: &fetcher,
|
||||
@ -163,7 +165,7 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
}
|
||||
err := transformer.Execute()
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("TestError"))
|
||||
Expect(err.Error()).To(ContainSubstring(fakes.FakeError.Error()))
|
||||
Expect(err.Error()).To(ContainSubstring("supply"))
|
||||
})
|
||||
|
||||
@ -178,7 +180,7 @@ var _ = Describe("Everyblock transformer", func() {
|
||||
}
|
||||
err := transformer.Execute()
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("TestError"))
|
||||
Expect(err.Error()).To(ContainSubstring(fakes.FakeError.Error()))
|
||||
Expect(err.Error()).To(ContainSubstring("supply"))
|
||||
})
|
||||
})
|
||||
|
@ -15,19 +15,18 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"math/big"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
)
|
||||
|
||||
var TestError = errors.New("TestError")
|
||||
|
||||
type Fetcher struct {
|
||||
ContractAddress string
|
||||
Abi string
|
||||
FetchedBlocks []int64
|
||||
Blockchain core.Blockchain
|
||||
BlockChain core.BlockChain
|
||||
supply big.Int
|
||||
}
|
||||
|
||||
@ -35,8 +34,8 @@ func (f *Fetcher) SetSupply(supply string) {
|
||||
f.supply.SetString(supply, 10)
|
||||
}
|
||||
|
||||
func (f Fetcher) GetBlockchain() core.Blockchain {
|
||||
return f.Blockchain
|
||||
func (f Fetcher) GetBlockChain() core.BlockChain {
|
||||
return f.BlockChain
|
||||
}
|
||||
|
||||
func (f *Fetcher) FetchSupplyOf(contractAbi string, contractAddress string, blockNumber int64) (big.Int, error) {
|
||||
@ -80,7 +79,7 @@ type FailureRepository struct {
|
||||
|
||||
func (fr *FailureRepository) Create(supply every_block.TokenSupply) error {
|
||||
if fr.createFail {
|
||||
return TestError
|
||||
return fakes.FakeError
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
@ -88,7 +87,7 @@ func (fr *FailureRepository) Create(supply every_block.TokenSupply) error {
|
||||
|
||||
func (fr *FailureRepository) MissingBlocks(startingBlock int64, highestBlock int64) ([]int64, error) {
|
||||
if fr.missingBlocksFail {
|
||||
return []int64{}, TestError
|
||||
return []int64{}, fakes.FakeError
|
||||
} else {
|
||||
return fr.missingBlocksNumbers, nil
|
||||
}
|
||||
@ -105,79 +104,3 @@ func (fr *FailureRepository) SetMissingBlocksFail(fail bool) {
|
||||
func (fr *FailureRepository) SetMissingBlocks(missingBlocks []int64) {
|
||||
fr.missingBlocksNumbers = missingBlocks
|
||||
}
|
||||
|
||||
type Blockchain struct {
|
||||
FetchedAbi string
|
||||
FetchedContractAddress string
|
||||
FetchedMethod string
|
||||
FetchedMethodArg interface{}
|
||||
FetchedResult interface{}
|
||||
FetchedBlockNumber int64
|
||||
lastBlock *big.Int
|
||||
}
|
||||
|
||||
func (fb *Blockchain) GetHeaderByNumber(blockNumber int64) (core.Header, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (fb *Blockchain) FetchContractData(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) error {
|
||||
fb.FetchedAbi = abiJSON
|
||||
fb.FetchedContractAddress = address
|
||||
fb.FetchedMethod = method
|
||||
fb.FetchedMethodArg = methodArg
|
||||
fb.FetchedResult = result
|
||||
fb.FetchedBlockNumber = blockNumber
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fb *Blockchain) GetBlockByNumber(blockNumber int64) (core.Block, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (fb *Blockchain) GetLogs(contract core.Contract, startingBlockNumber *big.Int, endingBlockNumber *big.Int) ([]core.Log, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (fb *Blockchain) LastBlock() *big.Int {
|
||||
return fb.lastBlock
|
||||
}
|
||||
|
||||
func (fb *Blockchain) Node() core.Node {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (fb *Blockchain) SetLastBlock(lastBlock *big.Int) {
|
||||
fb.lastBlock = lastBlock
|
||||
}
|
||||
|
||||
type FailureBlockchain struct {
|
||||
lastBlock *big.Int
|
||||
}
|
||||
|
||||
func (fb FailureBlockchain) GetHeaderByNumber(blockNumber int64) (core.Header, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (FailureBlockchain) FetchContractData(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) error {
|
||||
return errors.New("TestError")
|
||||
}
|
||||
|
||||
func (FailureBlockchain) GetBlockByNumber(blockNumber int64) (core.Block, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (FailureBlockchain) GetLogs(contract core.Contract, startingBlockNumber *big.Int, endingBlockNumber *big.Int) ([]core.Log, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (fb FailureBlockchain) LastBlock() *big.Int {
|
||||
return fb.lastBlock
|
||||
}
|
||||
|
||||
func (FailureBlockchain) Node() core.Node {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (fb *FailureBlockchain) SetLastBlock(lastBlock *big.Int) {
|
||||
fb.lastBlock = lastBlock
|
||||
}
|
||||
|
@ -5,9 +5,10 @@ import (
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
vRpc "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||
"github.com/vulcanize/vulcanizedb/test_config"
|
||||
)
|
||||
@ -15,16 +16,13 @@ import (
|
||||
var _ = Describe("Rewards calculations", func() {
|
||||
|
||||
It("calculates a block reward for a real block", func() {
|
||||
rpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
rawRpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
ethClient := ethclient.NewClient(rpcClient)
|
||||
blockChainClient := client.NewClient(ethClient)
|
||||
clientWrapper := node.ClientWrapper{
|
||||
ContextCaller: rpcClient,
|
||||
IPCPath: test_config.InfuraClient.IPCPath,
|
||||
}
|
||||
node := node.MakeNode(clientWrapper)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, test_config.InfuraClient.IPCPath)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := vRpc.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
block, err := blockChain.GetBlockByNumber(1071819)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
@ -32,16 +30,13 @@ var _ = Describe("Rewards calculations", func() {
|
||||
})
|
||||
|
||||
It("calculates an uncle reward for a real block", func() {
|
||||
rpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
rawRpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
ethClient := ethclient.NewClient(rpcClient)
|
||||
blockChainClient := client.NewClient(ethClient)
|
||||
clientWrapper := node.ClientWrapper{
|
||||
ContextCaller: rpcClient,
|
||||
IPCPath: test_config.InfuraClient.IPCPath,
|
||||
}
|
||||
node := node.MakeNode(clientWrapper)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, test_config.InfuraClient.IPCPath)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := vRpc.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
block, err := blockChain.GetBlockByNumber(1071819)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -32,15 +32,12 @@ var _ = Describe("Reading contracts", func() {
|
||||
},
|
||||
Index: 19,
|
||||
Data: "0x0000000000000000000000000000000000000000000000000c7d713b49da0000"}
|
||||
rpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
rawRpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
ethClient := ethclient.NewClient(rpcClient)
|
||||
blockChainClient := client.NewClient(ethClient)
|
||||
clientWrapper := node.ClientWrapper{
|
||||
ContextCaller: rpcClient,
|
||||
IPCPath: test_config.InfuraClient.IPCPath,
|
||||
}
|
||||
node := node.MakeNode(clientWrapper)
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, test_config.InfuraClient.IPCPath)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
contract := testing.SampleContract()
|
||||
@ -53,15 +50,12 @@ var _ = Describe("Reading contracts", func() {
|
||||
})
|
||||
|
||||
It("returns and empty log array when no events for a given block / contract combo", func() {
|
||||
rpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
rawRpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
ethClient := ethclient.NewClient(rpcClient)
|
||||
blockChainClient := client.NewClient(ethClient)
|
||||
clientWrapper := node.ClientWrapper{
|
||||
ContextCaller: rpcClient,
|
||||
IPCPath: test_config.InfuraClient.IPCPath,
|
||||
}
|
||||
node := node.MakeNode(clientWrapper)
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, test_config.InfuraClient.IPCPath)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
|
||||
@ -75,15 +69,12 @@ var _ = Describe("Reading contracts", func() {
|
||||
|
||||
Describe("Fetching Contract data", func() {
|
||||
It("returns the correct attribute for a real contract", func() {
|
||||
rpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
rawRpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
ethClient := ethclient.NewClient(rpcClient)
|
||||
blockChainClient := client.NewClient(ethClient)
|
||||
clientWrapper := node.ClientWrapper{
|
||||
ContextCaller: rpcClient,
|
||||
IPCPath: test_config.InfuraClient.IPCPath,
|
||||
}
|
||||
node := node.MakeNode(clientWrapper)
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, test_config.InfuraClient.IPCPath)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/inmemory"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
@ -17,29 +17,24 @@ import (
|
||||
|
||||
var _ = Describe("Reading from the Geth blockchain", func() {
|
||||
var blockChain *geth.BlockChain
|
||||
var inMemory *inmemory.InMemory
|
||||
|
||||
BeforeEach(func() {
|
||||
rpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
rawRpcClient, err := rpc.Dial(test_config.InfuraClient.IPCPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
ethClient := ethclient.NewClient(rpcClient)
|
||||
blockChainClient := client.NewClient(ethClient)
|
||||
clientWrapper := node.ClientWrapper{
|
||||
ContextCaller: rpcClient,
|
||||
IPCPath: test_config.InfuraClient.IPCPath,
|
||||
}
|
||||
node := node.MakeNode(clientWrapper)
|
||||
rpcClient := client.NewRpcClient(rawRpcClient, test_config.InfuraClient.IPCPath)
|
||||
ethClient := ethclient.NewClient(rawRpcClient)
|
||||
blockChainClient := client.NewEthClient(ethClient)
|
||||
node := node.MakeNode(rpcClient)
|
||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||
blockChain = geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
||||
inMemory = inmemory.NewInMemory()
|
||||
})
|
||||
|
||||
It("reads two blocks", func(done Done) {
|
||||
blocks := &inmemory.BlockRepository{InMemory: inMemory}
|
||||
blocks := fakes.NewMockBlockRepository()
|
||||
lastBlock := blockChain.LastBlock()
|
||||
queriedBlocks := []int64{lastBlock.Int64() - 5, lastBlock.Int64() - 6}
|
||||
history.RetrieveAndUpdateBlocks(blockChain, blocks, queriedBlocks)
|
||||
Expect(blocks.BlockCount()).To(Equal(2))
|
||||
blocks.AssertCreateOrUpdateBlocksCallCountAndBlockNumbersEquals(2, []int64{lastBlock.Int64() - 5, lastBlock.Int64() - 6})
|
||||
close(done)
|
||||
}, 30)
|
||||
|
||||
|
@ -10,7 +10,7 @@ type Transformer interface {
|
||||
Execute() error
|
||||
}
|
||||
|
||||
type TransformerInitializer func(db *postgres.DB, blockchain core.Blockchain) Transformer
|
||||
type TransformerInitializer func(db *postgres.DB, blockchain core.BlockChain) Transformer
|
||||
|
||||
func HexToInt64(byteString string) int64 {
|
||||
value := common.HexToHash(byteString)
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
type Watcher struct {
|
||||
Transformers []Transformer
|
||||
DB postgres.DB
|
||||
Blockchain core.Blockchain
|
||||
Blockchain core.BlockChain
|
||||
}
|
||||
|
||||
func (watcher *Watcher) AddTransformers(us []TransformerInitializer) {
|
||||
|
@ -23,7 +23,7 @@ func (mh *MockTransformer) Execute() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func fakeTransformerInitializer(db *postgres.DB, blockchain core.Blockchain) shared.Transformer {
|
||||
func fakeTransformerInitializer(db *postgres.DB, blockchain core.BlockChain) shared.Transformer {
|
||||
return &MockTransformer{}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ package core
|
||||
|
||||
import "math/big"
|
||||
|
||||
type Blockchain interface {
|
||||
type BlockChain interface {
|
||||
ContractDataFetcher
|
||||
GetBlockByNumber(blockNumber int64) (Block, error)
|
||||
GetHeaderByNumber(blockNumber int64) (Header, error)
|
||||
|
@ -5,12 +5,15 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
type EthClient interface {
|
||||
BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
|
||||
CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
|
||||
FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)
|
||||
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
|
||||
TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error)
|
||||
TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
|
||||
}
|
9
pkg/core/rpc_client.go
Normal file
9
pkg/core/rpc_client.go
Normal file
@ -0,0 +1,9 @@
|
||||
package core
|
||||
|
||||
import "context"
|
||||
|
||||
type RpcClient interface {
|
||||
CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
|
||||
IpcPath() string
|
||||
SupportedModules() (map[string]string, error)
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package inmemory
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
)
|
||||
|
||||
type BlockRepository struct {
|
||||
*InMemory
|
||||
}
|
||||
|
||||
func (blockRepository *BlockRepository) CreateOrUpdateBlock(block core.Block) (int64, 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 0, nil
|
||||
}
|
||||
|
||||
func (blockRepository *BlockRepository) GetBlock(blockNumber int64) (core.Block, error) {
|
||||
if block, ok := blockRepository.blocks[blockNumber]; ok {
|
||||
return block, nil
|
||||
}
|
||||
return core.Block{}, datastore.ErrBlockDoesNotExist(blockNumber)
|
||||
}
|
||||
|
||||
func (blockRepository *BlockRepository) MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64, nodeId string) []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)
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package inmemory
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
)
|
||||
|
||||
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{}, datastore.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,30 +0,0 @@
|
||||
package inmemory
|
||||
|
||||
import "github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
|
||||
type HeaderRepository struct {
|
||||
memory *InMemory
|
||||
}
|
||||
|
||||
func NewHeaderRepository(memory *InMemory) *HeaderRepository {
|
||||
return &HeaderRepository{memory: memory}
|
||||
}
|
||||
|
||||
func (repository *HeaderRepository) CreateOrUpdateHeader(header core.Header) (int64, error) {
|
||||
repository.memory.headers[header.BlockNumber] = header
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (repository *HeaderRepository) GetHeader(blockNumber int64) (core.Header, error) {
|
||||
return repository.memory.headers[blockNumber], nil
|
||||
}
|
||||
|
||||
func (repository *HeaderRepository) MissingBlockNumbers(startingBlockNumber, endingBlockNumber int64, nodeID string) []int64 {
|
||||
missingNumbers := []int64{}
|
||||
for blockNumber := int64(startingBlockNumber); blockNumber <= endingBlockNumber; blockNumber++ {
|
||||
if _, ok := repository.memory.headers[blockNumber]; !ok {
|
||||
missingNumbers = append(missingNumbers, blockNumber)
|
||||
}
|
||||
}
|
||||
return missingNumbers
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package inmemory
|
||||
|
||||
import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/filters"
|
||||
)
|
||||
|
||||
const (
|
||||
blocksFromHeadBeforeFinal = 20
|
||||
)
|
||||
|
||||
type InMemory struct {
|
||||
CreateOrUpdateBlockCallCount int
|
||||
blocks map[int64]core.Block
|
||||
contracts map[string]core.Contract
|
||||
headers map[int64]core.Header
|
||||
logFilters map[string]filters.LogFilter
|
||||
logs map[string][]core.Log
|
||||
receipts map[string]core.Receipt
|
||||
}
|
||||
|
||||
func NewInMemory() *InMemory {
|
||||
return &InMemory{
|
||||
CreateOrUpdateBlockCallCount: 0,
|
||||
blocks: make(map[int64]core.Block),
|
||||
contracts: make(map[string]core.Contract),
|
||||
headers: make(map[int64]core.Header),
|
||||
logFilters: make(map[string]filters.LogFilter),
|
||||
logs: make(map[string][]core.Log),
|
||||
receipts: make(map[string]core.Receipt),
|
||||
}
|
||||
}
|
@ -7,14 +7,16 @@ import (
|
||||
)
|
||||
|
||||
type MockBlockRepository struct {
|
||||
createOrUpdateBlockCallCount int
|
||||
createOrUpdateBlockCalled bool
|
||||
createOrUpdateBlockPassedBlock core.Block
|
||||
createOrUpdateBlockReturnInt int64
|
||||
createOrUpdateBlockPassedBlockNumbers []int64
|
||||
createOrUpdateBlockReturnErr error
|
||||
createOrUpdateBlockReturnInt int64
|
||||
missingBlockNumbersCalled bool
|
||||
missingBlockNumbersPassedStartingBlockNumber int64
|
||||
missingBlockNumbersPassedEndingBlockNumber int64
|
||||
missingBlockNumbersPassedNodeId string
|
||||
missingBlockNumbersPassedStartingBlockNumber int64
|
||||
missingBlockNumbersReturnArray []int64
|
||||
setBlockStatusCalled bool
|
||||
setBlockStatusPassedChainHead int64
|
||||
@ -22,65 +24,78 @@ type MockBlockRepository struct {
|
||||
|
||||
func NewMockBlockRepository() *MockBlockRepository {
|
||||
return &MockBlockRepository{
|
||||
createOrUpdateBlockCallCount: 0,
|
||||
createOrUpdateBlockCalled: false,
|
||||
createOrUpdateBlockPassedBlock: core.Block{},
|
||||
createOrUpdateBlockReturnInt: 0,
|
||||
createOrUpdateBlockPassedBlockNumbers: nil,
|
||||
createOrUpdateBlockReturnErr: nil,
|
||||
createOrUpdateBlockReturnInt: 0,
|
||||
missingBlockNumbersCalled: false,
|
||||
missingBlockNumbersPassedStartingBlockNumber: 0,
|
||||
missingBlockNumbersPassedEndingBlockNumber: 0,
|
||||
missingBlockNumbersPassedNodeId: "",
|
||||
missingBlockNumbersPassedStartingBlockNumber: 0,
|
||||
missingBlockNumbersReturnArray: nil,
|
||||
setBlockStatusCalled: false,
|
||||
setBlockStatusPassedChainHead: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (mbr *MockBlockRepository) SetCreateOrUpdateBlockReturnVals(i int64, err error) {
|
||||
mbr.createOrUpdateBlockReturnInt = i
|
||||
mbr.createOrUpdateBlockReturnErr = err
|
||||
func (repository *MockBlockRepository) SetCreateOrUpdateBlockReturnVals(i int64, err error) {
|
||||
repository.createOrUpdateBlockReturnInt = i
|
||||
repository.createOrUpdateBlockReturnErr = err
|
||||
}
|
||||
|
||||
func (mbr *MockBlockRepository) SetMissingBlockNumbersReturnArray(returnArray []int64) {
|
||||
mbr.missingBlockNumbersReturnArray = returnArray
|
||||
func (repository *MockBlockRepository) SetMissingBlockNumbersReturnArray(returnArray []int64) {
|
||||
repository.missingBlockNumbersReturnArray = returnArray
|
||||
}
|
||||
|
||||
func (mbr *MockBlockRepository) CreateOrUpdateBlock(block core.Block) (int64, error) {
|
||||
mbr.createOrUpdateBlockCalled = true
|
||||
mbr.createOrUpdateBlockPassedBlock = block
|
||||
return mbr.createOrUpdateBlockReturnInt, mbr.createOrUpdateBlockReturnErr
|
||||
func (repository *MockBlockRepository) CreateOrUpdateBlock(block core.Block) (int64, error) {
|
||||
repository.createOrUpdateBlockCallCount++
|
||||
repository.createOrUpdateBlockCalled = true
|
||||
repository.createOrUpdateBlockPassedBlock = block
|
||||
repository.createOrUpdateBlockPassedBlockNumbers = append(repository.createOrUpdateBlockPassedBlockNumbers, block.Number)
|
||||
return repository.createOrUpdateBlockReturnInt, repository.createOrUpdateBlockReturnErr
|
||||
}
|
||||
|
||||
func (mbr *MockBlockRepository) GetBlock(blockNumber int64) (core.Block, error) {
|
||||
panic("implement me")
|
||||
func (repository *MockBlockRepository) GetBlock(blockNumber int64) (core.Block, error) {
|
||||
return core.Block{Number: blockNumber}, nil
|
||||
}
|
||||
|
||||
func (mbr *MockBlockRepository) MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64, nodeId string) []int64 {
|
||||
mbr.missingBlockNumbersCalled = true
|
||||
mbr.missingBlockNumbersPassedStartingBlockNumber = startingBlockNumber
|
||||
mbr.missingBlockNumbersPassedEndingBlockNumber = endingBlockNumber
|
||||
mbr.missingBlockNumbersPassedNodeId = nodeId
|
||||
return mbr.missingBlockNumbersReturnArray
|
||||
func (repository *MockBlockRepository) MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64, nodeId string) []int64 {
|
||||
repository.missingBlockNumbersCalled = true
|
||||
repository.missingBlockNumbersPassedStartingBlockNumber = startingBlockNumber
|
||||
repository.missingBlockNumbersPassedEndingBlockNumber = endingBlockNumber
|
||||
repository.missingBlockNumbersPassedNodeId = nodeId
|
||||
return repository.missingBlockNumbersReturnArray
|
||||
}
|
||||
|
||||
func (mbr *MockBlockRepository) SetBlocksStatus(chainHead int64) {
|
||||
mbr.setBlockStatusCalled = true
|
||||
mbr.setBlockStatusPassedChainHead = chainHead
|
||||
func (repository *MockBlockRepository) SetBlocksStatus(chainHead int64) {
|
||||
repository.setBlockStatusCalled = true
|
||||
repository.setBlockStatusPassedChainHead = chainHead
|
||||
}
|
||||
|
||||
func (mbr *MockBlockRepository) AssertCreateOrUpdateBlockCalledWith(block core.Block) {
|
||||
Expect(mbr.createOrUpdateBlockCalled).To(BeTrue())
|
||||
Expect(mbr.createOrUpdateBlockPassedBlock).To(Equal(block))
|
||||
func (repository *MockBlockRepository) AssertCreateOrUpdateBlockCallCountEquals(times int) {
|
||||
Expect(repository.createOrUpdateBlockCallCount).To(Equal(times))
|
||||
}
|
||||
|
||||
func (mbr *MockBlockRepository) AssertMissingBlockNumbersCalledWith(startingBlockNumber int64, endingBlockNumber int64, nodeId string) {
|
||||
Expect(mbr.missingBlockNumbersCalled).To(BeTrue())
|
||||
Expect(mbr.missingBlockNumbersPassedStartingBlockNumber).To(Equal(startingBlockNumber))
|
||||
Expect(mbr.missingBlockNumbersPassedEndingBlockNumber).To(Equal(endingBlockNumber))
|
||||
Expect(mbr.missingBlockNumbersPassedNodeId).To(Equal(nodeId))
|
||||
func (repository *MockBlockRepository) AssertCreateOrUpdateBlocksCallCountAndBlockNumbersEquals(times int, blockNumbers []int64) {
|
||||
Expect(repository.createOrUpdateBlockCallCount).To(Equal(times))
|
||||
Expect(repository.createOrUpdateBlockPassedBlockNumbers).To(Equal(blockNumbers))
|
||||
}
|
||||
|
||||
func (mbr *MockBlockRepository) AssertSetBlockStatusCalledWith(chainHead int64) {
|
||||
Expect(mbr.setBlockStatusCalled).To(BeTrue())
|
||||
Expect(mbr.setBlockStatusPassedChainHead).To(Equal(chainHead))
|
||||
func (repository *MockBlockRepository) AssertCreateOrUpdateBlockCalledWith(block core.Block) {
|
||||
Expect(repository.createOrUpdateBlockCalled).To(BeTrue())
|
||||
Expect(repository.createOrUpdateBlockPassedBlock).To(Equal(block))
|
||||
}
|
||||
|
||||
func (repository *MockBlockRepository) AssertMissingBlockNumbersCalledWith(startingBlockNumber int64, endingBlockNumber int64, nodeId string) {
|
||||
Expect(repository.missingBlockNumbersCalled).To(BeTrue())
|
||||
Expect(repository.missingBlockNumbersPassedStartingBlockNumber).To(Equal(startingBlockNumber))
|
||||
Expect(repository.missingBlockNumbersPassedEndingBlockNumber).To(Equal(endingBlockNumber))
|
||||
Expect(repository.missingBlockNumbersPassedNodeId).To(Equal(nodeId))
|
||||
}
|
||||
|
||||
func (repository *MockBlockRepository) AssertSetBlockStatusCalledWith(chainHead int64) {
|
||||
Expect(repository.setBlockStatusCalled).To(BeTrue())
|
||||
Expect(repository.setBlockStatusPassedChainHead).To(Equal(chainHead))
|
||||
}
|
||||
|
@ -3,95 +3,81 @@ package fakes
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
type MockBlockChain struct {
|
||||
ContractReturnValue []byte
|
||||
WasToldToStop bool
|
||||
blocks map[int64]core.Block
|
||||
blocksChannel chan core.Block
|
||||
contractAttributes map[string]map[string]string
|
||||
err error
|
||||
headers map[int64]core.Header
|
||||
logs map[string][]core.Log
|
||||
node core.Node
|
||||
fetchContractDataErr error
|
||||
fetchContractDataPassedAbi string
|
||||
fetchContractDataPassedAddress string
|
||||
fetchContractDataPassedMethod string
|
||||
fetchContractDataPassedMethodArg interface{}
|
||||
fetchContractDataPassedResult interface{}
|
||||
fetchContractDataPassedBlockNumber int64
|
||||
getBlockByNumberErr error
|
||||
lastBlock *big.Int
|
||||
node core.Node
|
||||
}
|
||||
|
||||
func NewMockBlockChain() *MockBlockChain {
|
||||
return &MockBlockChain{
|
||||
node: core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "Geth"},
|
||||
}
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) SetFetchContractDataErr(err error) {
|
||||
blockChain.fetchContractDataErr = err
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) SetLastBlock(blockNumber *big.Int) {
|
||||
blockChain.lastBlock = blockNumber
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) SetGetBlockByNumberErr(err error) {
|
||||
blockChain.getBlockByNumberErr = err
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) GetHeaderByNumber(blockNumber int64) (core.Header, error) {
|
||||
return blockChain.headers[blockNumber], nil
|
||||
return core.Header{BlockNumber: blockNumber}, nil
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) FetchContractData(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) error {
|
||||
panic("implement me")
|
||||
blockChain.fetchContractDataPassedAbi = abiJSON
|
||||
blockChain.fetchContractDataPassedAddress = address
|
||||
blockChain.fetchContractDataPassedMethod = method
|
||||
blockChain.fetchContractDataPassedMethodArg = methodArg
|
||||
blockChain.fetchContractDataPassedResult = result
|
||||
blockChain.fetchContractDataPassedBlockNumber = blockNumber
|
||||
return blockChain.fetchContractDataErr
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) CallContract(contractHash string, input []byte, blockNumber *big.Int) ([]byte, error) {
|
||||
return blockChain.ContractReturnValue, nil
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) LastBlock() *big.Int {
|
||||
var max int64
|
||||
for blockNumber := range blockChain.blocks {
|
||||
if blockNumber > max {
|
||||
max = blockNumber
|
||||
}
|
||||
}
|
||||
return big.NewInt(max)
|
||||
return blockChain.lastBlock
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) GetLogs(contract core.Contract, startingBlock *big.Int, endingBlock *big.Int) ([]core.Log, error) {
|
||||
return blockChain.logs[contract.Hash], nil
|
||||
return []core.Log{}, nil
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) Node() core.Node {
|
||||
return blockChain.node
|
||||
}
|
||||
|
||||
func NewMockBlockChain(err error) *MockBlockChain {
|
||||
return &MockBlockChain{
|
||||
blocks: make(map[int64]core.Block),
|
||||
logs: make(map[string][]core.Log),
|
||||
contractAttributes: make(map[string]map[string]string),
|
||||
node: core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "Geth"},
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func NewMockBlockChainWithBlocks(blocks []core.Block) *MockBlockChain {
|
||||
blockNumberToBlocks := make(map[int64]core.Block)
|
||||
for _, block := range blocks {
|
||||
blockNumberToBlocks[block.Number] = block
|
||||
}
|
||||
return &MockBlockChain{
|
||||
blocks: blockNumberToBlocks,
|
||||
}
|
||||
}
|
||||
|
||||
func NewMockBlockChainWithHeaders(headers []core.Header) *MockBlockChain {
|
||||
// need to create blocks and headers so that LastBlock() will work in the mock
|
||||
// no reason to implement LastBlock() separately for headers since it checks
|
||||
// the last header in the Node's DB already
|
||||
memoryBlocks := make(map[int64]core.Block)
|
||||
memoryHeaders := make(map[int64]core.Header)
|
||||
for _, header := range headers {
|
||||
memoryBlocks[header.BlockNumber] = core.Block{Number: header.BlockNumber}
|
||||
memoryHeaders[header.BlockNumber] = header
|
||||
}
|
||||
return &MockBlockChain{
|
||||
blocks: memoryBlocks,
|
||||
headers: memoryHeaders,
|
||||
}
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) GetBlockByNumber(blockNumber int64) (core.Block, error) {
|
||||
if blockChain.err != nil {
|
||||
return core.Block{}, blockChain.err
|
||||
}
|
||||
return blockChain.blocks[blockNumber], nil
|
||||
return core.Block{Number: blockNumber}, blockChain.getBlockByNumberErr
|
||||
}
|
||||
|
||||
func (blockChain *MockBlockChain) AddBlock(block core.Block) {
|
||||
blockChain.blocks[block.Number] = block
|
||||
blockChain.blocksChannel <- block
|
||||
// TODO: handle methodArg being nil (can't match nil to nil in Gomega)
|
||||
func (blockChain *MockBlockChain) AssertFetchContractDataCalledWith(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) {
|
||||
Expect(blockChain.fetchContractDataPassedAbi).To(Equal(abiJSON))
|
||||
Expect(blockChain.fetchContractDataPassedAddress).To(Equal(address))
|
||||
Expect(blockChain.fetchContractDataPassedMethod).To(Equal(method))
|
||||
Expect(blockChain.fetchContractDataPassedResult).To(Equal(result))
|
||||
Expect(blockChain.fetchContractDataPassedBlockNumber).To(Equal(blockNumber))
|
||||
}
|
||||
|
@ -5,11 +5,12 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
type MockClient struct {
|
||||
type MockEthClient struct {
|
||||
callContractErr error
|
||||
callContractPassedContext context.Context
|
||||
callContractPassedMsg ethereum.CallMsg
|
||||
@ -27,10 +28,14 @@ type MockClient struct {
|
||||
filterLogsPassedContext context.Context
|
||||
filterLogsPassedQuery ethereum.FilterQuery
|
||||
filterLogsReturnLogs []types.Log
|
||||
transactionReceipts map[string]*types.Receipt
|
||||
err error
|
||||
transactionSenderErr error
|
||||
transactionReceiptErr error
|
||||
}
|
||||
|
||||
func NewMockClient() *MockClient {
|
||||
return &MockClient{
|
||||
func NewMockEthClient() *MockEthClient {
|
||||
return &MockEthClient{
|
||||
callContractErr: nil,
|
||||
callContractPassedContext: nil,
|
||||
callContractPassedMsg: ethereum.CallMsg{},
|
||||
@ -48,83 +53,110 @@ func NewMockClient() *MockClient {
|
||||
filterLogsPassedContext: nil,
|
||||
filterLogsPassedQuery: ethereum.FilterQuery{},
|
||||
filterLogsReturnLogs: nil,
|
||||
transactionReceipts: make(map[string]*types.Receipt),
|
||||
err: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (client *MockClient) SetCallContractErr(err error) {
|
||||
func (client *MockEthClient) SetCallContractErr(err error) {
|
||||
client.callContractErr = err
|
||||
}
|
||||
|
||||
func (client *MockClient) SetCallContractReturnBytes(returnBytes []byte) {
|
||||
func (client *MockEthClient) SetCallContractReturnBytes(returnBytes []byte) {
|
||||
client.callContractReturnBytes = returnBytes
|
||||
}
|
||||
|
||||
func (client *MockClient) SetBlockByNumberErr(err error) {
|
||||
func (client *MockEthClient) SetBlockByNumberErr(err error) {
|
||||
client.blockByNumberErr = err
|
||||
}
|
||||
|
||||
func (client *MockClient) SetBlockByNumberReturnBlock(block *types.Block) {
|
||||
func (client *MockEthClient) SetBlockByNumberReturnBlock(block *types.Block) {
|
||||
client.blockByNumberReturnBlock = block
|
||||
}
|
||||
|
||||
func (client *MockClient) SetHeaderByNumberErr(err error) {
|
||||
func (client *MockEthClient) SetHeaderByNumberErr(err error) {
|
||||
client.headerByNumberErr = err
|
||||
}
|
||||
|
||||
func (client *MockClient) SetHeaderByNumberReturnHeader(header *types.Header) {
|
||||
func (client *MockEthClient) SetHeaderByNumberReturnHeader(header *types.Header) {
|
||||
client.headerByNumberReturnHeader = header
|
||||
}
|
||||
|
||||
func (client *MockClient) SetFilterLogsErr(err error) {
|
||||
func (client *MockEthClient) SetFilterLogsErr(err error) {
|
||||
client.filterLogsErr = err
|
||||
}
|
||||
|
||||
func (client *MockClient) SetFilterLogsReturnLogs(logs []types.Log) {
|
||||
func (client *MockEthClient) SetFilterLogsReturnLogs(logs []types.Log) {
|
||||
client.filterLogsReturnLogs = logs
|
||||
}
|
||||
|
||||
func (client *MockClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
|
||||
func (client *MockEthClient) SetTransactionReceiptErr(err error) {
|
||||
client.transactionReceiptErr = err
|
||||
}
|
||||
|
||||
func (client *MockEthClient) SetTransactionReceipts(receipts []*types.Receipt) {
|
||||
for _, receipt := range receipts {
|
||||
client.transactionReceipts[receipt.TxHash.Hex()] = receipt
|
||||
}
|
||||
}
|
||||
|
||||
func (client *MockEthClient) SetTransactionSenderErr(err error) {
|
||||
client.transactionSenderErr = err
|
||||
}
|
||||
|
||||
func (client *MockEthClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
|
||||
client.callContractPassedContext = ctx
|
||||
client.callContractPassedMsg = msg
|
||||
client.callContractPassedNumber = blockNumber
|
||||
return client.callContractReturnBytes, client.callContractErr
|
||||
}
|
||||
|
||||
func (client *MockClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
|
||||
func (client *MockEthClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
|
||||
client.blockByNumberPassedContext = ctx
|
||||
client.blockByNumberPassedNumber = number
|
||||
return client.blockByNumberReturnBlock, client.blockByNumberErr
|
||||
}
|
||||
|
||||
func (client *MockClient) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
|
||||
func (client *MockEthClient) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
|
||||
client.headerByNumberPassedContext = ctx
|
||||
client.headerByNumberPassedNumber = number
|
||||
return client.headerByNumberReturnHeader, client.headerByNumberErr
|
||||
}
|
||||
|
||||
func (client *MockClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
|
||||
func (client *MockEthClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
|
||||
client.filterLogsPassedContext = ctx
|
||||
client.filterLogsPassedQuery = q
|
||||
return client.filterLogsReturnLogs, client.filterLogsErr
|
||||
}
|
||||
|
||||
func (client *MockClient) AssertCallContractCalledWith(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) {
|
||||
func (client *MockEthClient) TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) {
|
||||
return common.HexToAddress("0x123"), client.transactionSenderErr
|
||||
}
|
||||
|
||||
func (client *MockEthClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
|
||||
if gasUsed, ok := client.transactionReceipts[txHash.Hex()]; ok {
|
||||
return gasUsed, client.transactionReceiptErr
|
||||
}
|
||||
return &types.Receipt{GasUsed: uint64(0)}, client.transactionReceiptErr
|
||||
}
|
||||
|
||||
func (client *MockEthClient) AssertCallContractCalledWith(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) {
|
||||
Expect(client.callContractPassedContext).To(Equal(ctx))
|
||||
Expect(client.callContractPassedMsg).To(Equal(msg))
|
||||
Expect(client.callContractPassedNumber).To(Equal(blockNumber))
|
||||
}
|
||||
|
||||
func (client *MockClient) AssertBlockByNumberCalledWith(ctx context.Context, number *big.Int) {
|
||||
func (client *MockEthClient) AssertBlockByNumberCalledWith(ctx context.Context, number *big.Int) {
|
||||
Expect(client.blockByNumberPassedContext).To(Equal(ctx))
|
||||
Expect(client.blockByNumberPassedNumber).To(Equal(number))
|
||||
}
|
||||
|
||||
func (client *MockClient) AssertHeaderByNumberCalledWith(ctx context.Context, number *big.Int) {
|
||||
func (client *MockEthClient) AssertHeaderByNumberCalledWith(ctx context.Context, number *big.Int) {
|
||||
Expect(client.headerByNumberPassedContext).To(Equal(ctx))
|
||||
Expect(client.headerByNumberPassedNumber).To(Equal(number))
|
||||
}
|
||||
|
||||
func (client *MockClient) AssertFilterLogsCalledWith(ctx context.Context, q ethereum.FilterQuery) {
|
||||
func (client *MockEthClient) AssertFilterLogsCalledWith(ctx context.Context, q ethereum.FilterQuery) {
|
||||
Expect(client.filterLogsPassedContext).To(Equal(ctx))
|
||||
Expect(client.filterLogsPassedQuery).To(Equal(q))
|
||||
}
|
40
pkg/fakes/mock_header_repository.go
Normal file
40
pkg/fakes/mock_header_repository.go
Normal file
@ -0,0 +1,40 @@
|
||||
package fakes
|
||||
|
||||
import (
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
type MockHeaderRepository struct {
|
||||
createOrUpdateBlockNumbersCallCount int
|
||||
createOrUpdateBlockNumbersPassedBlockNumbers []int64
|
||||
missingBlockNumbers []int64
|
||||
}
|
||||
|
||||
func NewMockHeaderRepository() *MockHeaderRepository {
|
||||
return &MockHeaderRepository{}
|
||||
}
|
||||
|
||||
func (repository *MockHeaderRepository) SetMissingBlockNumbers(blockNumbers []int64) {
|
||||
repository.missingBlockNumbers = blockNumbers
|
||||
}
|
||||
|
||||
func (repository *MockHeaderRepository) CreateOrUpdateHeader(header core.Header) (int64, error) {
|
||||
repository.createOrUpdateBlockNumbersCallCount++
|
||||
repository.createOrUpdateBlockNumbersPassedBlockNumbers = append(repository.createOrUpdateBlockNumbersPassedBlockNumbers, header.BlockNumber)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (*MockHeaderRepository) GetHeader(blockNumber int64) (core.Header, error) {
|
||||
return core.Header{BlockNumber: blockNumber}, nil
|
||||
}
|
||||
|
||||
func (repository *MockHeaderRepository) MissingBlockNumbers(startingBlockNumber, endingBlockNumber int64, nodeID string) []int64 {
|
||||
return repository.missingBlockNumbers
|
||||
}
|
||||
|
||||
func (repository *MockHeaderRepository) AssertCreateOrUpdateHeaderCallCountAndPassedBlockNumbers(times int, blockNumbers []int64) {
|
||||
Expect(repository.createOrUpdateBlockNumbersCallCount).To(Equal(times))
|
||||
Expect(repository.createOrUpdateBlockNumbersPassedBlockNumbers).To(Equal(blockNumbers))
|
||||
}
|
73
pkg/fakes/mock_rpc_client.go
Normal file
73
pkg/fakes/mock_rpc_client.go
Normal file
@ -0,0 +1,73 @@
|
||||
package fakes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
type MockRpcClient struct {
|
||||
ipcPath string
|
||||
nodeType core.NodeType
|
||||
}
|
||||
|
||||
func NewMockRpcClient() *MockRpcClient {
|
||||
return &MockRpcClient{}
|
||||
}
|
||||
|
||||
func (client *MockRpcClient) SetNodeType(nodeType core.NodeType) {
|
||||
client.nodeType = nodeType
|
||||
}
|
||||
|
||||
func (client *MockRpcClient) SetIpcPath(ipcPath string) {
|
||||
client.ipcPath = ipcPath
|
||||
}
|
||||
|
||||
func (*MockRpcClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
|
||||
switch method {
|
||||
case "admin_nodeInfo":
|
||||
if p, ok := result.(*p2p.NodeInfo); ok {
|
||||
p.ID = "enode://GethNode@172.17.0.1:30303"
|
||||
p.Name = "Geth/v1.7"
|
||||
}
|
||||
case "eth_getBlockByNumber":
|
||||
if p, ok := result.(*types.Header); ok {
|
||||
*p = types.Header{}
|
||||
}
|
||||
|
||||
case "parity_versionInfo":
|
||||
if p, ok := result.(*core.ParityNodeInfo); ok {
|
||||
*p = core.ParityNodeInfo{
|
||||
Track: "",
|
||||
ParityVersion: core.ParityVersion{
|
||||
Major: 1,
|
||||
Minor: 2,
|
||||
Patch: 3,
|
||||
},
|
||||
Hash: "",
|
||||
}
|
||||
}
|
||||
case "parity_enode":
|
||||
if p, ok := result.(*string); ok {
|
||||
*p = "enode://ParityNode@172.17.0.1:30303"
|
||||
}
|
||||
case "net_version":
|
||||
if p, ok := result.(*string); ok {
|
||||
*p = "1234"
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *MockRpcClient) IpcPath() string {
|
||||
return client.ipcPath
|
||||
}
|
||||
|
||||
func (client *MockRpcClient) SupportedModules() (map[string]string, error) {
|
||||
result := make(map[string]string)
|
||||
if client.nodeType == core.GETH {
|
||||
result["admin"] = "ok"
|
||||
}
|
||||
return result, nil
|
||||
}
|
@ -12,13 +12,13 @@ import (
|
||||
)
|
||||
|
||||
type BlockChain struct {
|
||||
client core.Client
|
||||
client core.EthClient
|
||||
blockConverter vulcCommon.BlockConverter
|
||||
headerConverter vulcCommon.HeaderConverter
|
||||
node core.Node
|
||||
}
|
||||
|
||||
func NewBlockChain(client core.Client, node core.Node, converter vulcCommon.TransactionConverter) *BlockChain {
|
||||
func NewBlockChain(client core.EthClient, node core.Node, converter vulcCommon.TransactionConverter) *BlockChain {
|
||||
return &BlockChain{
|
||||
client: client,
|
||||
blockConverter: vulcCommon.NewBlockConverter(converter),
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
var _ = Describe("Geth blockchain", func() {
|
||||
Describe("getting a block", func() {
|
||||
It("fetches block from client", func() {
|
||||
mockClient := fakes.NewMockClient()
|
||||
mockClient := fakes.NewMockEthClient()
|
||||
mockClient.SetBlockByNumberReturnBlock(types.NewBlockWithHeader(&types.Header{}))
|
||||
node := vulcCore.Node{}
|
||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
||||
@ -32,7 +32,7 @@ var _ = Describe("Geth blockchain", func() {
|
||||
})
|
||||
|
||||
It("returns err if client returns err", func() {
|
||||
mockClient := fakes.NewMockClient()
|
||||
mockClient := fakes.NewMockEthClient()
|
||||
mockClient.SetBlockByNumberErr(fakes.FakeError)
|
||||
node := vulcCore.Node{}
|
||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
||||
@ -46,7 +46,7 @@ var _ = Describe("Geth blockchain", func() {
|
||||
|
||||
Describe("getting a header", func() {
|
||||
It("fetches header from client", func() {
|
||||
mockClient := fakes.NewMockClient()
|
||||
mockClient := fakes.NewMockEthClient()
|
||||
blockNumber := int64(100)
|
||||
mockClient.SetHeaderByNumberReturnHeader(&types.Header{Number: big.NewInt(blockNumber)})
|
||||
node := vulcCore.Node{}
|
||||
@ -59,7 +59,7 @@ var _ = Describe("Geth blockchain", func() {
|
||||
})
|
||||
|
||||
It("returns err if client returns err", func() {
|
||||
mockClient := fakes.NewMockClient()
|
||||
mockClient := fakes.NewMockEthClient()
|
||||
mockClient.SetHeaderByNumberErr(fakes.FakeError)
|
||||
node := vulcCore.Node{}
|
||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
||||
@ -73,7 +73,7 @@ var _ = Describe("Geth blockchain", func() {
|
||||
|
||||
Describe("getting logs", func() {
|
||||
It("fetches logs from client", func() {
|
||||
mockClient := fakes.NewMockClient()
|
||||
mockClient := fakes.NewMockEthClient()
|
||||
mockClient.SetFilterLogsReturnLogs([]types.Log{{}})
|
||||
node := vulcCore.Node{}
|
||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
||||
@ -93,7 +93,7 @@ var _ = Describe("Geth blockchain", func() {
|
||||
})
|
||||
|
||||
It("returns err if client returns err", func() {
|
||||
mockClient := fakes.NewMockClient()
|
||||
mockClient := fakes.NewMockEthClient()
|
||||
mockClient.SetFilterLogsErr(fakes.FakeError)
|
||||
node := vulcCore.Node{}
|
||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
||||
@ -110,7 +110,7 @@ var _ = Describe("Geth blockchain", func() {
|
||||
|
||||
Describe("getting the most recent block number", func() {
|
||||
It("fetches latest header from client", func() {
|
||||
mockClient := fakes.NewMockClient()
|
||||
mockClient := fakes.NewMockEthClient()
|
||||
blockNumber := int64(100)
|
||||
mockClient.SetHeaderByNumberReturnHeader(&types.Header{Number: big.NewInt(blockNumber)})
|
||||
node := vulcCore.Node{}
|
||||
|
@ -1,33 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
client *ethclient.Client
|
||||
}
|
||||
|
||||
func NewClient(client *ethclient.Client) Client {
|
||||
return Client{client: client}
|
||||
}
|
||||
|
||||
func (client Client) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
|
||||
return client.client.BlockByNumber(ctx, number)
|
||||
}
|
||||
|
||||
func (client Client) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
|
||||
return client.client.CallContract(ctx, msg, blockNumber)
|
||||
}
|
||||
|
||||
func (client Client) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
|
||||
return client.client.FilterLogs(ctx, q)
|
||||
}
|
||||
|
||||
func (client Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
|
||||
return client.client.HeaderByNumber(ctx, number)
|
||||
}
|
42
pkg/geth/client/eth_client.go
Normal file
42
pkg/geth/client/eth_client.go
Normal file
@ -0,0 +1,42 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
type EthClient struct {
|
||||
client *ethclient.Client
|
||||
}
|
||||
|
||||
func NewEthClient(client *ethclient.Client) EthClient {
|
||||
return EthClient{client: client}
|
||||
}
|
||||
|
||||
func (client EthClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
|
||||
return client.client.BlockByNumber(ctx, number)
|
||||
}
|
||||
|
||||
func (client EthClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
|
||||
return client.client.CallContract(ctx, msg, blockNumber)
|
||||
}
|
||||
|
||||
func (client EthClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
|
||||
return client.client.FilterLogs(ctx, q)
|
||||
}
|
||||
|
||||
func (client EthClient) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
|
||||
return client.client.HeaderByNumber(ctx, number)
|
||||
}
|
||||
|
||||
func (client EthClient) TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) {
|
||||
return client.client.TransactionSender(ctx, tx, block, index)
|
||||
}
|
||||
|
||||
func (client EthClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
|
||||
return client.client.TransactionReceipt(ctx, txHash)
|
||||
}
|
30
pkg/geth/client/rpc_client.go
Normal file
30
pkg/geth/client/rpc_client.go
Normal file
@ -0,0 +1,30 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
type RpcClient struct {
|
||||
client *rpc.Client
|
||||
ipcPath string
|
||||
}
|
||||
|
||||
func NewRpcClient(client *rpc.Client, ipcPath string) RpcClient {
|
||||
return RpcClient{
|
||||
client: client,
|
||||
ipcPath: ipcPath,
|
||||
}
|
||||
}
|
||||
|
||||
func (client RpcClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
|
||||
return client.client.CallContext(ctx, result, method, args)
|
||||
}
|
||||
|
||||
func (client RpcClient) IpcPath() string {
|
||||
return client.ipcPath
|
||||
}
|
||||
|
||||
func (client RpcClient) SupportedModules() (map[string]string, error) {
|
||||
return client.client.SupportedModules()
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
package common_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/big"
|
||||
@ -14,57 +12,11 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
)
|
||||
|
||||
type FakeGethClient struct {
|
||||
receipts map[string]*types.Receipt
|
||||
err error
|
||||
}
|
||||
|
||||
type TransActionReceiptError struct{}
|
||||
|
||||
func (tarErr TransActionReceiptError) Error() string {
|
||||
return fmt.Sprintf("transaction receipt error")
|
||||
}
|
||||
|
||||
type TransactionSenderError struct{}
|
||||
|
||||
func (tasErr TransactionSenderError) Error() string {
|
||||
return fmt.Sprintf("transaction sender error")
|
||||
}
|
||||
|
||||
func NewFakeClient(err error) *FakeGethClient {
|
||||
return &FakeGethClient{
|
||||
receipts: make(map[string]*types.Receipt),
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func (client *FakeGethClient) AddReceipts(receipts []*types.Receipt) {
|
||||
for _, receipt := range receipts {
|
||||
client.receipts[receipt.TxHash.Hex()] = receipt
|
||||
}
|
||||
}
|
||||
|
||||
func (client *FakeGethClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
|
||||
if err, ok := client.err.(TransActionReceiptError); ok {
|
||||
return &types.Receipt{}, err
|
||||
}
|
||||
if gasUsed, ok := client.receipts[txHash.Hex()]; ok {
|
||||
return gasUsed, nil
|
||||
}
|
||||
return &types.Receipt{GasUsed: uint64(0)}, nil
|
||||
}
|
||||
|
||||
func (client *FakeGethClient) TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) {
|
||||
if err, ok := client.err.(TransactionSenderError); ok {
|
||||
return common.Address{}, err
|
||||
}
|
||||
return common.HexToAddress("0x123"), nil
|
||||
}
|
||||
|
||||
var _ = Describe("Conversion of GethBlock to core.Block", func() {
|
||||
|
||||
It("converts basic Block metadata", func() {
|
||||
@ -90,7 +42,7 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() {
|
||||
UncleHash: common.Hash{128},
|
||||
}
|
||||
block := types.NewBlock(&header, []*types.Transaction{}, []*types.Header{}, []*types.Receipt{})
|
||||
client := &FakeGethClient{}
|
||||
client := fakes.NewMockEthClient()
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
@ -132,8 +84,8 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() {
|
||||
}
|
||||
receipts := []*types.Receipt{&receipt}
|
||||
|
||||
client := NewFakeClient(nil)
|
||||
client.AddReceipts(receipts)
|
||||
client := fakes.NewMockEthClient()
|
||||
client.SetTransactionReceipts(receipts)
|
||||
|
||||
number := int64(1071819)
|
||||
header := types.Header{
|
||||
@ -176,8 +128,8 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() {
|
||||
}
|
||||
block := types.NewBlock(&header, transactions, uncles, receipts)
|
||||
|
||||
client := NewFakeClient(nil)
|
||||
client.AddReceipts(receipts)
|
||||
client := fakes.NewMockEthClient()
|
||||
client.SetTransactionReceipts(receipts)
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
@ -225,8 +177,8 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() {
|
||||
var uncles []*types.Header
|
||||
block := types.NewBlock(&header, transactions, uncles, receipts)
|
||||
|
||||
client := NewFakeClient(nil)
|
||||
client.AddReceipts(receipts)
|
||||
client := fakes.NewMockEthClient()
|
||||
client.SetTransactionReceipts(receipts)
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
@ -241,7 +193,7 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() {
|
||||
It("is empty", func() {
|
||||
header := types.Header{}
|
||||
block := types.NewBlock(&header, []*types.Transaction{}, []*types.Header{}, []*types.Receipt{})
|
||||
client := &FakeGethClient{}
|
||||
client := fakes.NewMockEthClient()
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
@ -270,8 +222,8 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() {
|
||||
TxHash: gethTransaction.Hash(),
|
||||
}
|
||||
|
||||
client := NewFakeClient(nil)
|
||||
client.AddReceipts([]*types.Receipt{gethReceipt})
|
||||
client := fakes.NewMockEthClient()
|
||||
client.SetTransactionReceipts([]*types.Receipt{gethReceipt})
|
||||
|
||||
header := types.Header{}
|
||||
block := types.NewBlock(
|
||||
@ -317,8 +269,8 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() {
|
||||
ContractAddress: common.HexToAddress("0x1023342345"),
|
||||
}
|
||||
|
||||
client := NewFakeClient(nil)
|
||||
client.AddReceipts([]*types.Receipt{gethReceipt})
|
||||
client := fakes.NewMockEthClient()
|
||||
client.SetTransactionReceipts([]*types.Receipt{gethReceipt})
|
||||
|
||||
block := types.NewBlock(
|
||||
&types.Header{},
|
||||
@ -373,25 +325,25 @@ var _ = Describe("Conversion of GethBlock to core.Block", func() {
|
||||
})
|
||||
|
||||
It("returns an error when transaction sender call fails", func() {
|
||||
client := NewFakeClient(TransactionSenderError{})
|
||||
client.AddReceipts([]*types.Receipt{})
|
||||
client := fakes.NewMockEthClient()
|
||||
client.SetTransactionSenderErr(fakes.FakeError)
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
_, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).To(Equal(TransactionSenderError{}))
|
||||
Expect(err).To(MatchError(fakes.FakeError))
|
||||
})
|
||||
|
||||
It("returns an error when transaction receipt call fails", func() {
|
||||
client := NewFakeClient(TransActionReceiptError{})
|
||||
client.AddReceipts([]*types.Receipt{})
|
||||
client := fakes.NewMockEthClient()
|
||||
client.SetTransactionReceiptErr(fakes.FakeError)
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
_, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).To(Equal(TransActionReceiptError{}))
|
||||
Expect(err).To(MatchError(fakes.FakeError))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -14,16 +14,11 @@ import (
|
||||
vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error)
|
||||
TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
|
||||
}
|
||||
|
||||
type RpcTransactionConverter struct {
|
||||
client Client
|
||||
client core.EthClient
|
||||
}
|
||||
|
||||
func NewRpcTransactionConverter(client Client) *RpcTransactionConverter {
|
||||
func NewRpcTransactionConverter(client core.EthClient) *RpcTransactionConverter {
|
||||
return &RpcTransactionConverter{client: client}
|
||||
}
|
||||
|
||||
@ -42,7 +37,7 @@ func (rtc *RpcTransactionConverter) ConvertTransactionsToCore(gethBlock *types.B
|
||||
return err
|
||||
}
|
||||
coreTransaction := transToCoreTrans(transaction, &from)
|
||||
coreTransaction, err = appendReceiptToTransaction(rtc.client, coreTransaction)
|
||||
coreTransaction, err = rtc.appendReceiptToTransaction(coreTransaction)
|
||||
if err != nil {
|
||||
log.Println("receipt: ", err)
|
||||
return err
|
||||
@ -58,8 +53,8 @@ func (rtc *RpcTransactionConverter) ConvertTransactionsToCore(gethBlock *types.B
|
||||
return coreTransactions, nil
|
||||
}
|
||||
|
||||
func appendReceiptToTransaction(client Client, transaction core.Transaction) (core.Transaction, error) {
|
||||
gethReceipt, err := client.TransactionReceipt(context.Background(), common.HexToHash(transaction.Hash))
|
||||
func (rtc *RpcTransactionConverter) appendReceiptToTransaction(transaction core.Transaction) (core.Transaction, error) {
|
||||
gethReceipt, err := rtc.client.TransactionReceipt(context.Background(), common.HexToHash(transaction.Hash))
|
||||
if err != nil {
|
||||
return transaction, err
|
||||
}
|
||||
|
@ -7,69 +7,38 @@ import (
|
||||
|
||||
"regexp"
|
||||
|
||||
"strings"
|
||||
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type PropertiesReader interface {
|
||||
type IPropertiesReader interface {
|
||||
NodeInfo() (id string, name string)
|
||||
NetworkId() float64
|
||||
GenesisBlock() string
|
||||
}
|
||||
|
||||
type ClientWrapper struct {
|
||||
ContextCaller
|
||||
IPCPath string
|
||||
}
|
||||
|
||||
type ContextCaller interface {
|
||||
CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
|
||||
SupportedModules() (map[string]string, error)
|
||||
type PropertiesReader struct {
|
||||
client core.RpcClient
|
||||
}
|
||||
|
||||
type ParityClient struct {
|
||||
ClientWrapper
|
||||
PropertiesReader
|
||||
}
|
||||
|
||||
type GethClient struct {
|
||||
ClientWrapper
|
||||
PropertiesReader
|
||||
}
|
||||
|
||||
type InfuraClient struct {
|
||||
ClientWrapper
|
||||
PropertiesReader
|
||||
}
|
||||
|
||||
func (clientWrapper ClientWrapper) NodeType() core.NodeType {
|
||||
if strings.Contains(clientWrapper.IPCPath, "infura") {
|
||||
return core.INFURA
|
||||
}
|
||||
modules, _ := clientWrapper.SupportedModules()
|
||||
if _, ok := modules["admin"]; ok {
|
||||
return core.GETH
|
||||
}
|
||||
return core.PARITY
|
||||
}
|
||||
|
||||
func makePropertiesReader(wrapper ClientWrapper) PropertiesReader {
|
||||
switch wrapper.NodeType() {
|
||||
case core.GETH:
|
||||
return GethClient{ClientWrapper: wrapper}
|
||||
case core.PARITY:
|
||||
return ParityClient{ClientWrapper: wrapper}
|
||||
case core.INFURA:
|
||||
return InfuraClient{ClientWrapper: wrapper}
|
||||
default:
|
||||
return wrapper
|
||||
}
|
||||
}
|
||||
|
||||
func MakeNode(wrapper ClientWrapper) core.Node {
|
||||
pr := makePropertiesReader(wrapper)
|
||||
func MakeNode(rpcClient core.RpcClient) core.Node {
|
||||
pr := makePropertiesReader(rpcClient)
|
||||
id, name := pr.NodeInfo()
|
||||
return core.Node{
|
||||
GenesisBlock: pr.GenesisBlock(),
|
||||
@ -79,9 +48,33 @@ func MakeNode(wrapper ClientWrapper) core.Node {
|
||||
}
|
||||
}
|
||||
|
||||
func (client ClientWrapper) NetworkId() float64 {
|
||||
func makePropertiesReader(client core.RpcClient) IPropertiesReader {
|
||||
switch getNodeType(client) {
|
||||
case core.GETH:
|
||||
return GethClient{PropertiesReader: PropertiesReader{client: client}}
|
||||
case core.PARITY:
|
||||
return ParityClient{PropertiesReader: PropertiesReader{client: client}}
|
||||
case core.INFURA:
|
||||
return InfuraClient{PropertiesReader: PropertiesReader{client: client}}
|
||||
default:
|
||||
return PropertiesReader{client: client}
|
||||
}
|
||||
}
|
||||
|
||||
func getNodeType(client core.RpcClient) core.NodeType {
|
||||
if strings.Contains(client.IpcPath(), "infura") {
|
||||
return core.INFURA
|
||||
}
|
||||
modules, _ := client.SupportedModules()
|
||||
if _, ok := modules["admin"]; ok {
|
||||
return core.GETH
|
||||
}
|
||||
return core.PARITY
|
||||
}
|
||||
|
||||
func (reader PropertiesReader) NetworkId() float64 {
|
||||
var version string
|
||||
err := client.CallContext(context.Background(), &version, "net_version")
|
||||
err := reader.client.CallContext(context.Background(), &version, "net_version")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
@ -89,17 +82,17 @@ func (client ClientWrapper) NetworkId() float64 {
|
||||
return networkId
|
||||
}
|
||||
|
||||
func (client ClientWrapper) GenesisBlock() string {
|
||||
func (reader PropertiesReader) GenesisBlock() string {
|
||||
var header *types.Header
|
||||
blockZero := "0x0"
|
||||
includeTransactions := false
|
||||
client.CallContext(context.Background(), &header, "eth_getBlockByNumber", blockZero, includeTransactions)
|
||||
reader.client.CallContext(context.Background(), &header, "eth_getBlockByNumber", blockZero, includeTransactions)
|
||||
return header.Hash().Hex()
|
||||
}
|
||||
|
||||
func (client ClientWrapper) NodeInfo() (string, string) {
|
||||
func (reader PropertiesReader) NodeInfo() (string, string) {
|
||||
var info p2p.NodeInfo
|
||||
client.CallContext(context.Background(), &info, "admin_nodeInfo")
|
||||
reader.client.CallContext(context.Background(), &info, "admin_nodeInfo")
|
||||
return info.ID, info.Name
|
||||
}
|
||||
|
||||
@ -115,14 +108,14 @@ func (client InfuraClient) NodeInfo() (string, string) {
|
||||
|
||||
func (client ParityClient) parityNodeInfo() string {
|
||||
var nodeInfo core.ParityNodeInfo
|
||||
client.CallContext(context.Background(), &nodeInfo, "parity_versionInfo")
|
||||
client.client.CallContext(context.Background(), &nodeInfo, "parity_versionInfo")
|
||||
return nodeInfo.String()
|
||||
}
|
||||
|
||||
func (client ParityClient) parityID() string {
|
||||
var enodeId = regexp.MustCompile(`^enode://(.+)@.+$`)
|
||||
var enodeURL string
|
||||
client.CallContext(context.Background(), &enodeURL, "parity_enode")
|
||||
client.client.CallContext(context.Background(), &enodeURL, "parity_enode")
|
||||
enode := enodeId.FindStringSubmatch(enodeURL)
|
||||
if len(enode) < 2 {
|
||||
return ""
|
||||
|
@ -3,66 +3,15 @@ package node_test
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"context"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||
)
|
||||
|
||||
type MockContextCaller struct {
|
||||
nodeType core.NodeType
|
||||
}
|
||||
|
||||
var EmpytHeaderHash = "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
|
||||
|
||||
func (MockContextCaller) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
|
||||
switch method {
|
||||
case "admin_nodeInfo":
|
||||
if p, ok := result.(*p2p.NodeInfo); ok {
|
||||
p.ID = "enode://GethNode@172.17.0.1:30303"
|
||||
p.Name = "Geth/v1.7"
|
||||
}
|
||||
case "eth_getBlockByNumber":
|
||||
if p, ok := result.(*types.Header); ok {
|
||||
*p = types.Header{}
|
||||
}
|
||||
|
||||
case "parity_versionInfo":
|
||||
if p, ok := result.(*core.ParityNodeInfo); ok {
|
||||
*p = core.ParityNodeInfo{
|
||||
Track: "",
|
||||
ParityVersion: core.ParityVersion{
|
||||
Major: 1,
|
||||
Minor: 2,
|
||||
Patch: 3,
|
||||
},
|
||||
Hash: "",
|
||||
}
|
||||
}
|
||||
case "parity_enode":
|
||||
if p, ok := result.(*string); ok {
|
||||
*p = "enode://ParityNode@172.17.0.1:30303"
|
||||
}
|
||||
case "net_version":
|
||||
if p, ok := result.(*string); ok {
|
||||
*p = "1234"
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mcc MockContextCaller) SupportedModules() (map[string]string, error) {
|
||||
result := make(map[string]string)
|
||||
if mcc.nodeType == core.GETH {
|
||||
result["admin"] = "ok"
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
var _ = Describe("Parity Node Info", func() {
|
||||
|
||||
It("verifies parity_versionInfo can be unmarshalled into ParityNodeInfo", func() {
|
||||
@ -99,39 +48,38 @@ var _ = Describe("Parity Node Info", func() {
|
||||
})
|
||||
|
||||
It("returns the genesis block for any client", func() {
|
||||
mcc := MockContextCaller{}
|
||||
cw := node.ClientWrapper{ContextCaller: mcc}
|
||||
n := node.MakeNode(cw)
|
||||
client := fakes.NewMockRpcClient()
|
||||
n := node.MakeNode(client)
|
||||
Expect(n.GenesisBlock).To(Equal(EmpytHeaderHash))
|
||||
})
|
||||
|
||||
It("returns the network id for any client", func() {
|
||||
mcc := MockContextCaller{}
|
||||
cw := node.ClientWrapper{ContextCaller: mcc}
|
||||
n := node.MakeNode(cw)
|
||||
client := fakes.NewMockRpcClient()
|
||||
n := node.MakeNode(client)
|
||||
Expect(n.NetworkID).To(Equal(float64(1234)))
|
||||
})
|
||||
|
||||
It("returns parity ID and client name for parity node", func() {
|
||||
mcc := MockContextCaller{core.PARITY}
|
||||
cw := node.ClientWrapper{ContextCaller: mcc}
|
||||
n := node.MakeNode(cw)
|
||||
client := fakes.NewMockRpcClient()
|
||||
client.SetNodeType(core.PARITY)
|
||||
n := node.MakeNode(client)
|
||||
Expect(n.ID).To(Equal("ParityNode"))
|
||||
Expect(n.ClientName).To(Equal("Parity/v1.2.3/"))
|
||||
})
|
||||
|
||||
It("returns geth ID and client name for geth node", func() {
|
||||
mcc := MockContextCaller{core.GETH}
|
||||
cw := node.ClientWrapper{ContextCaller: mcc}
|
||||
n := node.MakeNode(cw)
|
||||
client := fakes.NewMockRpcClient()
|
||||
client.SetNodeType(core.GETH)
|
||||
n := node.MakeNode(client)
|
||||
Expect(n.ID).To(Equal("enode://GethNode@172.17.0.1:30303"))
|
||||
Expect(n.ClientName).To(Equal("Geth/v1.7"))
|
||||
})
|
||||
|
||||
It("returns infura ID and client name for infura node", func() {
|
||||
mcc := MockContextCaller{core.INFURA}
|
||||
cw := node.ClientWrapper{ContextCaller: mcc, IPCPath: "https://mainnet.infura.io/123"}
|
||||
n := node.MakeNode(cw)
|
||||
client := fakes.NewMockRpcClient()
|
||||
client.SetNodeType(core.INFURA)
|
||||
client.SetIpcPath("infura/path")
|
||||
n := node.MakeNode(client)
|
||||
Expect(n.ID).To(Equal("infura"))
|
||||
Expect(n.ClientName).To(Equal("infura"))
|
||||
})
|
||||
|
@ -6,12 +6,12 @@ import (
|
||||
)
|
||||
|
||||
type BlockValidator struct {
|
||||
blockchain core.Blockchain
|
||||
blockchain core.BlockChain
|
||||
blockRepository datastore.BlockRepository
|
||||
windowSize int
|
||||
}
|
||||
|
||||
func NewBlockValidator(blockchain core.Blockchain, blockRepository datastore.BlockRepository, windowSize int) *BlockValidator {
|
||||
func NewBlockValidator(blockchain core.BlockChain, blockRepository datastore.BlockRepository, windowSize int) *BlockValidator {
|
||||
return &BlockValidator{
|
||||
blockchain: blockchain,
|
||||
blockRepository: blockRepository,
|
||||
|
@ -4,39 +4,29 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/inmemory"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/history"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var _ = Describe("Blocks validator", func() {
|
||||
|
||||
It("calls create or update for all blocks within the window", func() {
|
||||
blockchain := fakes.NewMockBlockChainWithBlocks([]core.Block{
|
||||
{Number: 4},
|
||||
{Number: 5},
|
||||
{Number: 6},
|
||||
{Number: 7},
|
||||
})
|
||||
inMemoryDB := inmemory.NewInMemory()
|
||||
blocksRepository := &inmemory.BlockRepository{InMemory: inMemoryDB}
|
||||
validator := history.NewBlockValidator(blockchain, blocksRepository, 2)
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(big.NewInt(7))
|
||||
blocksRepository := fakes.NewMockBlockRepository()
|
||||
validator := history.NewBlockValidator(blockChain, blocksRepository, 2)
|
||||
|
||||
window := validator.ValidateBlocks()
|
||||
|
||||
Expect(window).To(Equal(history.ValidationWindow{LowerBound: 5, UpperBound: 7}))
|
||||
Expect(blocksRepository.BlockCount()).To(Equal(3))
|
||||
Expect(blocksRepository.CreateOrUpdateBlockCallCount).To(Equal(3))
|
||||
blocksRepository.AssertCreateOrUpdateBlockCallCountEquals(3)
|
||||
})
|
||||
|
||||
It("returns the number of largest block", func() {
|
||||
blockchain := fakes.NewMockBlockChainWithBlocks([]core.Block{
|
||||
{Number: 1},
|
||||
{Number: 2},
|
||||
{Number: 3},
|
||||
})
|
||||
maxBlockNumber := blockchain.LastBlock()
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(big.NewInt(3))
|
||||
maxBlockNumber := blockChain.LastBlock()
|
||||
|
||||
Expect(maxBlockNumber.Int64()).To(Equal(int64(3)))
|
||||
})
|
||||
|
@ -6,12 +6,12 @@ import (
|
||||
)
|
||||
|
||||
type HeaderValidator struct {
|
||||
blockChain core.Blockchain
|
||||
blockChain core.BlockChain
|
||||
headerRepository datastore.HeaderRepository
|
||||
windowSize int
|
||||
}
|
||||
|
||||
func NewHeaderValidator(blockChain core.Blockchain, repository datastore.HeaderRepository, windowSize int) HeaderValidator {
|
||||
func NewHeaderValidator(blockChain core.BlockChain, repository datastore.HeaderRepository, windowSize int) HeaderValidator {
|
||||
return HeaderValidator{
|
||||
blockChain: blockChain,
|
||||
headerRepository: repository,
|
||||
|
@ -1,39 +1,22 @@
|
||||
package history_test
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/inmemory"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/history"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var _ = Describe("Header validator", func() {
|
||||
It("replaces headers in the validation window that have changed", func() {
|
||||
blockNumber := int64(10)
|
||||
oldHash := common.HexToHash("0x0987654321").Hex()
|
||||
oldHeader := core.Header{
|
||||
BlockNumber: blockNumber,
|
||||
Hash: oldHash,
|
||||
}
|
||||
inMemory := inmemory.NewInMemory()
|
||||
headerRepository := inmemory.NewHeaderRepository(inMemory)
|
||||
headerRepository.CreateOrUpdateHeader(oldHeader)
|
||||
newHash := common.HexToHash("0x123456789").Hex()
|
||||
newHeader := core.Header{
|
||||
BlockNumber: blockNumber,
|
||||
Hash: newHash,
|
||||
}
|
||||
headers := []core.Header{newHeader}
|
||||
blockChain := fakes.NewMockBlockChainWithHeaders(headers)
|
||||
validator := history.NewHeaderValidator(blockChain, headerRepository, 1)
|
||||
It("attempts to create every header in the validation window", func() {
|
||||
headerRepository := fakes.NewMockHeaderRepository()
|
||||
headerRepository.SetMissingBlockNumbers([]int64{})
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(big.NewInt(3))
|
||||
validator := history.NewHeaderValidator(blockChain, headerRepository, 2)
|
||||
|
||||
validator.ValidateHeaders()
|
||||
|
||||
dbHeader, _ := headerRepository.GetHeader(blockNumber)
|
||||
Expect(dbHeader.Hash).NotTo(Equal(oldHash))
|
||||
Expect(dbHeader.Hash).To(Equal(newHash))
|
||||
headerRepository.AssertCreateOrUpdateHeaderCallCountAndPassedBlockNumbers(3, []int64{1, 2, 3})
|
||||
})
|
||||
})
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||
)
|
||||
|
||||
func PopulateMissingBlocks(blockchain core.Blockchain, blockRepository datastore.BlockRepository, startingBlockNumber int64) int {
|
||||
func PopulateMissingBlocks(blockchain core.BlockChain, blockRepository datastore.BlockRepository, startingBlockNumber int64) int {
|
||||
lastBlock := blockchain.LastBlock().Int64()
|
||||
blockRange := blockRepository.MissingBlockNumbers(startingBlockNumber, lastBlock, blockchain.Node().ID)
|
||||
log.SetPrefix("")
|
||||
@ -16,7 +16,7 @@ func PopulateMissingBlocks(blockchain core.Blockchain, blockRepository datastore
|
||||
return len(blockRange)
|
||||
}
|
||||
|
||||
func RetrieveAndUpdateBlocks(blockchain core.Blockchain, blockRepository datastore.BlockRepository, blockNumbers []int64) int {
|
||||
func RetrieveAndUpdateBlocks(blockchain core.BlockChain, blockRepository datastore.BlockRepository, blockNumbers []int64) int {
|
||||
for _, blockNumber := range blockNumbers {
|
||||
block, err := blockchain.GetBlockByNumber(blockNumber)
|
||||
if err != nil {
|
||||
|
@ -1,35 +1,26 @@
|
||||
package history_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/inmemory"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/history"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var _ = Describe("Populating blocks", func() {
|
||||
var inMemory *inmemory.InMemory
|
||||
var blockRepository *inmemory.BlockRepository
|
||||
var blockRepository *fakes.MockBlockRepository
|
||||
|
||||
BeforeEach(func() {
|
||||
inMemory = inmemory.NewInMemory()
|
||||
blockRepository = &inmemory.BlockRepository{InMemory: inMemory}
|
||||
blockRepository = fakes.NewMockBlockRepository()
|
||||
})
|
||||
|
||||
It("fills in the only missing block (BlockNumber 1)", func() {
|
||||
blocks := []core.Block{
|
||||
{Number: 1},
|
||||
{Number: 2},
|
||||
}
|
||||
blockchain := fakes.NewMockBlockChainWithBlocks(blocks)
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(big.NewInt(2))
|
||||
blockRepository.SetMissingBlockNumbersReturnArray([]int64{2})
|
||||
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 2})
|
||||
|
||||
blocksAdded := history.PopulateMissingBlocks(blockchain, blockRepository, 1)
|
||||
blocksAdded := history.PopulateMissingBlocks(blockChain, blockRepository, 1)
|
||||
_, err := blockRepository.GetBlock(1)
|
||||
|
||||
Expect(blocksAdded).To(Equal(1))
|
||||
@ -37,77 +28,41 @@ var _ = Describe("Populating blocks", func() {
|
||||
})
|
||||
|
||||
It("fills in the three missing blocks (Numbers: 5,8,10)", func() {
|
||||
blockchain := fakes.NewMockBlockChainWithBlocks([]core.Block{
|
||||
{Number: 4},
|
||||
{Number: 5},
|
||||
{Number: 6},
|
||||
{Number: 7},
|
||||
{Number: 8},
|
||||
{Number: 9},
|
||||
{Number: 10},
|
||||
{Number: 11},
|
||||
{Number: 12},
|
||||
{Number: 13},
|
||||
})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 1})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 2})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 3})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 6})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 7})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 9})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 11})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 12})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 13})
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(big.NewInt(13))
|
||||
blockRepository.SetMissingBlockNumbersReturnArray([]int64{5, 8, 10})
|
||||
|
||||
blocksAdded := history.PopulateMissingBlocks(blockchain, blockRepository, 5)
|
||||
blocksAdded := history.PopulateMissingBlocks(blockChain, blockRepository, 5)
|
||||
|
||||
Expect(blocksAdded).To(Equal(3))
|
||||
Expect(blockRepository.BlockCount()).To(Equal(12))
|
||||
_, err := blockRepository.GetBlock(4)
|
||||
Expect(err).To(HaveOccurred())
|
||||
_, err = blockRepository.GetBlock(5)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = blockRepository.GetBlock(8)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = blockRepository.GetBlock(10)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = blockRepository.GetBlock(14)
|
||||
Expect(err).To(HaveOccurred())
|
||||
blockRepository.AssertCreateOrUpdateBlocksCallCountAndBlockNumbersEquals(3, []int64{5, 8, 10})
|
||||
})
|
||||
|
||||
It("returns the number of blocks created", func() {
|
||||
blockchain := fakes.NewMockBlockChainWithBlocks([]core.Block{
|
||||
{Number: 4},
|
||||
{Number: 5},
|
||||
{Number: 6},
|
||||
})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 3})
|
||||
blockRepository.CreateOrUpdateBlock(core.Block{Number: 6})
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(big.NewInt(6))
|
||||
blockRepository.SetMissingBlockNumbersReturnArray([]int64{4, 5})
|
||||
|
||||
numberOfBlocksCreated := history.PopulateMissingBlocks(blockchain, blockRepository, 3)
|
||||
numberOfBlocksCreated := history.PopulateMissingBlocks(blockChain, blockRepository, 3)
|
||||
|
||||
Expect(numberOfBlocksCreated).To(Equal(2))
|
||||
})
|
||||
|
||||
It("updates the repository with a range of blocks w/in the range ", func() {
|
||||
blockchain := fakes.NewMockBlockChainWithBlocks([]core.Block{
|
||||
{Number: 1},
|
||||
{Number: 2},
|
||||
{Number: 3},
|
||||
{Number: 4},
|
||||
{Number: 5},
|
||||
})
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
|
||||
history.RetrieveAndUpdateBlocks(blockchain, blockRepository, history.MakeRange(2, 5))
|
||||
Expect(blockRepository.BlockCount()).To(Equal(4))
|
||||
Expect(blockRepository.CreateOrUpdateBlockCallCount).To(Equal(4))
|
||||
history.RetrieveAndUpdateBlocks(blockChain, blockRepository, history.MakeRange(2, 5))
|
||||
|
||||
blockRepository.AssertCreateOrUpdateBlocksCallCountAndBlockNumbersEquals(4, []int64{2, 3, 4, 5})
|
||||
})
|
||||
|
||||
It("does not call repository create block when there is an error", func() {
|
||||
blockchain := fakes.NewMockBlockChain(errors.New("error getting block"))
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetGetBlockByNumberErr(fakes.FakeError)
|
||||
blocks := history.MakeRange(1, 10)
|
||||
history.RetrieveAndUpdateBlocks(blockchain, blockRepository, blocks)
|
||||
Expect(blockRepository.BlockCount()).To(Equal(0))
|
||||
Expect(blockRepository.CreateOrUpdateBlockCallCount).To(Equal(0))
|
||||
|
||||
history.RetrieveAndUpdateBlocks(blockChain, blockRepository, blocks)
|
||||
|
||||
blockRepository.AssertCreateOrUpdateBlockCallCountEquals(0)
|
||||
})
|
||||
})
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"log"
|
||||
)
|
||||
|
||||
func PopulateMissingHeaders(blockchain core.Blockchain, headerRepository datastore.HeaderRepository, startingBlockNumber int64) int {
|
||||
func PopulateMissingHeaders(blockchain core.BlockChain, headerRepository datastore.HeaderRepository, startingBlockNumber int64) int {
|
||||
lastBlock := blockchain.LastBlock().Int64()
|
||||
blockRange := headerRepository.MissingBlockNumbers(startingBlockNumber, lastBlock, blockchain.Node().ID)
|
||||
log.SetPrefix("")
|
||||
@ -15,7 +15,7 @@ func PopulateMissingHeaders(blockchain core.Blockchain, headerRepository datasto
|
||||
return len(blockRange)
|
||||
}
|
||||
|
||||
func RetrieveAndUpdateHeaders(blockchain core.Blockchain, headerRepository datastore.HeaderRepository, blockNumbers []int64) int {
|
||||
func RetrieveAndUpdateHeaders(blockchain core.BlockChain, headerRepository datastore.HeaderRepository, blockNumbers []int64) int {
|
||||
for _, blockNumber := range blockNumbers {
|
||||
header, err := blockchain.GetHeaderByNumber(blockNumber)
|
||||
if err != nil {
|
||||
|
@ -1,33 +1,29 @@
|
||||
package history_test
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/inmemory"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/history"
|
||||
)
|
||||
|
||||
var _ = Describe("Populating headers", func() {
|
||||
|
||||
var inMemory *inmemory.InMemory
|
||||
var headerRepository *inmemory.HeaderRepository
|
||||
var headerRepository *fakes.MockHeaderRepository
|
||||
|
||||
BeforeEach(func() {
|
||||
inMemory = inmemory.NewInMemory()
|
||||
headerRepository = inmemory.NewHeaderRepository(inMemory)
|
||||
headerRepository = fakes.NewMockHeaderRepository()
|
||||
})
|
||||
|
||||
Describe("When 1 missing header", func() {
|
||||
|
||||
It("returns number of headers added", func() {
|
||||
headers := []core.Header{
|
||||
{BlockNumber: 1},
|
||||
{BlockNumber: 2},
|
||||
}
|
||||
blockChain := fakes.NewMockBlockChainWithHeaders(headers)
|
||||
headerRepository.CreateOrUpdateHeader(core.Header{BlockNumber: 2})
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(big.NewInt(2))
|
||||
headerRepository.SetMissingBlockNumbers([]int64{2})
|
||||
|
||||
headersAdded := history.PopulateMissingHeaders(blockChain, headerRepository, 1)
|
||||
|
||||
@ -36,17 +32,12 @@ var _ = Describe("Populating headers", func() {
|
||||
})
|
||||
|
||||
It("adds missing headers to the db", func() {
|
||||
headers := []core.Header{
|
||||
{BlockNumber: 1},
|
||||
{BlockNumber: 2},
|
||||
}
|
||||
blockChain := fakes.NewMockBlockChainWithHeaders(headers)
|
||||
dbHeader, _ := headerRepository.GetHeader(1)
|
||||
Expect(dbHeader.BlockNumber).To(BeZero())
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(big.NewInt(2))
|
||||
headerRepository.SetMissingBlockNumbers([]int64{2})
|
||||
|
||||
history.PopulateMissingHeaders(blockChain, headerRepository, 1)
|
||||
|
||||
dbHeader, _ = headerRepository.GetHeader(1)
|
||||
Expect(dbHeader.BlockNumber).To(Equal(int64(1)))
|
||||
headerRepository.AssertCreateOrUpdateHeaderCallCountAndPassedBlockNumbers(1, []int64{2})
|
||||
})
|
||||
})
|
||||
|
@ -22,7 +22,7 @@ func (window ValidationWindow) Size() int {
|
||||
return int(window.UpperBound - window.LowerBound)
|
||||
}
|
||||
|
||||
func MakeValidationWindow(blockchain core.Blockchain, windowSize int) ValidationWindow {
|
||||
func MakeValidationWindow(blockchain core.BlockChain, windowSize int) ValidationWindow {
|
||||
upperBound := blockchain.LastBlock().Int64()
|
||||
lowerBound := upperBound - int64(windowSize)
|
||||
return ValidationWindow{lowerBound, upperBound}
|
||||
|
@ -6,22 +6,17 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/history"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var _ = Describe("", func() {
|
||||
var _ = Describe("Validation window", func() {
|
||||
It("creates a ValidationWindow equal to (HEAD-windowSize, HEAD)", func() {
|
||||
blockchain := fakes.NewMockBlockChainWithBlocks([]core.Block{
|
||||
{Number: 1},
|
||||
{Number: 2},
|
||||
{Number: 3},
|
||||
{Number: 4},
|
||||
{Number: 5},
|
||||
})
|
||||
blockChain := fakes.NewMockBlockChain()
|
||||
blockChain.SetLastBlock(big.NewInt(5))
|
||||
|
||||
validationWindow := history.MakeValidationWindow(blockchain, 2)
|
||||
validationWindow := history.MakeValidationWindow(blockChain, 2)
|
||||
|
||||
Expect(validationWindow.LowerBound).To(Equal(int64(3)))
|
||||
Expect(validationWindow.UpperBound).To(Equal(int64(5)))
|
||||
|
Loading…
Reference in New Issue
Block a user