Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate ipld plugin and ipfs #152

Merged
merged 24 commits into from
Feb 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions cmd/tendermint/commands/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ package commands

import (
"fmt"
"os"
"path/filepath"
"sync"

ipfscfg "github.com/ipfs/go-ipfs-config"
"github.com/ipfs/go-ipfs/plugin/loader"
"github.com/ipfs/go-ipfs/repo/fsrepo"
"github.com/ipfs/interface-go-ipfs-core/options"
"github.com/spf13/cobra"

cfg "github.com/lazyledger/lazyledger-core/config"
Expand Down Expand Up @@ -99,5 +106,90 @@ func initFilesWithConfig(config *cfg.Config) error {
logger.Info("Generated genesis file", "path", genFile)
}

if err := InitIpfs(config); err != nil {
return err
}

return nil
}

// InitIpfs takes a few config flags from the tendermint config.IPFS
// and applies them to the freshly created IPFS repo.
// The IPFS config will stored under config.IPFS.ConfigRootPath.
// TODO(ismail) move into separate file, and consider making IPFS initialization
// independent from the `tendermint init` subcommand.
// TODO(ismail): add counter part in ResetAllCmd
func InitIpfs(config *cfg.Config) error {
repoRoot := config.IPFSRepoRoot()
if fsrepo.IsInitialized(repoRoot) {
logger.Info("IPFS was already initialized", "ipfs-path", repoRoot)
return nil
}
var conf *ipfscfg.Config

identity, err := ipfscfg.CreateIdentity(os.Stdout, []options.KeyGenerateOption{
options.Key.Type(options.Ed25519Key),
})
if err != nil {
return err
}

logger.Info("initializing IPFS node", "ipfs-path", repoRoot)

if err := tmos.EnsureDir(repoRoot, 0700); err != nil {
return err
}

conf, err = ipfscfg.InitWithIdentity(identity)
if err != nil {
return err
}

applyFromTmConfig(conf, config.IPFS)
if err := setupPlugins(repoRoot); err != nil {
return err
}

if err := fsrepo.Init(repoRoot, conf); err != nil {
return err
}
return nil
}

// Inject replies on several global vars internally.
// For instance fsrepo.AddDatastoreConfigHandler will error
// if called multiple times with the same datastore.
// But for CI and integration tests, we want to setup the plugins
// for each repo but only inject once s.t. we can init multiple
// repos from the same runtime.
// TODO(ismail): find a more elegant way to achieve the same.
var injectPluginsOnce sync.Once

func setupPlugins(path string) error {
// Load plugins. This will skip the repo if not available.
plugins, err := loader.NewPluginLoader(filepath.Join(path, "plugins"))
if err != nil {
return fmt.Errorf("error loading plugins: %s", err)
}

if err := plugins.Initialize(); err != nil {
return fmt.Errorf("error initializing plugins: %s", err)
}

injectPluginsOnce.Do(func() {
err = plugins.Inject()
})
if err != nil {
return fmt.Errorf("error injecting plugins once: %w", err)
}

return nil
}

func applyFromTmConfig(ipfsConf *ipfscfg.Config, tmConf *cfg.IPFSConfig) {
ipfsConf.Addresses.API = ipfscfg.Strings{tmConf.API}
ipfsConf.Addresses.Gateway = ipfscfg.Strings{tmConf.Gateway}
ipfsConf.Addresses.Swarm = tmConf.Swarm
ipfsConf.Addresses.Announce = tmConf.Announce
ipfsConf.Addresses.NoAnnounce = tmConf.NoAnnounce
}
8 changes: 8 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ type Config struct {
Consensus *ConsensusConfig `mapstructure:"consensus"`
TxIndex *TxIndexConfig `mapstructure:"tx-index"`
Instrumentation *InstrumentationConfig `mapstructure:"instrumentation"`
// Options for IPFS service
IPFS *IPFSConfig `mapstructure:"ipfs"`
}

// DefaultConfig returns a default configuration for a Tendermint node
Expand All @@ -79,6 +81,7 @@ func DefaultConfig() *Config {
Consensus: DefaultConsensusConfig(),
TxIndex: DefaultTxIndexConfig(),
Instrumentation: DefaultInstrumentationConfig(),
IPFS: DefaultIPFSConfig(),
}
}

Expand All @@ -94,6 +97,7 @@ func TestConfig() *Config {
Consensus: TestConsensusConfig(),
TxIndex: TestTxIndexConfig(),
Instrumentation: TestInstrumentationConfig(),
IPFS: TetsIpfsConfig(),
}
}

Expand Down Expand Up @@ -1026,6 +1030,10 @@ func DefaultInstrumentationConfig() *InstrumentationConfig {
}
}

func TetsIpfsConfig() *IPFSConfig {
return DefaultIPFSConfig()
}

