port over lightSync updates from maker repo
This commit is contained in:
parent
26aaa8319b
commit
390a60f7f6
29
cmd/erc20.go
29
cmd/erc20.go
@ -20,20 +20,14 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered/dai"
|
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered/dai"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
"github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block"
|
||||||
"github.com/vulcanize/vulcanizedb/examples/generic"
|
"github.com/vulcanize/vulcanizedb/examples/generic"
|
||||||
"github.com/vulcanize/vulcanizedb/libraries/shared"
|
"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"
|
|
||||||
vRpc "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/omni/constants"
|
"github.com/vulcanize/vulcanizedb/pkg/omni/constants"
|
||||||
|
"github.com/vulcanize/vulcanizedb/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// erc20Cmd represents the erc20 command
|
// erc20Cmd represents the erc20 command
|
||||||
@ -62,25 +56,14 @@ Expects an ethereum node to be running and requires a .toml config file:
|
|||||||
func watchERC20s() {
|
func watchERC20s() {
|
||||||
ticker := time.NewTicker(5 * time.Second)
|
ticker := time.NewTicker(5 * time.Second)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
rawRpcClient, err := rpc.Dial(ipc)
|
|
||||||
if err != nil {
|
blockChain := getBlockChain()
|
||||||
log.Fatal(err)
|
db := utils.LoadPostgres(databaseConfig, blockChain.Node())
|
||||||
}
|
|
||||||
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 {
|
|
||||||
log.Fatal("Failed to initialize database.")
|
|
||||||
}
|
|
||||||
|
|
||||||
con := generic.DaiConfig
|
con := generic.DaiConfig
|
||||||
con.Filters = constants.DaiERC20Filters
|
con.Filters = constants.DaiERC20Filters
|
||||||
watcher := shared.Watcher{
|
watcher := shared.Watcher{
|
||||||
DB: *db,
|
DB: db,
|
||||||
Blockchain: blockChain,
|
Blockchain: blockChain,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +72,7 @@ func watchERC20s() {
|
|||||||
// collect balances and allowances at every block
|
// collect balances and allowances at every block
|
||||||
transformers := append(dai.DaiEventTriggeredTransformerInitializer(), every_block.ERC20EveryBlockTransformerInitializer()...)
|
transformers := append(dai.DaiEventTriggeredTransformerInitializer(), every_block.ERC20EveryBlockTransformerInitializer()...)
|
||||||
|
|
||||||
err = watcher.AddTransformers(transformers, con)
|
err := watcher.AddTransformers(transformers, con)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,20 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Copyright © 2018 Vulcanize
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -21,17 +35,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
|
||||||
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/pkg/history"
|
||||||
"github.com/vulcanize/vulcanizedb/utils"
|
"github.com/vulcanize/vulcanizedb/utils"
|
||||||
)
|
)
|
||||||
@ -42,16 +51,12 @@ var lightSyncCmd = &cobra.Command{
|
|||||||
Short: "Syncs VulcanizeDB with local ethereum node's block headers",
|
Short: "Syncs VulcanizeDB with local ethereum node's block headers",
|
||||||
Long: `Syncs VulcanizeDB with local ethereum node. Populates
|
Long: `Syncs VulcanizeDB with local ethereum node. Populates
|
||||||
Postgres with block headers.
|
Postgres with block headers.
|
||||||
|
|
||||||
./vulcanizedb lightSync --starting-block-number 0 --config public.toml
|
./vulcanizedb lightSync --starting-block-number 0 --config public.toml
|
||||||
|
|
||||||
Expects ethereum node to be running and requires a .toml config:
|
Expects ethereum node to be running and requires a .toml config:
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
name = "vulcanize_public"
|
name = "vulcanize_public"
|
||||||
hostname = "localhost"
|
hostname = "localhost"
|
||||||
port = 5432
|
port = 5432
|
||||||
|
|
||||||
[client]
|
[client]
|
||||||
ipcPath = "/Users/user/Library/Ethereum/geth.ipc"
|
ipcPath = "/Users/user/Library/Ethereum/geth.ipc"
|
||||||
`,
|
`,
|
||||||
@ -66,32 +71,20 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
populated, err := history.PopulateMissingHeaders(blockchain, headerRepository, startingBlockNumber)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error populating headers: ", err)
|
||||||
|
}
|
||||||
|
missingBlocksPopulated <- populated
|
||||||
}
|
}
|
||||||
|
|
||||||
func lightSync() {
|
func lightSync() {
|
||||||
ticker := time.NewTicker(pollingInterval)
|
ticker := time.NewTicker(pollingInterval)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
rawRpcClient, err := rpc.Dial(ipc)
|
blockChain := getBlockChain()
|
||||||
if err != nil {
|
validateArgs(blockChain)
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
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()
|
|
||||||
if lastBlock == 0 {
|
|
||||||
log.Fatal("geth initial: state sync not finished")
|
|
||||||
}
|
|
||||||
if startingBlockNumber > lastBlock {
|
|
||||||
log.Fatal("starting block number > current block number")
|
|
||||||
}
|
|
||||||
|
|
||||||
db := utils.LoadPostgres(databaseConfig, blockChain.Node())
|
db := utils.LoadPostgres(databaseConfig, blockChain.Node())
|
||||||
|
|
||||||
headerRepository := repositories.NewHeaderRepository(&db)
|
headerRepository := repositories.NewHeaderRepository(&db)
|
||||||
validator := history.NewHeaderValidator(blockChain, headerRepository, validationWindow)
|
validator := history.NewHeaderValidator(blockChain, headerRepository, validationWindow)
|
||||||
missingBlocksPopulated := make(chan int)
|
missingBlocksPopulated := make(chan int)
|
||||||
@ -107,3 +100,13 @@ func lightSync() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateArgs(blockChain *geth.BlockChain) {
|
||||||
|
lastBlock := blockChain.LastBlock().Int64()
|
||||||
|
if lastBlock == 0 {
|
||||||
|
log.Fatal("geth initial: state sync not finished")
|
||||||
|
}
|
||||||
|
if startingBlockNumber > lastBlock {
|
||||||
|
log.Fatal("starting block number > current block number")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -19,23 +19,16 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/libraries/shared"
|
"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"
|
|
||||||
vRpc "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/omni/transformer"
|
"github.com/vulcanize/vulcanizedb/pkg/omni/transformer"
|
||||||
|
"github.com/vulcanize/vulcanizedb/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// omniWatcherCmd represents the omniWatcher command
|
// omniWatcherCmd represents the omniWatcher command
|
||||||
@ -92,9 +85,9 @@ func omniWatcher() {
|
|||||||
ticker := time.NewTicker(5 * time.Second)
|
ticker := time.NewTicker(5 * time.Second)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
blockChain, db := setupBCandDB()
|
blockChain := getBlockChain()
|
||||||
|
db := utils.LoadPostgres(databaseConfig, blockChain.Node())
|
||||||
t := transformer.NewTransformer(network, blockChain, db)
|
t := transformer.NewTransformer(network, blockChain, &db)
|
||||||
|
|
||||||
contractAddresses = append(contractAddresses, contractAddress)
|
contractAddresses = append(contractAddresses, contractAddress)
|
||||||
for _, addr := range contractAddresses {
|
for _, addr := range contractAddresses {
|
||||||
@ -131,23 +124,3 @@ func init() {
|
|||||||
omniWatcherCmd.Flags().Int64VarP(&startingBlockNumber, "starting-block-number", "s", 0, "Block to begin watching- default is first block the contract exists")
|
omniWatcherCmd.Flags().Int64VarP(&startingBlockNumber, "starting-block-number", "s", 0, "Block to begin watching- default is first block the contract exists")
|
||||||
omniWatcherCmd.Flags().Int64VarP(&startingBlockNumber, "ending-block-number", "d", -1, "Block to end watching- default is most recent block")
|
omniWatcherCmd.Flags().Int64VarP(&startingBlockNumber, "ending-block-number", "d", -1, "Block to end watching- default is most recent block")
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupBCandDB() (core.BlockChain, *postgres.DB) {
|
|
||||||
rawRpcClient, err := rpc.Dial(ipc)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(fmt.Sprintf("Failed to initialize rpc client\r\nerr: %v\r\n", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
rpcClient := client.NewRpcClient(rawRpcClient, ipc)
|
|
||||||
ethClient := ethclient.NewClient(rawRpcClient)
|
|
||||||
cli := client.NewEthClient(ethClient)
|
|
||||||
n := node.MakeNode(rpcClient)
|
|
||||||
transactionConverter := vRpc.NewRpcTransactionConverter(ethClient)
|
|
||||||
blockChain := geth.NewBlockChain(cli, n, transactionConverter)
|
|
||||||
db, err := postgres.NewDB(databaseConfig, blockChain.Node())
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(fmt.Sprintf("Failed to initialize database\r\nerr: %v\r\n", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
return blockChain, db
|
|
||||||
}
|
|
||||||
|
22
cmd/root.go
22
cmd/root.go
@ -18,12 +18,20 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
||||||
|
vRpc "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -109,3 +117,17 @@ func initConfig() {
|
|||||||
fmt.Printf("Using config file: %s\n\n", viper.ConfigFileUsed())
|
fmt.Printf("Using config file: %s\n\n", viper.ConfigFileUsed())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getBlockChain() *geth.BlockChain {
|
||||||
|
rawRpcClient, err := rpc.Dial(ipc)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
rpcClient := client.NewRpcClient(rawRpcClient, ipc)
|
||||||
|
ethClient := ethclient.NewClient(rawRpcClient)
|
||||||
|
vdbEthClient := client.NewEthClient(ethClient)
|
||||||
|
vdbNode := node.MakeNode(rpcClient)
|
||||||
|
transactionConverter := vRpc.NewRpcTransactionConverter(ethClient)
|
||||||
|
return geth.NewBlockChain(vdbEthClient, rpcClient, vdbNode, transactionConverter)
|
||||||
|
}
|
||||||
|
18
cmd/sync.go
18
cmd/sync.go
@ -21,17 +21,11 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth"
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
|
|
||||||
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/pkg/history"
|
||||||
"github.com/vulcanize/vulcanizedb/utils"
|
"github.com/vulcanize/vulcanizedb/utils"
|
||||||
)
|
)
|
||||||
@ -78,16 +72,8 @@ func backFillAllBlocks(blockchain core.BlockChain, blockRepository datastore.Blo
|
|||||||
func sync() {
|
func sync() {
|
||||||
ticker := time.NewTicker(pollingInterval)
|
ticker := time.NewTicker(pollingInterval)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
rawRpcClient, err := rpc.Dial(ipc)
|
|
||||||
if err != nil {
|
blockChain := getBlockChain()
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
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()
|
lastBlock := blockChain.LastBlock().Int64()
|
||||||
if lastBlock == 0 {
|
if lastBlock == 0 {
|
||||||
|
@ -2,7 +2,8 @@ CREATE TABLE public.headers (
|
|||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
hash VARCHAR(66),
|
hash VARCHAR(66),
|
||||||
block_number BIGINT,
|
block_number BIGINT,
|
||||||
raw bytea,
|
raw JSONB,
|
||||||
|
block_timestamp NUMERIC,
|
||||||
eth_node_id INTEGER,
|
eth_node_id INTEGER,
|
||||||
eth_node_fingerprint VARCHAR(128),
|
eth_node_fingerprint VARCHAR(128),
|
||||||
CONSTRAINT eth_nodes_fk FOREIGN KEY (eth_node_id)
|
CONSTRAINT eth_nodes_fk FOREIGN KEY (eth_node_id)
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
DROP TABLE public.checked_headers;
|
@ -0,0 +1,5 @@
|
|||||||
|
CREATE TABLE public.checked_headers (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
header_id INTEGER UNIQUE NOT NULL REFERENCES headers (id) ON DELETE CASCADE,
|
||||||
|
price_feeds_checked BOOLEAN NOT NULL DEFAULT FALSE
|
||||||
|
);
|
@ -61,7 +61,7 @@ var _ = Describe("ERC20 Getter", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
realGetter := every_block.NewGetter(blockChain)
|
realGetter := every_block.NewGetter(blockChain)
|
||||||
result, err := realGetter.GetTotalSupply(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
result, err := realGetter.GetTotalSupply(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ var _ = Describe("ERC20 Getter", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
realGetter := every_block.NewGetter(blockChain)
|
realGetter := every_block.NewGetter(blockChain)
|
||||||
|
|
||||||
testTokenHolderAddress := common.HexToAddress("0x2cccc4b4708b318a6290511aac75d6c3dbe0cf9f")
|
testTokenHolderAddress := common.HexToAddress("0x2cccc4b4708b318a6290511aac75d6c3dbe0cf9f")
|
||||||
@ -179,7 +179,7 @@ var _ = Describe("ERC20 Getter", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
realGetter := every_block.NewGetter(blockChain)
|
realGetter := every_block.NewGetter(blockChain)
|
||||||
|
|
||||||
testTokenHolderAddress := common.HexToAddress("0x2cccc4b4708b318a6290511aac75d6c3dbe0cf9f")
|
testTokenHolderAddress := common.HexToAddress("0x2cccc4b4708b318a6290511aac75d6c3dbe0cf9f")
|
||||||
|
@ -61,7 +61,7 @@ var _ = Describe("every_block Getter", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
realGetter := every_block.NewGetter(blockChain)
|
realGetter := every_block.NewGetter(blockChain)
|
||||||
result, err := realGetter.GetStoppedStatus(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
result, err := realGetter.GetStoppedStatus(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ var _ = Describe("every_block Getter", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
realGetter := every_block.NewGetter(blockChain)
|
realGetter := every_block.NewGetter(blockChain)
|
||||||
result, err := realGetter.GetOwner(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
result, err := realGetter.GetOwner(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ var _ = Describe("every_block Getter", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
realGetter := every_block.NewGetter(blockChain)
|
realGetter := every_block.NewGetter(blockChain)
|
||||||
result, err := realGetter.GetHashName(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
result, err := realGetter.GetHashName(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ var _ = Describe("every_block Getter", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
realGetter := every_block.NewGetter(blockChain)
|
realGetter := every_block.NewGetter(blockChain)
|
||||||
result, err := realGetter.GetHashSymbol(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
result, err := realGetter.GetHashSymbol(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ var _ = Describe("every_block Getter", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
realGetter := every_block.NewGetter(blockChain)
|
realGetter := every_block.NewGetter(blockChain)
|
||||||
result, err := realGetter.GetDecimals(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
result, err := realGetter.GetDecimals(constants.DaiAbiString, constants.DaiContractAddress, blockNumber)
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ var _ = Describe("every_block Getter", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
realGetter := every_block.NewGetter(blockChain)
|
realGetter := every_block.NewGetter(blockChain)
|
||||||
result, err := realGetter.GetStringName(constants.TusdAbiString, constants.TusdContractAddress, blockNumber)
|
result, err := realGetter.GetStringName(constants.TusdAbiString, constants.TusdContractAddress, blockNumber)
|
||||||
|
|
||||||
@ -342,7 +342,7 @@ var _ = Describe("every_block Getter", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
realGetter := every_block.NewGetter(blockChain)
|
realGetter := every_block.NewGetter(blockChain)
|
||||||
result, err := realGetter.GetStringName(constants.TusdAbiString, constants.TusdContractAddress, blockNumber)
|
result, err := realGetter.GetStringName(constants.TusdAbiString, constants.TusdContractAddress, blockNumber)
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ var _ = Describe("Rewards calculations", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := vRpc.NewRpcTransactionConverter(ethClient)
|
transactionConverter := vRpc.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
block, err := blockChain.GetBlockByNumber(1071819)
|
block, err := blockChain.GetBlockByNumber(1071819)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(block.Reward).To(Equal(5.31355))
|
Expect(block.Reward).To(Equal(5.31355))
|
||||||
@ -53,7 +53,7 @@ var _ = Describe("Rewards calculations", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := vRpc.NewRpcTransactionConverter(ethClient)
|
transactionConverter := vRpc.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
block, err := blockChain.GetBlockByNumber(1071819)
|
block, err := blockChain.GetBlockByNumber(1071819)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(block.UnclesReward).To(Equal(6.875))
|
Expect(block.UnclesReward).To(Equal(6.875))
|
||||||
|
@ -56,7 +56,7 @@ var _ = Describe("Reading contracts", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
contract := testing.SampleContract()
|
contract := testing.SampleContract()
|
||||||
|
|
||||||
logs, err := blockChain.GetLogs(contract, big.NewInt(4703824), nil)
|
logs, err := blockChain.GetLogs(contract, big.NewInt(4703824), nil)
|
||||||
@ -74,7 +74,7 @@ var _ = Describe("Reading contracts", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
|
|
||||||
logs, err := blockChain.GetLogs(core.Contract{Hash: "x123"}, big.NewInt(4703824), nil)
|
logs, err := blockChain.GetLogs(core.Contract{Hash: "x123"}, big.NewInt(4703824), nil)
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ var _ = Describe("Reading contracts", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
|
|
||||||
contract := testing.SampleContract()
|
contract := testing.SampleContract()
|
||||||
var balance = new(big.Int)
|
var balance = new(big.Int)
|
||||||
|
@ -43,7 +43,7 @@ var _ = Describe("Reading from the Geth blockchain", func() {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain = geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain = geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("reads two blocks", func(done Done) {
|
It("reads two blocks", func(done Done) {
|
||||||
|
@ -16,8 +16,33 @@
|
|||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
)
|
||||||
|
|
||||||
type Header struct {
|
type Header struct {
|
||||||
|
Id int64
|
||||||
BlockNumber int64 `db:"block_number"`
|
BlockNumber int64 `db:"block_number"`
|
||||||
Hash string
|
Hash string
|
||||||
Raw []byte
|
Raw []byte
|
||||||
|
Timestamp string `db:"block_timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type POAHeader struct {
|
||||||
|
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
|
||||||
|
UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"`
|
||||||
|
Coinbase common.Address `json:"miner" gencodec:"required"`
|
||||||
|
Root common.Hash `json:"stateRoot" gencodec:"required"`
|
||||||
|
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
|
||||||
|
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
|
||||||
|
Bloom types.Bloom `json:"logsBloom" gencodec:"required"`
|
||||||
|
Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"`
|
||||||
|
Number *hexutil.Big `json:"number" gencodec:"required"`
|
||||||
|
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
|
||||||
|
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
|
||||||
|
Time *hexutil.Big `json:"timestamp" gencodec:"required"`
|
||||||
|
Extra hexutil.Bytes `json:"extraData" gencodec:"required"`
|
||||||
|
Hash common.Hash `json:"hash"`
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,11 @@ const (
|
|||||||
GETH NodeType = iota
|
GETH NodeType = iota
|
||||||
PARITY
|
PARITY
|
||||||
INFURA
|
INFURA
|
||||||
|
GANACHE
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
KOVAN_NETWORK_ID = 42
|
||||||
)
|
)
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
|
@ -92,6 +92,7 @@ var _ = Describe("Postgres DB", func() {
|
|||||||
}
|
}
|
||||||
node := core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "geth"}
|
node := core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "geth"}
|
||||||
db := test_config.NewTestDB(node)
|
db := test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
blocksRepository := repositories.NewBlockRepository(db)
|
blocksRepository := repositories.NewBlockRepository(db)
|
||||||
|
|
||||||
_, err1 := blocksRepository.CreateOrUpdateBlock(badBlock)
|
_, err1 := blocksRepository.CreateOrUpdateBlock(badBlock)
|
||||||
|
@ -42,6 +42,7 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
db = test_config.NewTestDB(node)
|
db = test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
blockRepository = repositories.NewBlockRepository(db)
|
blockRepository = repositories.NewBlockRepository(db)
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -58,6 +59,7 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
ClientName: "Geth",
|
ClientName: "Geth",
|
||||||
}
|
}
|
||||||
dbTwo := test_config.NewTestDB(nodeTwo)
|
dbTwo := test_config.NewTestDB(nodeTwo)
|
||||||
|
test_config.CleanTestDB(dbTwo)
|
||||||
repositoryTwo := repositories.NewBlockRepository(dbTwo)
|
repositoryTwo := repositories.NewBlockRepository(dbTwo)
|
||||||
|
|
||||||
_, err := repositoryTwo.GetBlock(123)
|
_, err := repositoryTwo.GetBlock(123)
|
||||||
@ -184,6 +186,7 @@ var _ = Describe("Saving blocks", func() {
|
|||||||
NetworkID: 1,
|
NetworkID: 1,
|
||||||
}
|
}
|
||||||
dbTwo := test_config.NewTestDB(nodeTwo)
|
dbTwo := test_config.NewTestDB(nodeTwo)
|
||||||
|
test_config.CleanTestDB(dbTwo)
|
||||||
repositoryTwo := repositories.NewBlockRepository(dbTwo)
|
repositoryTwo := repositories.NewBlockRepository(dbTwo)
|
||||||
|
|
||||||
blockRepository.CreateOrUpdateBlock(blockOne)
|
blockRepository.CreateOrUpdateBlock(blockOne)
|
||||||
|
@ -41,6 +41,7 @@ var _ = Describe("Creating contracts", func() {
|
|||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
db = test_config.NewTestDB(node)
|
db = test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
contractRepository = repositories.ContractRepository{DB: db}
|
contractRepository = repositories.ContractRepository{DB: db}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -18,10 +18,14 @@ package repositories
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrValidHeaderExists = errors.New("valid header already exists")
|
||||||
|
|
||||||
type HeaderRepository struct {
|
type HeaderRepository struct {
|
||||||
database *postgres.DB
|
database *postgres.DB
|
||||||
}
|
}
|
||||||
@ -41,7 +45,7 @@ func (repository HeaderRepository) CreateOrUpdateHeader(header core.Header) (int
|
|||||||
if headerMustBeReplaced(hash, header) {
|
if headerMustBeReplaced(hash, header) {
|
||||||
return repository.replaceHeader(header)
|
return repository.replaceHeader(header)
|
||||||
}
|
}
|
||||||
return 0, err
|
return 0, ErrValidHeaderExists
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repository HeaderRepository) GetHeader(blockNumber int64) (core.Header, error) {
|
func (repository HeaderRepository) GetHeader(blockNumber int64) (core.Header, error) {
|
||||||
@ -81,8 +85,8 @@ func (repository HeaderRepository) getHeaderHash(header core.Header) (string, er
|
|||||||
func (repository HeaderRepository) insertHeader(header core.Header) (int64, error) {
|
func (repository HeaderRepository) insertHeader(header core.Header) (int64, error) {
|
||||||
var headerId int64
|
var headerId int64
|
||||||
err := repository.database.QueryRowx(
|
err := repository.database.QueryRowx(
|
||||||
`INSERT INTO public.headers (block_number, hash, raw, eth_node_id, eth_node_fingerprint) VALUES ($1, $2, $3, $4, $5) RETURNING id`,
|
`INSERT INTO public.headers (block_number, hash, block_timestamp, raw, eth_node_id, eth_node_fingerprint) VALUES ($1, $2, $3::NUMERIC, $4, $5, $6) RETURNING id`,
|
||||||
header.BlockNumber, header.Hash, header.Raw, repository.database.NodeID, repository.database.Node.ID).Scan(&headerId)
|
header.BlockNumber, header.Hash, header.Timestamp, header.Raw, repository.database.NodeID, repository.database.Node.ID).Scan(&headerId)
|
||||||
return headerId, err
|
return headerId, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,44 +18,66 @@ package repositories_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"encoding/json"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
"github.com/vulcanize/vulcanizedb/test_config"
|
"github.com/vulcanize/vulcanizedb/test_config"
|
||||||
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Block header repository", func() {
|
var _ = Describe("Block header repository", func() {
|
||||||
Describe("creating or updating a header", func() {
|
var (
|
||||||
|
rawHeader []byte
|
||||||
|
err error
|
||||||
|
timestamp string
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
rawHeader, err = json.Marshal(types.Header{})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
timestamp = big.NewInt(123456789).String()
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("creating or updating a header", func() {
|
||||||
It("adds a header", func() {
|
It("adds a header", func() {
|
||||||
node := core.Node{}
|
node := core.Node{}
|
||||||
db := test_config.NewTestDB(node)
|
db := test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
repo := repositories.NewHeaderRepository(db)
|
repo := repositories.NewHeaderRepository(db)
|
||||||
header := core.Header{
|
header := core.Header{
|
||||||
BlockNumber: 100,
|
BlockNumber: 100,
|
||||||
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
||||||
Raw: []byte{1, 2, 3, 4, 5},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := repo.CreateOrUpdateHeader(header)
|
_, err := repo.CreateOrUpdateHeader(header)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
var dbHeader core.Header
|
var dbHeader core.Header
|
||||||
err = db.Get(&dbHeader, `SELECT block_number, hash, raw FROM public.headers WHERE block_number = $1`, header.BlockNumber)
|
err = db.Get(&dbHeader, `SELECT block_number, hash, raw, block_timestamp FROM public.headers WHERE block_number = $1`, header.BlockNumber)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(dbHeader.BlockNumber).To(Equal(header.BlockNumber))
|
Expect(dbHeader.BlockNumber).To(Equal(header.BlockNumber))
|
||||||
Expect(dbHeader.Hash).To(Equal(header.Hash))
|
Expect(dbHeader.Hash).To(Equal(header.Hash))
|
||||||
Expect(dbHeader.Raw).To(Equal(header.Raw))
|
Expect(dbHeader.Raw).To(MatchJSON(header.Raw))
|
||||||
|
Expect(dbHeader.Timestamp).To(Equal(header.Timestamp))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("adds node data to header", func() {
|
It("adds node data to header", func() {
|
||||||
node := core.Node{ID: "EthNodeFingerprint"}
|
node := core.Node{ID: "EthNodeFingerprint"}
|
||||||
db := test_config.NewTestDB(node)
|
db := test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
repo := repositories.NewHeaderRepository(db)
|
repo := repositories.NewHeaderRepository(db)
|
||||||
header := core.Header{BlockNumber: 100}
|
header := core.Header{
|
||||||
|
BlockNumber: 100,
|
||||||
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
|
}
|
||||||
|
|
||||||
_, err := repo.CreateOrUpdateHeader(header)
|
_, err := repo.CreateOrUpdateHeader(header)
|
||||||
|
|
||||||
@ -70,21 +92,24 @@ var _ = Describe("Block header repository", func() {
|
|||||||
Expect(ethNodeFingerprint).To(Equal(db.Node.ID))
|
Expect(ethNodeFingerprint).To(Equal(db.Node.ID))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("does not duplicate headers", func() {
|
It("returns valid header exists error if attempting duplicate headers", func() {
|
||||||
node := core.Node{}
|
node := core.Node{}
|
||||||
db := test_config.NewTestDB(node)
|
db := test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
repo := repositories.NewHeaderRepository(db)
|
repo := repositories.NewHeaderRepository(db)
|
||||||
header := core.Header{
|
header := core.Header{
|
||||||
BlockNumber: 100,
|
BlockNumber: 100,
|
||||||
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
||||||
Raw: []byte{1, 2, 3, 4, 5},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := repo.CreateOrUpdateHeader(header)
|
_, err := repo.CreateOrUpdateHeader(header)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
_, err = repo.CreateOrUpdateHeader(header)
|
_, err = repo.CreateOrUpdateHeader(header)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err).To(MatchError(repositories.ErrValidHeaderExists))
|
||||||
|
|
||||||
var dbHeaders []core.Header
|
var dbHeaders []core.Header
|
||||||
err = db.Select(&dbHeaders, `SELECT block_number, hash, raw FROM public.headers WHERE block_number = $1`, header.BlockNumber)
|
err = db.Select(&dbHeaders, `SELECT block_number, hash, raw FROM public.headers WHERE block_number = $1`, header.BlockNumber)
|
||||||
@ -95,18 +120,21 @@ var _ = Describe("Block header repository", func() {
|
|||||||
It("replaces header if hash is different", func() {
|
It("replaces header if hash is different", func() {
|
||||||
node := core.Node{}
|
node := core.Node{}
|
||||||
db := test_config.NewTestDB(node)
|
db := test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
repo := repositories.NewHeaderRepository(db)
|
repo := repositories.NewHeaderRepository(db)
|
||||||
header := core.Header{
|
header := core.Header{
|
||||||
BlockNumber: 100,
|
BlockNumber: 100,
|
||||||
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
||||||
Raw: []byte{1, 2, 3, 4, 5},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
_, err := repo.CreateOrUpdateHeader(header)
|
_, err := repo.CreateOrUpdateHeader(header)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
headerTwo := core.Header{
|
headerTwo := core.Header{
|
||||||
BlockNumber: header.BlockNumber,
|
BlockNumber: header.BlockNumber,
|
||||||
Hash: common.BytesToHash([]byte{5, 4, 3, 2, 1}).Hex(),
|
Hash: common.BytesToHash([]byte{5, 4, 3, 2, 1}).Hex(),
|
||||||
Raw: []byte{5, 4, 3, 2, 1},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = repo.CreateOrUpdateHeader(headerTwo)
|
_, err = repo.CreateOrUpdateHeader(headerTwo)
|
||||||
@ -116,17 +144,19 @@ var _ = Describe("Block header repository", func() {
|
|||||||
err = db.Get(&dbHeader, `SELECT block_number, hash, raw FROM headers WHERE block_number = $1`, header.BlockNumber)
|
err = db.Get(&dbHeader, `SELECT block_number, hash, raw FROM headers WHERE block_number = $1`, header.BlockNumber)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(dbHeader.Hash).To(Equal(headerTwo.Hash))
|
Expect(dbHeader.Hash).To(Equal(headerTwo.Hash))
|
||||||
Expect(dbHeader.Raw).To(Equal(headerTwo.Raw))
|
Expect(dbHeader.Raw).To(MatchJSON(headerTwo.Raw))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("does not replace header if node fingerprint is different", func() {
|
It("does not replace header if node fingerprint is different", func() {
|
||||||
node := core.Node{ID: "Fingerprint"}
|
node := core.Node{ID: "Fingerprint"}
|
||||||
db := test_config.NewTestDB(node)
|
db := test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
repo := repositories.NewHeaderRepository(db)
|
repo := repositories.NewHeaderRepository(db)
|
||||||
header := core.Header{
|
header := core.Header{
|
||||||
BlockNumber: 100,
|
BlockNumber: 100,
|
||||||
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
||||||
Raw: []byte{1, 2, 3, 4, 5},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
_, err := repo.CreateOrUpdateHeader(header)
|
_, err := repo.CreateOrUpdateHeader(header)
|
||||||
nodeTwo := core.Node{ID: "FingerprintTwo"}
|
nodeTwo := core.Node{ID: "FingerprintTwo"}
|
||||||
@ -136,7 +166,8 @@ var _ = Describe("Block header repository", func() {
|
|||||||
headerTwo := core.Header{
|
headerTwo := core.Header{
|
||||||
BlockNumber: header.BlockNumber,
|
BlockNumber: header.BlockNumber,
|
||||||
Hash: common.BytesToHash([]byte{5, 4, 3, 2, 1}).Hex(),
|
Hash: common.BytesToHash([]byte{5, 4, 3, 2, 1}).Hex(),
|
||||||
Raw: []byte{5, 4, 3, 2, 1},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = repoTwo.CreateOrUpdateHeader(headerTwo)
|
_, err = repoTwo.CreateOrUpdateHeader(headerTwo)
|
||||||
@ -155,7 +186,8 @@ var _ = Describe("Block header repository", func() {
|
|||||||
header := core.Header{
|
header := core.Header{
|
||||||
BlockNumber: 100,
|
BlockNumber: 100,
|
||||||
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
||||||
Raw: []byte{1, 2, 3, 4, 5},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
_, err := repo.CreateOrUpdateHeader(header)
|
_, err := repo.CreateOrUpdateHeader(header)
|
||||||
nodeTwo := core.Node{ID: "FingerprintTwo"}
|
nodeTwo := core.Node{ID: "FingerprintTwo"}
|
||||||
@ -165,13 +197,15 @@ var _ = Describe("Block header repository", func() {
|
|||||||
headerTwo := core.Header{
|
headerTwo := core.Header{
|
||||||
BlockNumber: header.BlockNumber,
|
BlockNumber: header.BlockNumber,
|
||||||
Hash: common.BytesToHash([]byte{5, 4, 3, 2, 1}).Hex(),
|
Hash: common.BytesToHash([]byte{5, 4, 3, 2, 1}).Hex(),
|
||||||
Raw: []byte{5, 4, 3, 2, 1},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
_, err = repoTwo.CreateOrUpdateHeader(headerTwo)
|
_, err = repoTwo.CreateOrUpdateHeader(headerTwo)
|
||||||
headerThree := core.Header{
|
headerThree := core.Header{
|
||||||
BlockNumber: header.BlockNumber,
|
BlockNumber: header.BlockNumber,
|
||||||
Hash: common.BytesToHash([]byte{1, 1, 1, 1, 1}).Hex(),
|
Hash: common.BytesToHash([]byte{1, 1, 1, 1, 1}).Hex(),
|
||||||
Raw: []byte{1, 1, 1, 1, 1},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = repoTwo.CreateOrUpdateHeader(headerThree)
|
_, err = repoTwo.CreateOrUpdateHeader(headerThree)
|
||||||
@ -183,8 +217,8 @@ var _ = Describe("Block header repository", func() {
|
|||||||
Expect(len(dbHeaders)).To(Equal(2))
|
Expect(len(dbHeaders)).To(Equal(2))
|
||||||
Expect(dbHeaders[0].Hash).To(Or(Equal(header.Hash), Equal(headerThree.Hash)))
|
Expect(dbHeaders[0].Hash).To(Or(Equal(header.Hash), Equal(headerThree.Hash)))
|
||||||
Expect(dbHeaders[1].Hash).To(Or(Equal(header.Hash), Equal(headerThree.Hash)))
|
Expect(dbHeaders[1].Hash).To(Or(Equal(header.Hash), Equal(headerThree.Hash)))
|
||||||
Expect(dbHeaders[0].Raw).To(Or(Equal(header.Raw), Equal(headerThree.Raw)))
|
Expect(dbHeaders[0].Raw).To(Or(MatchJSON(header.Raw), MatchJSON(headerThree.Raw)))
|
||||||
Expect(dbHeaders[1].Raw).To(Or(Equal(header.Raw), Equal(headerThree.Raw)))
|
Expect(dbHeaders[1].Raw).To(Or(MatchJSON(header.Raw), MatchJSON(headerThree.Raw)))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -192,11 +226,13 @@ var _ = Describe("Block header repository", func() {
|
|||||||
It("returns header if it exists", func() {
|
It("returns header if it exists", func() {
|
||||||
node := core.Node{}
|
node := core.Node{}
|
||||||
db := test_config.NewTestDB(node)
|
db := test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
repo := repositories.NewHeaderRepository(db)
|
repo := repositories.NewHeaderRepository(db)
|
||||||
header := core.Header{
|
header := core.Header{
|
||||||
BlockNumber: 100,
|
BlockNumber: 100,
|
||||||
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
||||||
Raw: []byte{1, 2, 3, 4, 5},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
_, err := repo.CreateOrUpdateHeader(header)
|
_, err := repo.CreateOrUpdateHeader(header)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
@ -204,17 +240,21 @@ var _ = Describe("Block header repository", func() {
|
|||||||
dbHeader, err := repo.GetHeader(header.BlockNumber)
|
dbHeader, err := repo.GetHeader(header.BlockNumber)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(dbHeader).To(Equal(header))
|
Expect(dbHeader.BlockNumber).To(Equal(header.BlockNumber))
|
||||||
|
Expect(dbHeader.Hash).To(Equal(header.Hash))
|
||||||
|
Expect(dbHeader.Raw).To(MatchJSON(header.Raw))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("does not return header for a different node fingerprint", func() {
|
It("does not return header for a different node fingerprint", func() {
|
||||||
node := core.Node{}
|
node := core.Node{}
|
||||||
db := test_config.NewTestDB(node)
|
db := test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
repo := repositories.NewHeaderRepository(db)
|
repo := repositories.NewHeaderRepository(db)
|
||||||
header := core.Header{
|
header := core.Header{
|
||||||
BlockNumber: 100,
|
BlockNumber: 100,
|
||||||
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
|
Hash: common.BytesToHash(rawHeader).Hex(),
|
||||||
Raw: []byte{1, 2, 3, 4, 5},
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
_, err := repo.CreateOrUpdateHeader(header)
|
_, err := repo.CreateOrUpdateHeader(header)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
@ -234,10 +274,23 @@ var _ = Describe("Block header repository", func() {
|
|||||||
It("returns block numbers for headers not in the database", func() {
|
It("returns block numbers for headers not in the database", func() {
|
||||||
node := core.Node{}
|
node := core.Node{}
|
||||||
db := test_config.NewTestDB(node)
|
db := test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
repo := repositories.NewHeaderRepository(db)
|
repo := repositories.NewHeaderRepository(db)
|
||||||
repo.CreateOrUpdateHeader(core.Header{BlockNumber: 1})
|
repo.CreateOrUpdateHeader(core.Header{
|
||||||
repo.CreateOrUpdateHeader(core.Header{BlockNumber: 3})
|
BlockNumber: 1,
|
||||||
repo.CreateOrUpdateHeader(core.Header{BlockNumber: 5})
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
|
})
|
||||||
|
repo.CreateOrUpdateHeader(core.Header{
|
||||||
|
BlockNumber: 3,
|
||||||
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
|
})
|
||||||
|
repo.CreateOrUpdateHeader(core.Header{
|
||||||
|
BlockNumber: 5,
|
||||||
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
|
})
|
||||||
|
|
||||||
missingBlockNumbers := repo.MissingBlockNumbers(1, 5, node.ID)
|
missingBlockNumbers := repo.MissingBlockNumbers(1, 5, node.ID)
|
||||||
|
|
||||||
@ -247,10 +300,23 @@ var _ = Describe("Block header repository", func() {
|
|||||||
It("does not count headers created by a different node fingerprint", func() {
|
It("does not count headers created by a different node fingerprint", func() {
|
||||||
node := core.Node{ID: "NodeFingerprint"}
|
node := core.Node{ID: "NodeFingerprint"}
|
||||||
db := test_config.NewTestDB(node)
|
db := test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
repo := repositories.NewHeaderRepository(db)
|
repo := repositories.NewHeaderRepository(db)
|
||||||
repo.CreateOrUpdateHeader(core.Header{BlockNumber: 1})
|
repo.CreateOrUpdateHeader(core.Header{
|
||||||
repo.CreateOrUpdateHeader(core.Header{BlockNumber: 3})
|
BlockNumber: 1,
|
||||||
repo.CreateOrUpdateHeader(core.Header{BlockNumber: 5})
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
|
})
|
||||||
|
repo.CreateOrUpdateHeader(core.Header{
|
||||||
|
BlockNumber: 3,
|
||||||
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
|
})
|
||||||
|
repo.CreateOrUpdateHeader(core.Header{
|
||||||
|
BlockNumber: 5,
|
||||||
|
Raw: rawHeader,
|
||||||
|
Timestamp: timestamp,
|
||||||
|
})
|
||||||
nodeTwo := core.Node{ID: "NodeFingerprintTwo"}
|
nodeTwo := core.Node{ID: "NodeFingerprintTwo"}
|
||||||
dbTwo, err := postgres.NewDB(test_config.DBConfig, nodeTwo)
|
dbTwo, err := postgres.NewDB(test_config.DBConfig, nodeTwo)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
@ -39,6 +39,7 @@ var _ = Describe("Log Filters Repository", func() {
|
|||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
db = test_config.NewTestDB(node)
|
db = test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
filterRepository = repositories.FilterRepository{DB: db}
|
filterRepository = repositories.FilterRepository{DB: db}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ var _ = Describe("Logs Repository", func() {
|
|||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
db = test_config.NewTestDB(node)
|
db = test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
blockRepository = repositories.NewBlockRepository(db)
|
blockRepository = repositories.NewBlockRepository(db)
|
||||||
logsRepository = repositories.LogRepository{DB: db}
|
logsRepository = repositories.LogRepository{DB: db}
|
||||||
receiptRepository = repositories.ReceiptRepository{DB: db}
|
receiptRepository = repositories.ReceiptRepository{DB: db}
|
||||||
|
@ -40,6 +40,7 @@ var _ = Describe("Receipts Repository", func() {
|
|||||||
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
}
|
}
|
||||||
db = test_config.NewTestDB(node)
|
db = test_config.NewTestDB(node)
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
blockRepository = repositories.NewBlockRepository(db)
|
blockRepository = repositories.NewBlockRepository(db)
|
||||||
logRepository = repositories.LogRepository{DB: db}
|
logRepository = repositories.LogRepository{DB: db}
|
||||||
receiptRepository = repositories.ReceiptRepository{DB: db}
|
receiptRepository = repositories.ReceiptRepository{DB: db}
|
||||||
|
@ -37,6 +37,7 @@ var _ = Describe("Watched Events Repository", func() {
|
|||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
db = test_config.NewTestDB(core.Node{})
|
db = test_config.NewTestDB(core.Node{})
|
||||||
|
test_config.CleanTestDB(db)
|
||||||
blocksRepository = repositories.NewBlockRepository(db)
|
blocksRepository = repositories.NewBlockRepository(db)
|
||||||
filterRepository = repositories.FilterRepository{DB: db}
|
filterRepository = repositories.FilterRepository{DB: db}
|
||||||
logRepository = repositories.LogRepository{DB: db}
|
logRepository = repositories.LogRepository{DB: db}
|
||||||
|
@ -16,6 +16,35 @@
|
|||||||
|
|
||||||
package fakes
|
package fakes
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
var FakeError = errors.New("failed")
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
FakeError = errors.New("failed")
|
||||||
|
FakeHash = common.BytesToHash([]byte{1, 2, 3, 4, 5})
|
||||||
|
fakeTimestamp = int64(111111111)
|
||||||
|
)
|
||||||
|
|
||||||
|
var rawFakeHeader, _ = json.Marshal(types.Header{})
|
||||||
|
var FakeHeader = core.Header{
|
||||||
|
Hash: FakeHash.String(),
|
||||||
|
Raw: rawFakeHeader,
|
||||||
|
Timestamp: strconv.FormatInt(fakeTimestamp, 10),
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFakeHeader(blockNumber int64) core.Header {
|
||||||
|
return core.Header{
|
||||||
|
Hash: FakeHash.String(),
|
||||||
|
BlockNumber: blockNumber,
|
||||||
|
Raw: rawFakeHeader,
|
||||||
|
Timestamp: strconv.FormatInt(fakeTimestamp, 10),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,29 +18,38 @@ package fakes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockRpcClient struct {
|
type MockRpcClient struct {
|
||||||
ipcPath string
|
callContextErr error
|
||||||
nodeType core.NodeType
|
ipcPath string
|
||||||
|
nodeType core.NodeType
|
||||||
|
passedContext context.Context
|
||||||
|
passedMethod string
|
||||||
|
passedResult interface{}
|
||||||
|
returnPOAHeader core.POAHeader
|
||||||
|
supportedModules map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMockRpcClient() *MockRpcClient {
|
func NewMockRpcClient() *MockRpcClient {
|
||||||
return &MockRpcClient{}
|
return &MockRpcClient{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *MockRpcClient) SetNodeType(nodeType core.NodeType) {
|
|
||||||
client.nodeType = nodeType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (client *MockRpcClient) SetIpcPath(ipcPath string) {
|
func (client *MockRpcClient) SetIpcPath(ipcPath string) {
|
||||||
client.ipcPath = ipcPath
|
client.ipcPath = ipcPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*MockRpcClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
|
func (client *MockRpcClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
|
||||||
|
client.passedContext = ctx
|
||||||
|
client.passedResult = result
|
||||||
|
client.passedMethod = method
|
||||||
switch method {
|
switch method {
|
||||||
case "admin_nodeInfo":
|
case "admin_nodeInfo":
|
||||||
if p, ok := result.(*p2p.NodeInfo); ok {
|
if p, ok := result.(*p2p.NodeInfo); ok {
|
||||||
@ -49,9 +58,14 @@ func (*MockRpcClient) CallContext(ctx context.Context, result interface{}, metho
|
|||||||
}
|
}
|
||||||
case "eth_getBlockByNumber":
|
case "eth_getBlockByNumber":
|
||||||
if p, ok := result.(*types.Header); ok {
|
if p, ok := result.(*types.Header); ok {
|
||||||
*p = types.Header{}
|
*p = types.Header{Number: big.NewInt(123)}
|
||||||
|
}
|
||||||
|
if p, ok := result.(*core.POAHeader); ok {
|
||||||
|
*p = client.returnPOAHeader
|
||||||
|
}
|
||||||
|
if client.callContextErr != nil {
|
||||||
|
return client.callContextErr
|
||||||
}
|
}
|
||||||
|
|
||||||
case "parity_versionInfo":
|
case "parity_versionInfo":
|
||||||
if p, ok := result.(*core.ParityNodeInfo); ok {
|
if p, ok := result.(*core.ParityNodeInfo); ok {
|
||||||
*p = core.ParityNodeInfo{
|
*p = core.ParityNodeInfo{
|
||||||
@ -81,9 +95,23 @@ func (client *MockRpcClient) IpcPath() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (client *MockRpcClient) SupportedModules() (map[string]string, error) {
|
func (client *MockRpcClient) SupportedModules() (map[string]string, error) {
|
||||||
result := make(map[string]string)
|
return client.supportedModules, nil
|
||||||
if client.nodeType == core.GETH {
|
}
|
||||||
result["admin"] = "ok"
|
|
||||||
}
|
func (client *MockRpcClient) SetSupporedModules(supportedModules map[string]string) {
|
||||||
return result, nil
|
client.supportedModules = supportedModules
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *MockRpcClient) SetCallContextErr(err error) {
|
||||||
|
client.callContextErr = err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *MockRpcClient) SetReturnPOAHeader(header core.POAHeader) {
|
||||||
|
client.returnPOAHeader = header
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *MockRpcClient) AssertCallContextCalledWith(ctx context.Context, result interface{}, method string) {
|
||||||
|
Expect(client.passedContext).To(Equal(ctx))
|
||||||
|
Expect(client.passedResult).To(BeAssignableToTypeOf(result))
|
||||||
|
Expect(client.passedMethod).To(Equal(method))
|
||||||
}
|
}
|
||||||
|
@ -17,34 +17,41 @@
|
|||||||
package geth
|
package geth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
|
vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrEmptyHeader = errors.New("empty header returned over RPC")
|
||||||
|
|
||||||
type BlockChain struct {
|
type BlockChain struct {
|
||||||
client core.EthClient
|
|
||||||
blockConverter vulcCommon.BlockConverter
|
blockConverter vulcCommon.BlockConverter
|
||||||
|
ethClient core.EthClient
|
||||||
headerConverter vulcCommon.HeaderConverter
|
headerConverter vulcCommon.HeaderConverter
|
||||||
node core.Node
|
node core.Node
|
||||||
|
rpcClient core.RpcClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBlockChain(client core.EthClient, node core.Node, converter vulcCommon.TransactionConverter) *BlockChain {
|
func NewBlockChain(ethClient core.EthClient, rpcClient core.RpcClient, node core.Node, converter vulcCommon.TransactionConverter) *BlockChain {
|
||||||
return &BlockChain{
|
return &BlockChain{
|
||||||
client: client,
|
|
||||||
blockConverter: vulcCommon.NewBlockConverter(converter),
|
blockConverter: vulcCommon.NewBlockConverter(converter),
|
||||||
|
ethClient: ethClient,
|
||||||
headerConverter: vulcCommon.HeaderConverter{},
|
headerConverter: vulcCommon.HeaderConverter{},
|
||||||
node: node,
|
node: node,
|
||||||
|
rpcClient: rpcClient,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (blockChain *BlockChain) GetBlockByNumber(blockNumber int64) (block core.Block, err error) {
|
func (blockChain *BlockChain) GetBlockByNumber(blockNumber int64) (block core.Block, err error) {
|
||||||
gethBlock, err := blockChain.client.BlockByNumber(context.Background(), big.NewInt(blockNumber))
|
gethBlock, err := blockChain.ethClient.BlockByNumber(context.Background(), big.NewInt(blockNumber))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return block, err
|
return block, err
|
||||||
}
|
}
|
||||||
@ -52,11 +59,46 @@ func (blockChain *BlockChain) GetBlockByNumber(blockNumber int64) (block core.Bl
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (blockChain *BlockChain) GetHeaderByNumber(blockNumber int64) (header core.Header, err error) {
|
func (blockChain *BlockChain) GetHeaderByNumber(blockNumber int64) (header core.Header, err error) {
|
||||||
gethHeader, err := blockChain.client.HeaderByNumber(context.Background(), big.NewInt(blockNumber))
|
if blockChain.node.NetworkID == core.KOVAN_NETWORK_ID {
|
||||||
|
return blockChain.getPOAHeader(blockNumber)
|
||||||
|
}
|
||||||
|
return blockChain.getPOWHeader(blockNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blockChain *BlockChain) getPOWHeader(blockNumber int64) (header core.Header, err error) {
|
||||||
|
gethHeader, err := blockChain.ethClient.HeaderByNumber(context.Background(), big.NewInt(blockNumber))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return header, err
|
return header, err
|
||||||
}
|
}
|
||||||
return blockChain.headerConverter.Convert(gethHeader)
|
return blockChain.headerConverter.Convert(gethHeader, gethHeader.Hash().String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blockChain *BlockChain) getPOAHeader(blockNumber int64) (header core.Header, err error) {
|
||||||
|
var POAHeader core.POAHeader
|
||||||
|
blockNumberArg := hexutil.EncodeBig(big.NewInt(blockNumber))
|
||||||
|
includeTransactions := false
|
||||||
|
err = blockChain.rpcClient.CallContext(context.Background(), &POAHeader, "eth_getBlockByNumber", blockNumberArg, includeTransactions)
|
||||||
|
if err != nil {
|
||||||
|
return header, err
|
||||||
|
}
|
||||||
|
if POAHeader.Number == nil {
|
||||||
|
return header, ErrEmptyHeader
|
||||||
|
}
|
||||||
|
return blockChain.headerConverter.Convert(&types.Header{
|
||||||
|
ParentHash: POAHeader.ParentHash,
|
||||||
|
UncleHash: POAHeader.UncleHash,
|
||||||
|
Coinbase: POAHeader.Coinbase,
|
||||||
|
Root: POAHeader.Root,
|
||||||
|
TxHash: POAHeader.TxHash,
|
||||||
|
ReceiptHash: POAHeader.ReceiptHash,
|
||||||
|
Bloom: POAHeader.Bloom,
|
||||||
|
Difficulty: POAHeader.Difficulty.ToInt(),
|
||||||
|
Number: POAHeader.Number.ToInt(),
|
||||||
|
GasLimit: uint64(POAHeader.GasLimit),
|
||||||
|
GasUsed: uint64(POAHeader.GasUsed),
|
||||||
|
Time: POAHeader.Time.ToInt(),
|
||||||
|
Extra: POAHeader.Extra,
|
||||||
|
}, POAHeader.Hash.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (blockChain *BlockChain) GetLogs(contract core.Contract, startingBlockNumber, endingBlockNumber *big.Int) ([]core.Log, error) {
|
func (blockChain *BlockChain) GetLogs(contract core.Contract, startingBlockNumber, endingBlockNumber *big.Int) ([]core.Log, error) {
|
||||||
@ -68,8 +110,9 @@ func (blockChain *BlockChain) GetLogs(contract core.Contract, startingBlockNumbe
|
|||||||
FromBlock: startingBlockNumber,
|
FromBlock: startingBlockNumber,
|
||||||
ToBlock: endingBlockNumber,
|
ToBlock: endingBlockNumber,
|
||||||
Addresses: []common.Address{contractAddress},
|
Addresses: []common.Address{contractAddress},
|
||||||
|
Topics: nil,
|
||||||
}
|
}
|
||||||
gethLogs, err := blockChain.client.FilterLogs(context.Background(), fc)
|
gethLogs, err := blockChain.GetEthLogsWithCustomQuery(fc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []core.Log{}, err
|
return []core.Log{}, err
|
||||||
}
|
}
|
||||||
@ -77,8 +120,16 @@ func (blockChain *BlockChain) GetLogs(contract core.Contract, startingBlockNumbe
|
|||||||
return logs, nil
|
return logs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (blockChain *BlockChain) GetEthLogsWithCustomQuery(query ethereum.FilterQuery) ([]types.Log, error) {
|
||||||
|
gethLogs, err := blockChain.ethClient.FilterLogs(context.Background(), query)
|
||||||
|
if err != nil {
|
||||||
|
return []types.Log{}, err
|
||||||
|
}
|
||||||
|
return gethLogs, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (blockChain *BlockChain) LastBlock() *big.Int {
|
func (blockChain *BlockChain) LastBlock() *big.Int {
|
||||||
block, _ := blockChain.client.HeaderByNumber(context.Background(), nil)
|
block, _ := blockChain.ethClient.HeaderByNumber(context.Background(), nil)
|
||||||
return block.Number
|
return block.Number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@ -33,12 +34,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Geth blockchain", func() {
|
var _ = Describe("Geth blockchain", func() {
|
||||||
|
var mockClient *fakes.MockEthClient
|
||||||
|
var mockRpcClient *fakes.MockRpcClient
|
||||||
|
var node vulcCore.Node
|
||||||
|
var blockChain *geth.BlockChain
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
mockClient = fakes.NewMockEthClient()
|
||||||
|
mockRpcClient = fakes.NewMockRpcClient()
|
||||||
|
node = vulcCore.Node{}
|
||||||
|
blockChain = geth.NewBlockChain(mockClient, mockRpcClient, node, cold_db.NewColdDbTransactionConverter())
|
||||||
|
})
|
||||||
|
|
||||||
Describe("getting a block", func() {
|
Describe("getting a block", func() {
|
||||||
It("fetches block from client", func() {
|
It("fetches block from ethClient", func() {
|
||||||
mockClient := fakes.NewMockEthClient()
|
|
||||||
mockClient.SetBlockByNumberReturnBlock(types.NewBlockWithHeader(&types.Header{}))
|
mockClient.SetBlockByNumberReturnBlock(types.NewBlockWithHeader(&types.Header{}))
|
||||||
node := vulcCore.Node{}
|
|
||||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
|
||||||
blockNumber := int64(100)
|
blockNumber := int64(100)
|
||||||
|
|
||||||
_, err := blockChain.GetBlockByNumber(blockNumber)
|
_, err := blockChain.GetBlockByNumber(blockNumber)
|
||||||
@ -47,11 +57,8 @@ var _ = Describe("Geth blockchain", func() {
|
|||||||
mockClient.AssertBlockByNumberCalledWith(context.Background(), big.NewInt(blockNumber))
|
mockClient.AssertBlockByNumberCalledWith(context.Background(), big.NewInt(blockNumber))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns err if client returns err", func() {
|
It("returns err if ethClient returns err", func() {
|
||||||
mockClient := fakes.NewMockEthClient()
|
|
||||||
mockClient.SetBlockByNumberErr(fakes.FakeError)
|
mockClient.SetBlockByNumberErr(fakes.FakeError)
|
||||||
node := vulcCore.Node{}
|
|
||||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
|
||||||
|
|
||||||
_, err := blockChain.GetBlockByNumber(100)
|
_, err := blockChain.GetBlockByNumber(100)
|
||||||
|
|
||||||
@ -61,38 +68,66 @@ var _ = Describe("Geth blockchain", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Describe("getting a header", func() {
|
Describe("getting a header", func() {
|
||||||
It("fetches header from client", func() {
|
Describe("default/mainnet", func() {
|
||||||
mockClient := fakes.NewMockEthClient()
|
It("fetches header from ethClient", func() {
|
||||||
blockNumber := int64(100)
|
blockNumber := int64(100)
|
||||||
mockClient.SetHeaderByNumberReturnHeader(&types.Header{Number: big.NewInt(blockNumber)})
|
mockClient.SetHeaderByNumberReturnHeader(&types.Header{Number: big.NewInt(blockNumber)})
|
||||||
node := vulcCore.Node{}
|
|
||||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
|
||||||
|
|
||||||
_, err := blockChain.GetHeaderByNumber(blockNumber)
|
_, err := blockChain.GetHeaderByNumber(blockNumber)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
mockClient.AssertHeaderByNumberCalledWith(context.Background(), big.NewInt(blockNumber))
|
mockClient.AssertHeaderByNumberCalledWith(context.Background(), big.NewInt(blockNumber))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns err if ethClient returns err", func() {
|
||||||
|
mockClient.SetHeaderByNumberErr(fakes.FakeError)
|
||||||
|
|
||||||
|
_, err := blockChain.GetHeaderByNumber(100)
|
||||||
|
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err).To(MatchError(fakes.FakeError))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns err if client returns err", func() {
|
Describe("POA/Kovan", func() {
|
||||||
mockClient := fakes.NewMockEthClient()
|
It("fetches header from rpcClient", func() {
|
||||||
mockClient.SetHeaderByNumberErr(fakes.FakeError)
|
node.NetworkID = vulcCore.KOVAN_NETWORK_ID
|
||||||
node := vulcCore.Node{}
|
blockNumber := hexutil.Big(*big.NewInt(123))
|
||||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
mockRpcClient.SetReturnPOAHeader(vulcCore.POAHeader{Number: &blockNumber})
|
||||||
|
blockChain = geth.NewBlockChain(mockClient, mockRpcClient, node, cold_db.NewColdDbTransactionConverter())
|
||||||
|
|
||||||
_, err := blockChain.GetHeaderByNumber(100)
|
_, err := blockChain.GetHeaderByNumber(100)
|
||||||
|
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(err).To(MatchError(fakes.FakeError))
|
mockRpcClient.AssertCallContextCalledWith(context.Background(), &vulcCore.POAHeader{}, "eth_getBlockByNumber")
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns err if rpcClient returns err", func() {
|
||||||
|
node.NetworkID = vulcCore.KOVAN_NETWORK_ID
|
||||||
|
mockRpcClient.SetCallContextErr(fakes.FakeError)
|
||||||
|
blockChain = geth.NewBlockChain(mockClient, mockRpcClient, node, cold_db.NewColdDbTransactionConverter())
|
||||||
|
|
||||||
|
_, err := blockChain.GetHeaderByNumber(100)
|
||||||
|
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err).To(MatchError(fakes.FakeError))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns error if returned header is empty", func() {
|
||||||
|
node.NetworkID = vulcCore.KOVAN_NETWORK_ID
|
||||||
|
blockChain = geth.NewBlockChain(mockClient, mockRpcClient, node, cold_db.NewColdDbTransactionConverter())
|
||||||
|
|
||||||
|
_, err := blockChain.GetHeaderByNumber(100)
|
||||||
|
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err).To(MatchError(geth.ErrEmptyHeader))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("getting logs", func() {
|
Describe("getting logs with default FilterQuery", func() {
|
||||||
It("fetches logs from client", func() {
|
It("fetches logs from ethClient", func() {
|
||||||
mockClient := fakes.NewMockEthClient()
|
|
||||||
mockClient.SetFilterLogsReturnLogs([]types.Log{{}})
|
mockClient.SetFilterLogsReturnLogs([]types.Log{{}})
|
||||||
node := vulcCore.Node{}
|
|
||||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
|
||||||
contract := vulcCore.Contract{Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex()}
|
contract := vulcCore.Contract{Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex()}
|
||||||
startingBlockNumber := big.NewInt(1)
|
startingBlockNumber := big.NewInt(1)
|
||||||
endingBlockNumber := big.NewInt(2)
|
endingBlockNumber := big.NewInt(2)
|
||||||
@ -108,11 +143,8 @@ var _ = Describe("Geth blockchain", func() {
|
|||||||
mockClient.AssertFilterLogsCalledWith(context.Background(), expectedQuery)
|
mockClient.AssertFilterLogsCalledWith(context.Background(), expectedQuery)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns err if client returns err", func() {
|
It("returns err if ethClient returns err", func() {
|
||||||
mockClient := fakes.NewMockEthClient()
|
|
||||||
mockClient.SetFilterLogsErr(fakes.FakeError)
|
mockClient.SetFilterLogsErr(fakes.FakeError)
|
||||||
node := vulcCore.Node{}
|
|
||||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
|
||||||
contract := vulcCore.Contract{Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex()}
|
contract := vulcCore.Contract{Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex()}
|
||||||
startingBlockNumber := big.NewInt(1)
|
startingBlockNumber := big.NewInt(1)
|
||||||
endingBlockNumber := big.NewInt(2)
|
endingBlockNumber := big.NewInt(2)
|
||||||
@ -124,13 +156,49 @@ var _ = Describe("Geth blockchain", func() {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Describe("getting logs with a custom FilterQuery", func() {
|
||||||
|
It("fetches logs from ethClient", func() {
|
||||||
|
mockClient.SetFilterLogsReturnLogs([]types.Log{{}})
|
||||||
|
address := common.HexToAddress("0x")
|
||||||
|
startingBlockNumber := big.NewInt(1)
|
||||||
|
endingBlockNumber := big.NewInt(2)
|
||||||
|
topic := common.HexToHash("0x")
|
||||||
|
query := ethereum.FilterQuery{
|
||||||
|
FromBlock: startingBlockNumber,
|
||||||
|
ToBlock: endingBlockNumber,
|
||||||
|
Addresses: []common.Address{address},
|
||||||
|
Topics: [][]common.Hash{{topic}},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := blockChain.GetEthLogsWithCustomQuery(query)
|
||||||
|
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
mockClient.AssertFilterLogsCalledWith(context.Background(), query)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns err if ethClient returns err", func() {
|
||||||
|
mockClient.SetFilterLogsErr(fakes.FakeError)
|
||||||
|
contract := vulcCore.Contract{Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex()}
|
||||||
|
startingBlockNumber := big.NewInt(1)
|
||||||
|
endingBlockNumber := big.NewInt(2)
|
||||||
|
query := ethereum.FilterQuery{
|
||||||
|
FromBlock: startingBlockNumber,
|
||||||
|
ToBlock: endingBlockNumber,
|
||||||
|
Addresses: []common.Address{common.HexToAddress(contract.Hash)},
|
||||||
|
Topics: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := blockChain.GetEthLogsWithCustomQuery(query)
|
||||||
|
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err).To(MatchError(fakes.FakeError))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
Describe("getting the most recent block number", func() {
|
Describe("getting the most recent block number", func() {
|
||||||
It("fetches latest header from client", func() {
|
It("fetches latest header from ethClient", func() {
|
||||||
mockClient := fakes.NewMockEthClient()
|
|
||||||
blockNumber := int64(100)
|
blockNumber := int64(100)
|
||||||
mockClient.SetHeaderByNumberReturnHeader(&types.Header{Number: big.NewInt(blockNumber)})
|
mockClient.SetHeaderByNumberReturnHeader(&types.Header{Number: big.NewInt(blockNumber)})
|
||||||
node := vulcCore.Node{}
|
|
||||||
blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter())
|
|
||||||
|
|
||||||
result := blockChain.LastBlock()
|
result := blockChain.LastBlock()
|
||||||
|
|
||||||
|
@ -17,9 +17,8 @@
|
|||||||
package geth
|
package geth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
@ -54,5 +53,5 @@ func (blockChain *BlockChain) FetchContractData(abiJSON string, address string,
|
|||||||
func (blockChain *BlockChain) callContract(contractHash string, input []byte, blockNumber *big.Int) ([]byte, error) {
|
func (blockChain *BlockChain) callContract(contractHash string, input []byte, blockNumber *big.Int) ([]byte, error) {
|
||||||
to := common.HexToAddress(contractHash)
|
to := common.HexToAddress(contractHash)
|
||||||
msg := ethereum.CallMsg{To: &to, Data: input}
|
msg := ethereum.CallMsg{To: &to, Data: input}
|
||||||
return blockChain.client.CallContract(context.Background(), msg, blockNumber)
|
return blockChain.ethClient.CallContract(context.Background(), msg, blockNumber)
|
||||||
}
|
}
|
||||||
|
@ -17,24 +17,25 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HeaderConverter struct{}
|
type HeaderConverter struct{}
|
||||||
|
|
||||||
func (converter HeaderConverter) Convert(gethHeader *types.Header) (core.Header, error) {
|
func (converter HeaderConverter) Convert(gethHeader *types.Header, blockHash string) (core.Header, error) {
|
||||||
writer := new(bytes.Buffer)
|
rawHeader, err := json.Marshal(gethHeader)
|
||||||
err := rlp.Encode(writer, &gethHeader)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
coreHeader := core.Header{
|
coreHeader := core.Header{
|
||||||
Hash: gethHeader.Hash().Hex(),
|
Hash: blockHash,
|
||||||
BlockNumber: gethHeader.Number.Int64(),
|
BlockNumber: gethHeader.Number.Int64(),
|
||||||
Raw: writer.Bytes(),
|
Raw: rawHeader,
|
||||||
|
Timestamp: gethHeader.Time.String(),
|
||||||
}
|
}
|
||||||
return coreHeader, nil
|
return coreHeader, nil
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,16 @@
|
|||||||
package common_test
|
package common_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"encoding/json"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||||
common2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
|
common2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
|
||||||
"math/big"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Block header converter", func() {
|
var _ = Describe("Block header converter", func() {
|
||||||
@ -35,29 +37,30 @@ var _ = Describe("Block header converter", func() {
|
|||||||
ParentHash: common.HexToHash("0xParent"),
|
ParentHash: common.HexToHash("0xParent"),
|
||||||
ReceiptHash: common.HexToHash("0xReceipt"),
|
ReceiptHash: common.HexToHash("0xReceipt"),
|
||||||
Root: common.HexToHash("0xRoot"),
|
Root: common.HexToHash("0xRoot"),
|
||||||
Time: big.NewInt(3),
|
Time: big.NewInt(123456789),
|
||||||
TxHash: common.HexToHash("0xTransaction"),
|
TxHash: common.HexToHash("0xTransaction"),
|
||||||
UncleHash: common.HexToHash("0xUncle"),
|
UncleHash: common.HexToHash("0xUncle"),
|
||||||
}
|
}
|
||||||
converter := common2.HeaderConverter{}
|
converter := common2.HeaderConverter{}
|
||||||
|
hash := fakes.FakeHash.String()
|
||||||
|
|
||||||
coreHeader, err := converter.Convert(gethHeader)
|
coreHeader, err := converter.Convert(gethHeader, hash)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(coreHeader.BlockNumber).To(Equal(gethHeader.Number.Int64()))
|
Expect(coreHeader.BlockNumber).To(Equal(gethHeader.Number.Int64()))
|
||||||
Expect(coreHeader.Hash).To(Equal(gethHeader.Hash().Hex()))
|
Expect(coreHeader.Hash).To(Equal(hash))
|
||||||
|
Expect(coreHeader.Timestamp).To(Equal(gethHeader.Time.String()))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("includes raw bytes for header", func() {
|
It("includes raw bytes for header as JSON", func() {
|
||||||
headerRLP := []byte{249, 2, 23, 160, 180, 251, 173, 248, 234, 69, 43, 19, 151, 24, 226, 112, 13, 193, 19, 92, 252, 129, 20, 80, 49, 200, 75, 122, 178, 124, 215, 16, 57, 79, 123, 56, 160, 29, 204, 77, 232, 222, 199, 93, 122, 171, 133, 181, 103, 182, 204, 212, 26, 211, 18, 69, 27, 148, 138, 116, 19, 240, 161, 66, 253, 64, 212, 147, 71, 148, 42, 101, 172, 164, 213, 252, 91, 92, 133, 144, 144, 166, 195, 77, 22, 65, 53, 57, 130, 38, 160, 14, 6, 111, 60, 34, 151, 165, 203, 48, 5, 147, 5, 38, 23, 209, 188, 165, 148, 111, 12, 170, 6, 53, 253, 177, 184, 90, 199, 229, 35, 111, 52, 160, 101, 186, 136, 127, 203, 8, 38, 246, 22, 208, 31, 115, 108, 29, 45, 103, 123, 202, 189, 226, 247, 252, 37, 170, 145, 207, 188, 11, 59, 173, 92, 179, 160, 32, 227, 83, 69, 64, 202, 241, 99, 120, 230, 232, 106, 43, 241, 35, 109, 159, 135, 109, 50, 24, 251, 192, 57, 88, 230, 219, 28, 99, 75, 35, 51, 185, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 134, 11, 105, 222, 129, 162, 43, 131, 15, 66, 64, 131, 47, 239, 216, 130, 196, 68, 132, 86, 191, 180, 21, 152, 215, 131, 1, 3, 3, 132, 71, 101, 116, 104, 135, 103, 111, 49, 46, 53, 46, 49, 133, 108, 105, 110, 117, 120, 160, 146, 196, 18, 154, 10, 226, 54, 27, 69, 42, 158, 222, 236, 229, 92, 18, 236, 238, 171, 134, 99, 22, 25, 94, 61, 135, 252, 27, 0, 91, 102, 69, 136, 205, 76, 85, 185, 65, 207, 144, 21}
|
gethHeader := types.Header{Number: big.NewInt(123)}
|
||||||
var gethHeader types.Header
|
|
||||||
err := rlp.Decode(bytes.NewReader(headerRLP), &gethHeader)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
converter := common2.HeaderConverter{}
|
converter := common2.HeaderConverter{}
|
||||||
|
|
||||||
coreHeader, err := converter.Convert(&gethHeader)
|
coreHeader, err := converter.Convert(&gethHeader, fakes.FakeHash.String())
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(coreHeader.Raw).To(Equal(headerRLP))
|
expectedJSON, err := json.Marshal(gethHeader)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(coreHeader.Raw).To(Equal(expectedJSON))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -53,6 +53,10 @@ type InfuraClient struct {
|
|||||||
PropertiesReader
|
PropertiesReader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GanacheClient struct {
|
||||||
|
PropertiesReader
|
||||||
|
}
|
||||||
|
|
||||||
func MakeNode(rpcClient core.RpcClient) core.Node {
|
func MakeNode(rpcClient core.RpcClient) core.Node {
|
||||||
pr := makePropertiesReader(rpcClient)
|
pr := makePropertiesReader(rpcClient)
|
||||||
id, name := pr.NodeInfo()
|
id, name := pr.NodeInfo()
|
||||||
@ -72,6 +76,8 @@ func makePropertiesReader(client core.RpcClient) IPropertiesReader {
|
|||||||
return ParityClient{PropertiesReader: PropertiesReader{client: client}}
|
return ParityClient{PropertiesReader: PropertiesReader{client: client}}
|
||||||
case core.INFURA:
|
case core.INFURA:
|
||||||
return InfuraClient{PropertiesReader: PropertiesReader{client: client}}
|
return InfuraClient{PropertiesReader: PropertiesReader{client: client}}
|
||||||
|
case core.GANACHE:
|
||||||
|
return GanacheClient{PropertiesReader: PropertiesReader{client: client}}
|
||||||
default:
|
default:
|
||||||
return PropertiesReader{client: client}
|
return PropertiesReader{client: client}
|
||||||
}
|
}
|
||||||
@ -81,6 +87,9 @@ func getNodeType(client core.RpcClient) core.NodeType {
|
|||||||
if strings.Contains(client.IpcPath(), "infura") {
|
if strings.Contains(client.IpcPath(), "infura") {
|
||||||
return core.INFURA
|
return core.INFURA
|
||||||
}
|
}
|
||||||
|
if strings.Contains(client.IpcPath(), "127.0.0.1") || strings.Contains(client.IpcPath(), "localhost") {
|
||||||
|
return core.GANACHE
|
||||||
|
}
|
||||||
modules, _ := client.SupportedModules()
|
modules, _ := client.SupportedModules()
|
||||||
if _, ok := modules["admin"]; ok {
|
if _, ok := modules["admin"]; ok {
|
||||||
return core.GETH
|
return core.GETH
|
||||||
@ -122,6 +131,10 @@ func (client InfuraClient) NodeInfo() (string, string) {
|
|||||||
return "infura", "infura"
|
return "infura", "infura"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client GanacheClient) NodeInfo() (string, string) {
|
||||||
|
return "ganache", "ganache"
|
||||||
|
}
|
||||||
|
|
||||||
func (client ParityClient) parityNodeInfo() string {
|
func (client ParityClient) parityNodeInfo() string {
|
||||||
var nodeInfo core.ParityNodeInfo
|
var nodeInfo core.ParityNodeInfo
|
||||||
client.client.CallContext(context.Background(), &nodeInfo, "parity_versionInfo")
|
client.client.CallContext(context.Background(), &nodeInfo, "parity_versionInfo")
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
"github.com/vulcanize/vulcanizedb/pkg/fakes"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
|
||||||
@ -28,12 +29,12 @@ import (
|
|||||||
|
|
||||||
var EmpytHeaderHash = "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
|
var EmpytHeaderHash = "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
|
||||||
|
|
||||||
var _ = Describe("Parity Node Info", func() {
|
var _ = Describe("Node Info", func() {
|
||||||
|
Describe("Parity Node Info", func() {
|
||||||
It("verifies parity_versionInfo can be unmarshalled into ParityNodeInfo", func() {
|
It("verifies parity_versionInfo can be unmarshalled into ParityNodeInfo", func() {
|
||||||
var parityNodeInfo core.ParityNodeInfo
|
var parityNodeInfo core.ParityNodeInfo
|
||||||
nodeInfoJSON := []byte(
|
nodeInfoJSON := []byte(
|
||||||
`{
|
`{
|
||||||
"hash": "0x2ae8b4ca278dd7b896090366615fef81cbbbc0e0",
|
"hash": "0x2ae8b4ca278dd7b896090366615fef81cbbbc0e0",
|
||||||
"track": "null",
|
"track": "null",
|
||||||
"version": {
|
"version": {
|
||||||
@ -42,25 +43,34 @@ var _ = Describe("Parity Node Info", func() {
|
|||||||
"patch": 0
|
"patch": 0
|
||||||
}
|
}
|
||||||
}`)
|
}`)
|
||||||
json.Unmarshal(nodeInfoJSON, &parityNodeInfo)
|
json.Unmarshal(nodeInfoJSON, &parityNodeInfo)
|
||||||
Expect(parityNodeInfo.Hash).To(Equal("0x2ae8b4ca278dd7b896090366615fef81cbbbc0e0"))
|
Expect(parityNodeInfo.Hash).To(Equal("0x2ae8b4ca278dd7b896090366615fef81cbbbc0e0"))
|
||||||
Expect(parityNodeInfo.Track).To(Equal("null"))
|
Expect(parityNodeInfo.Track).To(Equal("null"))
|
||||||
Expect(parityNodeInfo.Major).To(Equal(1))
|
Expect(parityNodeInfo.Major).To(Equal(1))
|
||||||
Expect(parityNodeInfo.Minor).To(Equal(6))
|
Expect(parityNodeInfo.Minor).To(Equal(6))
|
||||||
Expect(parityNodeInfo.Patch).To(Equal(0))
|
Expect(parityNodeInfo.Patch).To(Equal(0))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Creates client string", func() {
|
It("Creates client string", func() {
|
||||||
parityNodeInfo := core.ParityNodeInfo{
|
parityNodeInfo := core.ParityNodeInfo{
|
||||||
Track: "null",
|
Track: "null",
|
||||||
ParityVersion: core.ParityVersion{
|
ParityVersion: core.ParityVersion{
|
||||||
Major: 1,
|
Major: 1,
|
||||||
Minor: 6,
|
Minor: 6,
|
||||||
Patch: 0,
|
Patch: 0,
|
||||||
},
|
},
|
||||||
Hash: "0x1232144j",
|
Hash: "0x1232144j",
|
||||||
}
|
}
|
||||||
Expect(parityNodeInfo.String()).To(Equal("Parity/v1.6.0/"))
|
Expect(parityNodeInfo.String()).To(Equal("Parity/v1.6.0/"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns parity ID and client name for parity node", func() {
|
||||||
|
client := fakes.NewMockRpcClient()
|
||||||
|
|
||||||
|
n := node.MakeNode(client)
|
||||||
|
Expect(n.ID).To(Equal("ParityNode"))
|
||||||
|
Expect(n.ClientName).To(Equal("Parity/v1.2.3/"))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns the genesis block for any client", func() {
|
It("returns the genesis block for any client", func() {
|
||||||
@ -75,17 +85,12 @@ var _ = Describe("Parity Node Info", func() {
|
|||||||
Expect(n.NetworkID).To(Equal(float64(1234)))
|
Expect(n.NetworkID).To(Equal(float64(1234)))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns parity ID and client name for parity node", func() {
|
|
||||||
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() {
|
It("returns geth ID and client name for geth node", func() {
|
||||||
client := fakes.NewMockRpcClient()
|
client := fakes.NewMockRpcClient()
|
||||||
client.SetNodeType(core.GETH)
|
supportedModules := make(map[string]string)
|
||||||
|
supportedModules["admin"] = "ok"
|
||||||
|
client.SetSupporedModules(supportedModules)
|
||||||
|
|
||||||
n := node.MakeNode(client)
|
n := node.MakeNode(client)
|
||||||
Expect(n.ID).To(Equal("enode://GethNode@172.17.0.1:30303"))
|
Expect(n.ID).To(Equal("enode://GethNode@172.17.0.1:30303"))
|
||||||
Expect(n.ClientName).To(Equal("Geth/v1.7"))
|
Expect(n.ClientName).To(Equal("Geth/v1.7"))
|
||||||
@ -93,10 +98,22 @@ var _ = Describe("Parity Node Info", func() {
|
|||||||
|
|
||||||
It("returns infura ID and client name for infura node", func() {
|
It("returns infura ID and client name for infura node", func() {
|
||||||
client := fakes.NewMockRpcClient()
|
client := fakes.NewMockRpcClient()
|
||||||
client.SetNodeType(core.INFURA)
|
|
||||||
client.SetIpcPath("infura/path")
|
client.SetIpcPath("infura/path")
|
||||||
n := node.MakeNode(client)
|
n := node.MakeNode(client)
|
||||||
Expect(n.ID).To(Equal("infura"))
|
Expect(n.ID).To(Equal("infura"))
|
||||||
Expect(n.ClientName).To(Equal("infura"))
|
Expect(n.ClientName).To(Equal("infura"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("returns local id and client name for Local node", func() {
|
||||||
|
client := fakes.NewMockRpcClient()
|
||||||
|
client.SetIpcPath("127.0.0.1")
|
||||||
|
n := node.MakeNode(client)
|
||||||
|
Expect(n.ID).To(Equal("ganache"))
|
||||||
|
Expect(n.ClientName).To(Equal("ganache"))
|
||||||
|
|
||||||
|
client.SetIpcPath("localhost")
|
||||||
|
n = node.MakeNode(client)
|
||||||
|
Expect(n.ID).To(Equal("ganache"))
|
||||||
|
Expect(n.ClientName).To(Equal("ganache"))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -17,29 +17,38 @@
|
|||||||
package history
|
package history
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore"
|
||||||
"log"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PopulateMissingHeaders(blockchain core.BlockChain, headerRepository datastore.HeaderRepository, startingBlockNumber int64) int {
|
func PopulateMissingHeaders(blockchain core.BlockChain, headerRepository datastore.HeaderRepository, startingBlockNumber int64) (int, error) {
|
||||||
lastBlock := blockchain.LastBlock().Int64()
|
lastBlock := blockchain.LastBlock().Int64()
|
||||||
blockRange := headerRepository.MissingBlockNumbers(startingBlockNumber, lastBlock, blockchain.Node().ID)
|
blockRange := headerRepository.MissingBlockNumbers(startingBlockNumber, lastBlock, blockchain.Node().ID)
|
||||||
log.SetPrefix("")
|
log.SetPrefix("")
|
||||||
log.Printf("Backfilling %d blocks\n\n", len(blockRange))
|
log.Printf("Backfilling %d blocks\n\n", len(blockRange))
|
||||||
RetrieveAndUpdateHeaders(blockchain, headerRepository, blockRange)
|
_, err := RetrieveAndUpdateHeaders(blockchain, headerRepository, blockRange)
|
||||||
return len(blockRange)
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return len(blockRange), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RetrieveAndUpdateHeaders(blockchain core.BlockChain, headerRepository datastore.HeaderRepository, blockNumbers []int64) int {
|
func RetrieveAndUpdateHeaders(chain core.BlockChain, headerRepository datastore.HeaderRepository, blockNumbers []int64) (int, error) {
|
||||||
for _, blockNumber := range blockNumbers {
|
for _, blockNumber := range blockNumbers {
|
||||||
header, err := blockchain.GetHeaderByNumber(blockNumber)
|
header, err := chain.GetHeaderByNumber(blockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("failed to retrieve block number: %d\n", blockNumber)
|
return 0, err
|
||||||
return 0
|
}
|
||||||
|
_, err = headerRepository.CreateOrUpdateHeader(header)
|
||||||
|
if err != nil {
|
||||||
|
if err == repositories.ErrValidHeaderExists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
// TODO: handle possible error here
|
|
||||||
headerRepository.CreateOrUpdateHeader(header)
|
|
||||||
}
|
}
|
||||||
return len(blockNumbers)
|
return len(blockNumbers), nil
|
||||||
}
|
}
|
||||||
|
@ -34,17 +34,15 @@ var _ = Describe("Populating headers", func() {
|
|||||||
headerRepository = fakes.NewMockHeaderRepository()
|
headerRepository = fakes.NewMockHeaderRepository()
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("When 1 missing header", func() {
|
It("returns number of headers added", func() {
|
||||||
|
blockChain := fakes.NewMockBlockChain()
|
||||||
|
blockChain.SetLastBlock(big.NewInt(2))
|
||||||
|
headerRepository.SetMissingBlockNumbers([]int64{2})
|
||||||
|
|
||||||
It("returns number of headers added", func() {
|
headersAdded, err := history.PopulateMissingHeaders(blockChain, headerRepository, 1)
|
||||||
blockChain := fakes.NewMockBlockChain()
|
|
||||||
blockChain.SetLastBlock(big.NewInt(2))
|
|
||||||
headerRepository.SetMissingBlockNumbers([]int64{2})
|
|
||||||
|
|
||||||
headersAdded := history.PopulateMissingHeaders(blockChain, headerRepository, 1)
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(headersAdded).To(Equal(1))
|
||||||
Expect(headersAdded).To(Equal(1))
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("adds missing headers to the db", func() {
|
It("adds missing headers to the db", func() {
|
||||||
@ -52,8 +50,9 @@ var _ = Describe("Populating headers", func() {
|
|||||||
blockChain.SetLastBlock(big.NewInt(2))
|
blockChain.SetLastBlock(big.NewInt(2))
|
||||||
headerRepository.SetMissingBlockNumbers([]int64{2})
|
headerRepository.SetMissingBlockNumbers([]int64{2})
|
||||||
|
|
||||||
history.PopulateMissingHeaders(blockChain, headerRepository, 1)
|
_, err := history.PopulateMissingHeaders(blockChain, headerRepository, 1)
|
||||||
|
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
headerRepository.AssertCreateOrUpdateHeaderCallCountAndPassedBlockNumbers(1, []int64{2})
|
headerRepository.AssertCreateOrUpdateHeaderCallCountAndPassedBlockNumbers(1, []int64{2})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -74,26 +74,26 @@ func (c *converter) Convert(watchedEvent core.WatchedEvent, event *types.Event)
|
|||||||
|
|
||||||
strValues := make(map[string]string, len(values))
|
strValues := make(map[string]string, len(values))
|
||||||
|
|
||||||
for eventName, input := range values {
|
for fieldName, input := range values {
|
||||||
// Postgres cannot handle custom types, resolve to strings
|
// Postgres cannot handle custom types, resolve to strings
|
||||||
switch input.(type) {
|
switch input.(type) {
|
||||||
case *big.Int:
|
case *big.Int:
|
||||||
var b *big.Int
|
var b *big.Int
|
||||||
b = input.(*big.Int)
|
b = input.(*big.Int)
|
||||||
strValues[eventName] = b.String()
|
strValues[fieldName] = b.String()
|
||||||
case common.Address:
|
case common.Address:
|
||||||
var a common.Address
|
var a common.Address
|
||||||
a = input.(common.Address)
|
a = input.(common.Address)
|
||||||
strValues[eventName] = a.String()
|
strValues[fieldName] = a.String()
|
||||||
c.contractInfo.AddTokenHolderAddress(a.String()) // cache address in a list of contract's token holder addresses
|
c.contractInfo.AddTokenHolderAddress(a.String()) // cache address in a list of contract's token holder addresses
|
||||||
case common.Hash:
|
case common.Hash:
|
||||||
var h common.Hash
|
var h common.Hash
|
||||||
h = input.(common.Hash)
|
h = input.(common.Hash)
|
||||||
strValues[eventName] = h.String()
|
strValues[fieldName] = h.String()
|
||||||
case string:
|
case string:
|
||||||
strValues[eventName] = input.(string)
|
strValues[fieldName] = input.(string)
|
||||||
case bool:
|
case bool:
|
||||||
strValues[eventName] = strconv.FormatBool(input.(bool))
|
strValues[fieldName] = strconv.FormatBool(input.(bool))
|
||||||
default:
|
default:
|
||||||
return errors.New("error: unhandled abi type")
|
return errors.New("error: unhandled abi type")
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ func SetupBC() core.BlockChain {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
|
|
||||||
return blockChain
|
return blockChain
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ func SetupDBandBC() (*postgres.DB, core.BlockChain) {
|
|||||||
blockChainClient := client.NewEthClient(ethClient)
|
blockChainClient := client.NewEthClient(ethClient)
|
||||||
node := node.MakeNode(rpcClient)
|
node := node.MakeNode(rpcClient)
|
||||||
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
|
||||||
blockChain := geth.NewBlockChain(blockChainClient, node, transactionConverter)
|
blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
|
||||||
|
|
||||||
db, err := postgres.NewDB(config.Database{
|
db, err := postgres.NewDB(config.Database{
|
||||||
Hostname: "localhost",
|
Hostname: "localhost",
|
||||||
|
@ -47,6 +47,7 @@ func NewEventDataStore(db *postgres.DB) *eventDatastore {
|
|||||||
// Creates a schema for the contract
|
// Creates a schema for the contract
|
||||||
// Creates tables for the watched contract events
|
// Creates tables for the watched contract events
|
||||||
// Persists converted event log data into these custom tables
|
// Persists converted event log data into these custom tables
|
||||||
|
// Edit this method to accept a single event
|
||||||
func (d *eventDatastore) PersistContractEvents(con *contract.Contract) error {
|
func (d *eventDatastore) PersistContractEvents(con *contract.Contract) error {
|
||||||
_, err := d.CreateContractSchema(con.Address)
|
_, err := d.CreateContractSchema(con.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -209,6 +209,8 @@ func (tr transformer) Execute() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// After converting all logs for events of interest, persist all of the data
|
// After converting all logs for events of interest, persist all of the data
|
||||||
|
// Change this so that event logs are persisted immediately after being created
|
||||||
|
// So as to prevent a huge growth of data in the contract memory
|
||||||
err := tr.PersistContractEvents(con)
|
err := tr.PersistContractEvents(con)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -20,15 +20,18 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||||
|
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
|
||||||
)
|
)
|
||||||
|
|
||||||
var TestConfig *viper.Viper
|
var TestConfig *viper.Viper
|
||||||
var DBConfig config.Database
|
var DBConfig config.Database
|
||||||
|
var TestClient config.Client
|
||||||
var Infura *viper.Viper
|
var Infura *viper.Viper
|
||||||
var InfuraClient config.Client
|
var InfuraClient config.Client
|
||||||
var ABIFilePath string
|
var ABIFilePath string
|
||||||
@ -44,6 +47,7 @@ func setTestConfig() {
|
|||||||
TestConfig.SetConfigName("private")
|
TestConfig.SetConfigName("private")
|
||||||
TestConfig.AddConfigPath("$GOPATH/src/github.com/vulcanize/vulcanizedb/environments/")
|
TestConfig.AddConfigPath("$GOPATH/src/github.com/vulcanize/vulcanizedb/environments/")
|
||||||
err := TestConfig.ReadInConfig()
|
err := TestConfig.ReadInConfig()
|
||||||
|
ipc := TestConfig.GetString("client.ipcPath")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -55,6 +59,9 @@ func setTestConfig() {
|
|||||||
Name: name,
|
Name: name,
|
||||||
Port: port,
|
Port: port,
|
||||||
}
|
}
|
||||||
|
TestClient = config.Client{
|
||||||
|
IPCPath: ipc,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setInfuraConfig() {
|
func setInfuraConfig() {
|
||||||
@ -78,14 +85,34 @@ func setABIPath() {
|
|||||||
|
|
||||||
func NewTestDB(node core.Node) *postgres.DB {
|
func NewTestDB(node core.Node) *postgres.DB {
|
||||||
db, _ := postgres.NewDB(DBConfig, node)
|
db, _ := postgres.NewDB(DBConfig, node)
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
|
||||||
|
func CleanTestDB(db *postgres.DB) {
|
||||||
db.MustExec("DELETE FROM blocks")
|
db.MustExec("DELETE FROM blocks")
|
||||||
db.MustExec("DELETE FROM headers")
|
db.MustExec("DELETE FROM headers")
|
||||||
|
db.MustExec("DELETE FROM checked_headers")
|
||||||
db.MustExec("DELETE FROM log_filters")
|
db.MustExec("DELETE FROM log_filters")
|
||||||
db.MustExec("DELETE FROM logs")
|
db.MustExec("DELETE FROM logs")
|
||||||
db.MustExec("DELETE FROM receipts")
|
db.MustExec("DELETE FROM receipts")
|
||||||
db.MustExec("DELETE FROM transactions")
|
db.MustExec("DELETE FROM transactions")
|
||||||
db.MustExec("DELETE FROM watched_contracts")
|
db.MustExec("DELETE FROM watched_contracts")
|
||||||
return db
|
}
|
||||||
|
|
||||||
|
func NewTestNode() core.Node {
|
||||||
|
return core.Node{
|
||||||
|
GenesisBlock: "GENESIS",
|
||||||
|
NetworkID: 1,
|
||||||
|
ID: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
|
||||||
|
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTestBlock(blockNumber int64, repository repositories.BlockRepository) (blockId int64) {
|
||||||
|
blockId, err := repository.CreateOrUpdateBlock(core.Block{Number: blockNumber})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
return blockId
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTestDBWithoutDeletingRecords(node core.Node) *postgres.DB {
|
func NewTestDBWithoutDeletingRecords(node core.Node) *postgres.DB {
|
||||||
|
Loading…
Reference in New Issue
Block a user