dione/node/node_dep_providers.go
2021-06-11 14:40:39 +03:00

182 lines
5.8 KiB
Go

package node
import (
"context"
"fmt"
"time"
"github.com/asaskevich/EventBus"
"github.com/Secured-Finance/dione/blockchain"
drand2 "github.com/Secured-Finance/dione/beacon/drand"
"github.com/libp2p/go-libp2p-core/protocol"
gorpc "github.com/libp2p/go-libp2p-gorpc"
"github.com/Secured-Finance/dione/blockchain/sync"
"github.com/Secured-Finance/dione/blockchain/pool"
"github.com/Secured-Finance/dione/beacon"
"github.com/Secured-Finance/dione/cache"
"github.com/Secured-Finance/dione/config"
"github.com/Secured-Finance/dione/consensus"
"github.com/Secured-Finance/dione/ethclient"
"github.com/Secured-Finance/dione/pubsub"
"github.com/Secured-Finance/dione/types"
"github.com/Secured-Finance/dione/wallet"
pex "github.com/Secured-Finance/go-libp2p-pex"
"github.com/ethereum/go-ethereum/common"
"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/discovery"
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/peer"
pubsub2 "github.com/libp2p/go-libp2p-pubsub"
"github.com/multiformats/go-multiaddr"
"golang.org/x/xerrors"
)
const (
DioneProtocolID = protocol.ID("/dione/1.0")
)
func provideCache(config *config.Config) cache.Cache {
var backend cache.Cache
switch config.CacheType {
case "in-memory":
backend = cache.NewInMemoryCache()
case "redis":
backend = cache.NewRedisCache(config)
default:
backend = cache.NewInMemoryCache()
}
return backend
}
func provideDisputeManager(ctx context.Context, ethClient *ethclient.EthereumClient, pcm *consensus.PBFTConsensusManager, cfg *config.Config) (*consensus.DisputeManager, error) {
return consensus.NewDisputeManager(ctx, ethClient, pcm, cfg.Ethereum.DisputeVoteWindow)
}
func provideMiner(peerID peer.ID, ethAddress common.Address, ethClient *ethclient.EthereumClient, privateKey crypto.PrivKey, mempool *pool.Mempool) *consensus.Miner {
return consensus.NewMiner(peerID, ethAddress, ethClient, privateKey, mempool)
}
func provideBeacon(ps *pubsub2.PubSub, pcm *consensus.PBFTConsensusManager) (beacon.BeaconNetworks, error) {
networks := beacon.BeaconNetworks{}
bc, err := drand2.NewDrandBeacon(ps, pcm)
if err != nil {
return nil, fmt.Errorf("failed to setup drand beacon: %w", err)
}
networks = append(networks, beacon.BeaconNetwork{Start: config.DrandChainGenesisTime, Beacon: bc})
// NOTE: currently we use only one network
return networks, nil
}
// FIXME: do we really need this?
func provideWallet(peerID peer.ID, privKey []byte) (*wallet.LocalWallet, error) {
// TODO make persistent keystore
kstore := wallet.NewMemKeyStore()
keyInfo := types.KeyInfo{
Type: types.KTEd25519,
PrivateKey: privKey,
}
kstore.Put(wallet.KNamePrefix+peerID.String(), keyInfo)
w, err := wallet.NewWallet(kstore)
if err != nil {
return nil, xerrors.Errorf("failed to setup wallet: %w", err)
}
return w, nil
}
func provideEthereumClient(config *config.Config) (*ethclient.EthereumClient, error) {
ethereum := ethclient.NewEthereumClient()
err := ethereum.Initialize(&config.Ethereum)
if err != nil {
return nil, xerrors.Errorf("failed to initialize ethereum client: %v", err)
}
return ethereum, nil
}
func providePubsubRouter(lhost host.Host, config *config.Config) *pubsub.PubSubRouter {
return pubsub.NewPubSubRouter(lhost, config.PubSub.ServiceTopicName, config.IsBootstrap)
}
func provideConsensusManager(bus EventBus.Bus, psb *pubsub.PubSubRouter, miner *consensus.Miner, bc *blockchain.BlockChain, ethClient *ethclient.EthereumClient, privateKey crypto.PrivKey, minApprovals int) *consensus.PBFTConsensusManager {
return consensus.NewPBFTConsensusManager(bus, psb, minApprovals, privateKey, ethClient, miner, bc)
}
func provideLibp2pHost(config *config.Config, privateKey crypto.PrivKey) (host.Host, error) {
listenMultiAddr, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d", config.ListenAddr, config.ListenPort))
if err != nil {
return nil, xerrors.Errorf("failed to parse multiaddress: %v", err)
}
host, err := libp2p.New(
context.TODO(),
libp2p.ListenAddrs(listenMultiAddr),
libp2p.Identity(privateKey),
)
if err != nil {
return nil, xerrors.Errorf("failed to setup libp2p host: %v", err)
}
return host, nil
}
func provideNetworkRPCHost(h host.Host) *gorpc.Server {
return gorpc.NewServer(h, DioneProtocolID)
}
func provideBootstrapAddrs(c *config.Config) ([]multiaddr.Multiaddr, error) {
if c.IsBootstrap {
return nil, nil
}
var bootstrapMaddrs []multiaddr.Multiaddr
for _, a := range c.BootstrapNodes {
maddr, err := multiaddr.NewMultiaddr(a)
if err != nil {
return nil, xerrors.Errorf("invalid multiaddress of bootstrap node: %v", err)
}
bootstrapMaddrs = append(bootstrapMaddrs, maddr)
}
return bootstrapMaddrs, nil
}
func providePeerDiscovery(baddrs []multiaddr.Multiaddr, h host.Host, pexDiscoveryUpdateTime time.Duration) (discovery.Discovery, error) {
pexDiscovery, err := pex.NewPEXDiscovery(h, baddrs, pexDiscoveryUpdateTime)
if err != nil {
return nil, xerrors.Errorf("failed to setup pex pexDiscovery: %v", err)
}
return pexDiscovery, nil
}
func provideBlockChain(config *config.Config) (*blockchain.BlockChain, error) {
return blockchain.NewBlockChain(config.Blockchain.DatabasePath)
}
func provideMemPool() (*pool.Mempool, error) {
return pool.NewMempool()
}
func provideSyncManager(bus EventBus.Bus, bp *blockchain.BlockChain, mp *pool.Mempool, r *gorpc.Client, bootstrap multiaddr.Multiaddr, psb *pubsub.PubSubRouter) (sync.SyncManager, error) {
addr, err := peer.AddrInfoFromP2pAddr(bootstrap)
if err != nil {
return nil, err
}
return sync.NewSyncManager(bus, bp, mp, r, addr.ID, psb), nil
}
func provideP2PRPCClient(h host.Host) *gorpc.Client {
return gorpc.NewClient(h, DioneProtocolID)
}
func provideNetworkService(bp *blockchain.BlockChain) *NetworkService {
return NewNetworkService(bp)
}