watcher configuration; super node versioning
This commit is contained in:
+102
-4
@@ -17,10 +17,24 @@
|
||||
package watcher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/wasm"
|
||||
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/config"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/eth/client"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/eth/core"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/postgres"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/super_node/btc"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/super_node/eth"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/super_node/shared"
|
||||
shared2 "github.com/vulcanize/vulcanizedb/pkg/watcher/shared"
|
||||
"github.com/vulcanize/vulcanizedb/utils"
|
||||
)
|
||||
|
||||
// Config holds all of the parameters necessary for defining and running an instance of a watcher
|
||||
@@ -32,9 +46,93 @@ type Config struct {
|
||||
// DB itself
|
||||
DB *postgres.DB
|
||||
// Subscription client
|
||||
Client core.RPCClient
|
||||
Client interface{}
|
||||
// WASM instantiation paths and namespaces
|
||||
WASMInstances [][2]string
|
||||
// Path and names for trigger functions (sql files) that (can) use the instantiated wasm namespaces
|
||||
TriggerFunctions [][2]string
|
||||
WASMFunctions []wasm.WasmFunction
|
||||
// File paths for trigger functions (sql files) that (can) use the instantiated wasm namespaces
|
||||
TriggerFunctions []string
|
||||
// Chain type used to specify what type of raw data we will be processing
|
||||
Chain shared.ChainType
|
||||
// Source type used to specify which streamer to use based on what API we will be interfacing with
|
||||
Source shared2.SourceType
|
||||
// Info for the node
|
||||
NodeInfo core.Node
|
||||
}
|
||||
|
||||
func NewWatcherConfig() (*Config, error) {
|
||||
c := new(Config)
|
||||
var err error
|
||||
chain := viper.GetString("watcher.chain")
|
||||
c.Chain, err = shared.NewChainType(chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch c.Chain {
|
||||
case shared.Ethereum:
|
||||
c.SubscriptionConfig, err = eth.NewEthSubscriptionConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case shared.Bitcoin:
|
||||
c.SubscriptionConfig, err = btc.NewEthSubscriptionConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case shared.Omni:
|
||||
return nil, errors.New("omni chain type currently not supported")
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected chain type %s", c.Chain.String())
|
||||
}
|
||||
sourcePath := viper.GetString("watcher.dataSource")
|
||||
if sourcePath == "" {
|
||||
sourcePath = "ws://127.0.0.1:8080" // default to and try the default ws url if no path is provided
|
||||
}
|
||||
sourceType := viper.GetString("watcher.dataPath")
|
||||
c.Source, err = shared2.NewSourceType(sourceType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch c.Source {
|
||||
case shared2.Ethereum:
|
||||
return nil, errors.New("ethereum data source currently not supported")
|
||||
case shared2.Bitcoin:
|
||||
return nil, errors.New("bitcoin data source currently not supported")
|
||||
case shared2.VulcanizeDB:
|
||||
rawRPCClient, err := rpc.Dial(sourcePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cli := client.NewRPCClient(rawRPCClient, sourcePath)
|
||||
var nodeInfo core.Node
|
||||
if err := cli.CallContext(context.Background(), &nodeInfo, "vdb_node"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.NodeInfo = nodeInfo
|
||||
c.Client = cli
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected data source type %s", c.Source.String())
|
||||
}
|
||||
wasmBinaries := viper.GetStringSlice("watcher.wasmBinaries")
|
||||
wasmNamespaces := viper.GetStringSlice("watcher.wasmNamespaces")
|
||||
if len(wasmBinaries) != len(wasmNamespaces) {
|
||||
return nil, fmt.Errorf("watcher config needs a namespace for every wasm binary\r\nhave %d binaries and %d namespaces", len(wasmBinaries), len(wasmNamespaces))
|
||||
}
|
||||
c.WASMFunctions = make([]wasm.WasmFunction, len(wasmBinaries))
|
||||
for i, bin := range wasmBinaries {
|
||||
c.WASMFunctions[i] = wasm.WasmFunction{
|
||||
BinaryPath: bin,
|
||||
Namespace: wasmNamespaces[i],
|
||||
}
|
||||
}
|
||||
c.TriggerFunctions = viper.GetStringSlice("watcher.triggerFunctions")
|
||||
c.DBConfig = config.Database{
|
||||
Name: viper.GetString("watcher.database.name"),
|
||||
Hostname: viper.GetString("watcher.database.hostname"),
|
||||
Port: viper.GetInt("watcher.database.port"),
|
||||
User: viper.GetString("watcher.database.user"),
|
||||
Password: viper.GetString("watcher.database.password"),
|
||||
}
|
||||
db := utils.LoadPostgres(c.DBConfig, c.NodeInfo)
|
||||
c.DB = &db
|
||||
return c, nil
|
||||
}
|
||||
|
||||
@@ -28,12 +28,22 @@ import (
|
||||
)
|
||||
|
||||
// NewSuperNodeStreamer returns a new shared.SuperNodeStreamer
|
||||
func NewSuperNodeStreamer(client core.RPCClient) shared.SuperNodeStreamer {
|
||||
return streamer.NewSuperNodeStreamer(client)
|
||||
func NewSuperNodeStreamer(source shared.SourceType, client interface{}) (shared.SuperNodeStreamer, error) {
|
||||
switch source {
|
||||
case shared.VulcanizeDB:
|
||||
cli, ok := client.(core.RPCClient)
|
||||
if !ok {
|
||||
var expectedClientType core.RPCClient
|
||||
return nil, fmt.Errorf("vulcanizedb NewSuperNodeStreamer construct expects client type %T got %T", expectedClientType, client)
|
||||
}
|
||||
return streamer.NewSuperNodeStreamer(cli), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("NewSuperNodeStreamer constructor unexpected souce type %s", source.String())
|
||||
}
|
||||
}
|
||||
|
||||
// NewRepository constructs and returns a new Repository that satisfies the shared.Repository interface for the specified chain
|
||||
func NewRepository(chain shared2.ChainType, db *postgres.DB, triggerFuncs [][2]string) (shared.Repository, error) {
|
||||
func NewRepository(chain shared2.ChainType, db *postgres.DB, triggerFuncs []string) (shared.Repository, error) {
|
||||
switch chain {
|
||||
case shared2.Ethereum:
|
||||
return eth.NewRepository(db, triggerFuncs), nil
|
||||
|
||||
@@ -32,12 +32,12 @@ var (
|
||||
// Repository is the underlying struct for satisfying the shared.Repository interface for eth
|
||||
type Repository struct {
|
||||
db *postgres.DB
|
||||
triggerFunctions [][2]string
|
||||
triggerFunctions []string
|
||||
deleteCalls int64
|
||||
}
|
||||
|
||||
// NewRepository returns a new eth.Repository that satisfies the shared.Repository interface
|
||||
func NewRepository(db *postgres.DB, triggerFunctions [][2]string) shared.Repository {
|
||||
func NewRepository(db *postgres.DB, triggerFunctions []string) shared.Repository {
|
||||
return &Repository{
|
||||
db: db,
|
||||
triggerFunctions: triggerFunctions,
|
||||
|
||||
@@ -40,7 +40,7 @@ type Watcher interface {
|
||||
// Service is the underlying struct for the SuperNodeWatcher
|
||||
type Service struct {
|
||||
// Config
|
||||
WatcherConfig Config
|
||||
WatcherConfig *Config
|
||||
// Interface for streaming data from super node
|
||||
SuperNodeStreamer shared.SuperNodeStreamer
|
||||
// Interface for db operations
|
||||
@@ -60,16 +60,20 @@ type Service struct {
|
||||
}
|
||||
|
||||
// NewWatcher returns a new Service which satisfies the Watcher interface
|
||||
func NewWatcher(c Config, quitChan chan bool) (Watcher, error) {
|
||||
func NewWatcher(c *Config, quitChan chan bool) (Watcher, error) {
|
||||
repo, err := NewRepository(c.SubscriptionConfig.ChainType(), c.DB, c.TriggerFunctions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
streamer, err := NewSuperNodeStreamer(c.Source, c.Client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Service{
|
||||
WatcherConfig: c,
|
||||
SuperNodeStreamer: NewSuperNodeStreamer(c.Client),
|
||||
SuperNodeStreamer: streamer,
|
||||
Repository: repo,
|
||||
WASMIniter: wasm.NewWASMInstantiator(c.DB, c.WASMInstances),
|
||||
WASMIniter: wasm.NewWASMInstantiator(c.DB, c.WASMFunctions),
|
||||
PayloadChan: make(chan super_node.SubscriptionPayload, super_node.PayloadChanBufferSize),
|
||||
QuitChan: quitChan,
|
||||
}, nil
|
||||
@@ -85,7 +89,7 @@ func (s *Service) Init() error {
|
||||
return s.Repository.LoadTriggers()
|
||||
}
|
||||
|
||||
// Watch is the top level loop for watching super node
|
||||
// Watch is the top level loop for watching
|
||||
func (s *Service) Watch(wg *sync.WaitGroup) error {
|
||||
rlpConfig, err := rlp.EncodeToBytes(s.WatcherConfig.SubscriptionConfig)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// VulcanizeDB
|
||||
// Copyright © 2019 Vulcanize
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
|
||||
// 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/>.
|
||||
|
||||
package shared
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SourceType enum for specifying source type for raw chain data
|
||||
type SourceType int
|
||||
|
||||
const (
|
||||
Unknown SourceType = iota
|
||||
VulcanizeDB
|
||||
Ethereum
|
||||
Bitcoin
|
||||
)
|
||||
|
||||
func (c SourceType) String() string {
|
||||
switch c {
|
||||
case Ethereum:
|
||||
return "Ethereum"
|
||||
case Bitcoin:
|
||||
return "Bitcoin"
|
||||
case VulcanizeDB:
|
||||
return "VulcanizeDB"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func NewSourceType(name string) (SourceType, error) {
|
||||
switch strings.ToLower(name) {
|
||||
case "ethereum", "eth":
|
||||
return Ethereum, nil
|
||||
case "bitcoin", "btc", "xbt":
|
||||
return Bitcoin, nil
|
||||
case "vulcanizedb", "vdb":
|
||||
return VulcanizeDB, nil
|
||||
default:
|
||||
return Unknown, errors.New("invalid name for data source")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user