// TestInstrumentationConfig returns a default configuration for metrics
// reporting.
func TestInstrumentationConfig() *InstrumentationConfig {
Expand Down
34 changes: 34 additions & 0 deletions config/ipfs_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package config

// IPFSConfig defines a subset of the IPFS config that will be passed to the IPFS init and IPFS node (as a service)
// spun up by the tendermint node.
// It is mostly concerned about port configuration (Addresses).
type IPFSConfig struct {
// is where the generated IPFS config and files will be stored.
// The default is ~/.tendermint/ipfs.
ConfigRootPath string
// TODO: can we avoid copying the fields from ipfs' config.Addresses here?
// TODO: also, these are only used on init. Maybe ConfigRootPath is sufficient?
API string // address for the local API (RPC)
Gateway string // address to listen on for IPFS HTTP object gateway
// swarm related options:
Swarm []string // addresses for the swarm to listen on
Announce []string // swarm addresses to announce to the network
NoAnnounce []string // swarm addresses not to announce to the network
}
liamsi marked this conversation as resolved.
Show resolved Hide resolved

// DefaultIPFSConfig returns a default config different from the default IPFS config.
// This avoids conflicts with existing installations when running LazyLedger-core node
// locally for testing purposes.
func DefaultIPFSConfig() *IPFSConfig {
return &IPFSConfig{
ConfigRootPath: "ipfs/",
API: "/ip4/127.0.0.1/tcp/5002",
Gateway: "/ip4/127.0.0.1/tcp/5002",
Swarm: []string{"/ip4/0.0.0.0/tcp/4002", "/ip6/::/tcp/4002"},
}
}

func (cfg *Config) IPFSRepoRoot() string {
return rootify(cfg.IPFS.ConfigRootPath, cfg.RootDir)
}
23 changes: 23 additions & 0 deletions config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,29 @@ max-open-connections = {{ .Instrumentation.MaxOpenConnections }}

# Instrumentation namespace
namespace = "{{ .Instrumentation.Namespace }}"

#######################################################
### IPFS Configuration Options ###
#######################################################
[ipfs]

# IPFS repo root.
repo-root = "{{ .IPFS.ConfigRootPath}}"

## Below options will be passed to ipfs when initializing an ipfs repo.
## They will be written into the repo-root/config on init.
## To modify the generated config, edit repo-root/config accordingly.

# Address for the local API (RPC).
api = "{{ .IPFS.API }}"
# Address to listen on for IPFS HTTP object gateway.
gateway = "{{ .IPFS.Gateway }}"
# Addresses for the swarm to listen on
swarm = [{{ range .IPFS.Swarm }}{{ printf "%q, " . }}{{end}}]
# Swarm addresses to announce to the network
announce = [{{ range .IPFS.Announce }}{{ printf "%q, " . }}{{end}}]
# Swarm addresses not to announce to the network
no-announce = [{{ range .IPFS.NoAnnounce }}{{ printf "%q, " . }}{{end}}]
`

/****** these are for test settings ***********/
Expand Down
2 changes: 1 addition & 1 deletion consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ func (cs *State) handleMsg(mi msgInfo) {
// We probably don't want to stop the peer here. The vote does not
// necessarily comes from a malicious peer but can be just broadcasted by
// a typical peer.
// https://github.com/lazyledger/lazyledger-core/issues/1281
// https://github.com/tendermint/tendermint/issues/1281
liamsi marked this conversation as resolved.
Show resolved Hide resolved
// }

// NOTE: the vote is broadcast to peers by the reactor listening
Expand Down
13 changes: 10 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ require (
github.com/go-logfmt/logfmt v0.5.0
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.4.3
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect
github.com/gorilla/websocket v1.4.2
github.com/gtank/merlin v0.1.1
github.com/hdevalence/ed25519consensus v0.0.0-20201207055737-7fde80a9d5ff
github.com/ipfs/go-ipfs v0.7.0
github.com/ipfs/go-ipfs-config v0.12.0
github.com/ipfs/interface-go-ipfs-core v0.4.0
github.com/lazyledger/lazyledger-core/p2p/ipld/plugin v0.0.0-20210219190522-0eccfb24e2aa
github.com/lazyledger/nmt v0.2.0
github.com/lazyledger/rsmt2d v0.0.0-20201215203123-e5ec7910ddd4
github.com/libp2p/go-buffer-pool v0.0.2
Expand All @@ -28,16 +31,20 @@ require (
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0
github.com/rs/cors v1.7.0
github.com/sasha-s/go-deadlock v0.2.0
github.com/smartystreets/assertions v1.0.1 // indirect
github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa
github.com/spf13/cobra v1.1.1
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.7.0
github.com/tendermint/tm-db v0.6.4
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 // indirect
golang.org/x/net v0.0.0-20201021035429-f5854403a974
google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4 // indirect
google.golang.org/grpc v1.35.0
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
)

replace (
github.com/ipfs/go-ipfs => github.com/lazyledger/go-ipfs v0.7.0-lazypatch
github.com/lazyledger/lazyledger-core/p2p/ipld/plugin => ./p2p/ipld/plugin
liamsi marked this conversation as resolved.
Show resolved Hide resolved
)
Loading