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

Testing CI for moving where the IPFS node is init #329

Closed
wants to merge 60 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
31c996a
include DAH in block ID proto files, add QoL methods, and fix all ./t…
evan-forbes May 3, 2021
1522ee8
Merge branch 'master' into evan/add-dah-to-block-id
evan-forbes May 4, 2021
052bdbe
linter and bug
evan-forbes May 4, 2021
f9b9629
fix all evidence package bugs
evan-forbes May 4, 2021
760d371
don't use nil dah when creating a new blockchain reactor
evan-forbes May 4, 2021
e49a6ed
fix TestValidateBlockHeader
evan-forbes May 4, 2021
8243b27
fix TestLoadBaseMeta
evan-forbes May 4, 2021
8dd6964
fix TestLoadBlockMeta
evan-forbes May 4, 2021
24153f7
fix TestBlockFetchAtHeight
evan-forbes May 4, 2021
61969de
fix TestSignProposal
evan-forbes May 4, 2021
563e94e
fix TestMock
evan-forbes May 5, 2021
235da5b
fix TestCreateProposalBlock
evan-forbes May 5, 2021
300e0fb
Fix TestBlockchainMessageVectors
evan-forbes May 5, 2021
98c9f13
use EmptyBlockID func and use block in vote
evan-forbes May 5, 2021
4dcd7a8
Fix TestBlockHash
evan-forbes May 5, 2021
e8e50fc
go mod tidy
evan-forbes May 5, 2021
672ce3b
Fix TestBlockMakePartSet
evan-forbes May 5, 2021
76bae0c
Fix more nil commit Tests
evan-forbes May 5, 2021
5956145
fix more nil commit tests
evan-forbes May 5, 2021
39b5c75
get rid of the BlockID method
evan-forbes May 5, 2021
330e9dd
Fix TestBeginBlockByzantineValidators
evan-forbes May 5, 2021
0d9509a
fill in more of the blockIDs
evan-forbes May 6, 2021
d4a3bf8
Fix TestLightBlockProtobuf
evan-forbes May 6, 2021
1256a42
fix TestLightBlockValidateBasic
evan-forbes May 6, 2021
edc26f4
fix TestEvidenceProto
evan-forbes May 6, 2021
f80f731
fix TestHeader_ValidateBasic
evan-forbes May 6, 2021
80f6d75
fix TestProposalString
evan-forbes May 6, 2021
7847b9d
fix TestProposalValidateBasic
evan-forbes May 6, 2021
d7aa886
fix TestHeaderHash
evan-forbes May 6, 2021
d0034ec
update MaxHeaderBytes to fix TestMaxHeaderBytes
evan-forbes May 6, 2021
48a8305
fix TestProposalProtoBuf
evan-forbes May 6, 2021
03a4329
fix TestCommitValidateBasic
evan-forbes May 6, 2021
24681e6
tons of test fixes
evan-forbes May 7, 2021
df5b458
cleanup
evan-forbes May 7, 2021
d11f9d4
more fixes
evan-forbes May 8, 2021
9d53b41
don't return a nil for a non nil data availability header
evan-forbes May 10, 2021
bc81eff
Merge branch 'master' into evan/add-dah-to-block-id
evan-forbes May 10, 2021
3e5f077
Merge branch 'master' into evan/add-dah-to-block-id
evan-forbes May 10, 2021
5918bc0
fix more bugs
evan-forbes May 11, 2021
9dbf03a
linter
evan-forbes May 11, 2021
d865cc7
linter
evan-forbes May 11, 2021
8acce6b
remove unreachable code
evan-forbes May 11, 2021
a127447
linter
evan-forbes May 11, 2021
5c39da7
increase timeouts for CI
evan-forbes May 11, 2021
a6c85fc
remove unused nolint directive
evan-forbes May 11, 2021
304537f
add more docs to comptueshares
evan-forbes May 11, 2021
717ffd0
revert linter changes
evan-forbes May 11, 2021
2a33518
increase consensus timeouts
evan-forbes May 11, 2021
4c4bad0
increase timeout for RetrieveBlockData
evan-forbes May 11, 2021
74795bf
remove uneccessary hash call
evan-forbes May 11, 2021
ee766c7
add TxFilter test back in
evan-forbes May 11, 2021
51d9e95
revert uneccessary changes
evan-forbes May 11, 2021
912a067
increase timeouts for problem tests
evan-forbes May 11, 2021
d5dbe9a
hardcode bytes for min dah
evan-forbes May 12, 2021
cc5fd2d
fix accidental linter error
evan-forbes May 12, 2021
10c3334
slight timing adjustment
evan-forbes May 12, 2021
818c823
init ipfs everytime we make a new node
evan-forbes May 12, 2021
3bc1510
revert commented out test
evan-forbes May 13, 2021
8301d52
use less than or equal too instead of requiring equal
evan-forbes May 13, 2021
6a47a55
Merge branch 'evan/add-dah-to-block-id' into evan/move-ipfs-init
evan-forbes May 13, 2021
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
123 changes: 104 additions & 19 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@ import (
"net"
"net/http"
_ "net/http/pprof" // nolint: gosec // securely exposed on separate, optional port
"os"
"path/filepath"
"strings"
"time"

ipfscfg "github.com/ipfs/go-ipfs-config"
ipfscore "github.com/ipfs/go-ipfs/core"
coreapi "github.com/ipfs/go-ipfs/core/coreapi"
"github.com/ipfs/go-ipfs/core/coreapi"
"github.com/ipfs/go-ipfs/core/node/libp2p"
"github.com/ipfs/go-ipfs/plugin/loader"
"github.com/ipfs/go-ipfs/repo/fsrepo"
"github.com/ipfs/interface-go-ipfs-core/options"
tmos "github.com/lazyledger/lazyledger-core/libs/os"
"github.com/lazyledger/lazyledger-core/p2p/ipld/plugin/nodes"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
Expand Down Expand Up @@ -651,6 +655,21 @@ func NewNode(config *cfg.Config,
logger log.Logger,
options ...Option) (*Node, error) {

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

ipfsNode, err := createIpfsNode(config, true, logger)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's constantly true, maybe change then createIpfsNode?

if err != nil {
return nil, fmt.Errorf("failed to create IPFS node: %w", err)
}

ipfsAPI, err := coreapi.NewCoreAPI(ipfsNode)
if err != nil {
return nil, fmt.Errorf("failed to create an instance of the IPFS core API: %w", err)
}
Comment on lines +663 to +671
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks right to me. But I'm wondering if we shouldn't just pass in a CoreAPIobject into NewNode instead. Then it would be easier to e.g. use other mechanisms to use IPFS. Initialization would need to happen outside of Node.

Would also like to hear what @Wondertan thinks about this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that idea better than the current implementation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree. Having dependency initialized outside of a component is also a good practice, which for our case would allow more flexibility to allow users to use custom IPFS nodes until we decide to fully absorb IPFS(not just embed) by using its modules directly. The latter may be possible in the future as an optimization vector.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@liamsi, @evan-forbes, but how do we then ensure that a custom IPFS node includes the needed plugin(s)? That is not clear for me now and may require some investigation. I think we can still do the proposed changed on a code level for now(pass CoreAPI to NewNode), but still not give a user ability to use a custom one, until we understand how we can ensure that, as doing that now would be a waste of time.

@liamsi, if you haven't started this yet as part of the cleanup, I can include this change in my PR with API exposure to HTTP.

Copy link
Member

@liamsi liamsi May 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@liamsi, if you haven't started this yet as part of the cleanup, I can include this change in my PR with API exposure to HTTP

I have started it only in the sense that I've extracted two methods to a file for initialization and for the creation of the node. The changes that are missing is to move the creation out of node.OnStart (and similarly out of the light client constructor - but that is not a concern on master yet).
Feel free to use the changes from the light client mvp or start from scratch. It's relatively minimal changes anyways.

Regarding the plugins:

https://github.com/lazyledger/lazyledger-core/blob/d4e52d231b6db37f15b2aff2ed631461cb32fe28/p2p/ipfs.go#L153-L159

That code also exist on master (only at a different place).

I'm not sure how to assert that the plugin was loaded if we use another approach.


blockStore, stateDB, err := initDBs(config, dbProvider)
if err != nil {
return nil, err
Expand Down Expand Up @@ -687,7 +706,7 @@ func NewNode(config *cfg.Config,
// If an address is provided, listen on the socket for a connection from an
// external signing process.
if config.PrivValidatorListenAddr != "" {
// FIXME: we should start services inside OnStart
// FIXME: we should start services inside rt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably a typo here

privValidator, err = createAndStartPrivValidatorSocketClient(config.PrivValidatorListenAddr, genDoc.ChainID, logger)
if err != nil {
return nil, fmt.Errorf("error with private validator socket client: %w", err)
Expand Down Expand Up @@ -768,6 +787,8 @@ func NewNode(config *cfg.Config,
privValidator, csMetrics, stateSync || fastSync, eventBus, consensusLogger,
)

consensusState.IpfsAPI = ipfsAPI

// Set up state sync reactor, and schedule a sync if requested.
// FIXME The way we do phased startups (e.g. replay -> fast sync -> consensus) is very messy,
// we should clean this whole thing up. See:
Expand Down Expand Up @@ -950,23 +971,6 @@ func (n *Node) OnStart() error {
return fmt.Errorf("failed to start state sync: %w", err)
}
}
if n.embedIpfsNode {
// It is essential that we create a fresh instance of ipfs node on
// each start as internally the node gets only stopped once per instance.
// At least in ipfs 0.7.0; see:
// https://github.com/lazyledger/go-ipfs/blob/dd295e45608560d2ada7d7c8a30f1eef3f4019bb/core/builder.go#L48-L57
n.ipfsNode, err = createIpfsNode(n.config, n.areIpfsPluginsAlreadyLoaded, n.Logger)
if err != nil {
return fmt.Errorf("failed to create IPFS node: %w", err)
}

ipfsAPI, err := coreapi.NewCoreAPI(n.ipfsNode)
if err != nil {
return fmt.Errorf("failed to create an instance of the IPFS core API: %w", err)
}

n.consensusState.IpfsAPI = ipfsAPI
}

return nil
}
Expand Down Expand Up @@ -1526,3 +1530,84 @@ func splitAndTrimEmpty(s, sep, cutset string) []string {
}
return nonEmptyStrings
}

// 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, logger log.Logger) 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, logger); 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
}
2 changes: 1 addition & 1 deletion node/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ func TestNodeStartStop(t *testing.T) {

// create & start node
n, err := DefaultNewNode(config, log.TestingLogger())
n.embedIpfsNode = false // TODO: or init ipfs upfront
require.NoError(t, err)
n.embedIpfsNode = false // TODO: or init ipfs upfronts
err = n.Start()
require.NoError(t, err)

Expand Down