diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index a7fab7af9..55eb55b1a 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -66,6 +66,8 @@ Friendly reminder: We have a [bug bounty program](https://hackerone.com/tendermi Some core types have been kept in the `mempool` package such as `TxCache` and it's implementations, the `Mempool` interface itself and `TxInfo`. (@alexanderbez) - [crypto/sr25519] \#6526 Do not re-execute the Ed25519-style key derivation step when doing signing and verification. The derivation is now done once and only once. This breaks `sr25519.GenPrivKeyFromSecret` output compatibility. (@Yawning) + - [types] \#6627 Move `NodeKey` to types to make the type public. + - [config] \#6627 Extend `config` to contain methods `LoadNodeKeyID` and `LoadorGenNodeKeyID` - Blockchain Protocol diff --git a/cmd/tendermint/commands/gen_node_key.go b/cmd/tendermint/commands/gen_node_key.go index 472a82fa3..f796f4b7f 100644 --- a/cmd/tendermint/commands/gen_node_key.go +++ b/cmd/tendermint/commands/gen_node_key.go @@ -5,8 +5,8 @@ import ( "github.com/spf13/cobra" - "github.com/tendermint/tendermint/internal/p2p" tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/types" ) // GenNodeKeyCmd allows the generation of a node key. It prints JSON-encoded @@ -20,7 +20,7 @@ var GenNodeKeyCmd = &cobra.Command{ } func genNodeKey(cmd *cobra.Command, args []string) error { - nodeKey := p2p.GenNodeKey() + nodeKey := types.GenNodeKey() bz, err := tmjson.Marshal(nodeKey) if err != nil { diff --git a/cmd/tendermint/commands/init.go b/cmd/tendermint/commands/init.go index 8499c9085..bc94f763b 100644 --- a/cmd/tendermint/commands/init.go +++ b/cmd/tendermint/commands/init.go @@ -8,7 +8,6 @@ import ( "github.com/spf13/cobra" cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/internal/p2p" tmos "github.com/tendermint/tendermint/libs/os" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" @@ -76,7 +75,7 @@ func initFilesWithConfig(config *cfg.Config) error { if tmos.FileExists(nodeKeyFile) { logger.Info("Found node key", "path", nodeKeyFile) } else { - if _, err := p2p.LoadOrGenNodeKey(nodeKeyFile); err != nil { + if _, err := types.LoadOrGenNodeKey(nodeKeyFile); err != nil { return err } logger.Info("Generated node key", "path", nodeKeyFile) diff --git a/cmd/tendermint/commands/show_node_id.go b/cmd/tendermint/commands/show_node_id.go index 192de74ee..7a5814c3b 100644 --- a/cmd/tendermint/commands/show_node_id.go +++ b/cmd/tendermint/commands/show_node_id.go @@ -4,8 +4,6 @@ import ( "fmt" "github.com/spf13/cobra" - - "github.com/tendermint/tendermint/internal/p2p" ) // ShowNodeIDCmd dumps node's ID to the standard output. @@ -18,11 +16,11 @@ var ShowNodeIDCmd = &cobra.Command{ } func showNodeID(cmd *cobra.Command, args []string) error { - nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile()) + nodeKeyID, err := config.LoadNodeKeyID() if err != nil { return err } - fmt.Println(nodeKey.ID) + fmt.Println(nodeKeyID) return nil } diff --git a/cmd/tendermint/commands/testnet.go b/cmd/tendermint/commands/testnet.go index 337ffdaad..a7307b38f 100644 --- a/cmd/tendermint/commands/testnet.go +++ b/cmd/tendermint/commands/testnet.go @@ -12,7 +12,6 @@ import ( "github.com/spf13/viper" cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/internal/p2p" "github.com/tendermint/tendermint/libs/bytes" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" @@ -274,11 +273,11 @@ func persistentPeersArray(config *cfg.Config) ([]string, error) { for i := 0; i < nValidators+nNonValidators; i++ { nodeDir := filepath.Join(outputDir, fmt.Sprintf("%s%d", nodeDirPrefix, i)) config.SetRoot(nodeDir) - nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile()) + nodeKey, err := config.LoadNodeKeyID() if err != nil { return []string{}, err } - peers[i] = nodeKey.ID.AddressString(fmt.Sprintf("%s:%d", hostnameOrIP(i), p2pPort)) + peers[i] = nodeKey.AddressString(fmt.Sprintf("%s:%d", hostnameOrIP(i), p2pPort)) } return peers, nil } diff --git a/config/config.go b/config/config.go index 7c38aabc6..de1217134 100644 --- a/config/config.go +++ b/config/config.go @@ -4,12 +4,16 @@ import ( "encoding/hex" "errors" "fmt" + "io/ioutil" "net/http" "os" "path/filepath" "time" + tmjson "github.com/tendermint/tendermint/libs/json" "github.com/tendermint/tendermint/libs/log" + tmos "github.com/tendermint/tendermint/libs/os" + "github.com/tendermint/tendermint/types" ) const ( @@ -282,6 +286,41 @@ func (cfg BaseConfig) NodeKeyFile() string { return rootify(cfg.NodeKey, cfg.RootDir) } +// LoadNodeKey loads NodeKey located in filePath. +func (cfg BaseConfig) LoadNodeKeyID() (types.NodeID, error) { + jsonBytes, err := ioutil.ReadFile(cfg.NodeKeyFile()) + if err != nil { + return "", err + } + nodeKey := types.NodeKey{} + err = tmjson.Unmarshal(jsonBytes, &nodeKey) + if err != nil { + return "", err + } + nodeKey.ID = types.NodeIDFromPubKey(nodeKey.PubKey()) + return nodeKey.ID, nil +} + +// LoadOrGenNodeKey attempts to load the NodeKey from the given filePath. If +// the file does not exist, it generates and saves a new NodeKey. +func (cfg BaseConfig) LoadOrGenNodeKeyID() (types.NodeID, error) { + if tmos.FileExists(cfg.NodeKeyFile()) { + nodeKey, err := cfg.LoadNodeKeyID() + if err != nil { + return "", err + } + return nodeKey, nil + } + + nodeKey := types.GenNodeKey() + + if err := nodeKey.SaveAs(cfg.NodeKeyFile()); err != nil { + return "", err + } + + return nodeKey.ID, nil +} + // DBDir returns the full path to the database directory func (cfg BaseConfig) DBDir() string { return rootify(cfg.DBPath, cfg.RootDir) diff --git a/internal/p2p/mock/peer.go b/internal/p2p/mock/peer.go index b47e58662..cede51768 100644 --- a/internal/p2p/mock/peer.go +++ b/internal/p2p/mock/peer.go @@ -27,7 +27,7 @@ func NewPeer(ip net.IP) *Peer { } else { netAddr = types.NewNetAddressIPPort(ip, 26656) } - nodeKey := p2p.GenNodeKey() + nodeKey := types.GenNodeKey() netAddr.ID = nodeKey.ID mp := &Peer{ ip: ip, diff --git a/internal/p2p/peer_set_test.go b/internal/p2p/peer_set_test.go index 96e6ebd5a..3e2397d2d 100644 --- a/internal/p2p/peer_set_test.go +++ b/internal/p2p/peer_set_test.go @@ -38,7 +38,7 @@ func newMockPeer(ip net.IP) *mockPeer { if ip == nil { ip = net.IP{127, 0, 0, 1} } - nodeKey := GenNodeKey() + nodeKey := types.GenNodeKey() return &mockPeer{ ip: ip, id: nodeKey.ID, diff --git a/internal/p2p/switch.go b/internal/p2p/switch.go index fa8338834..e35a307d6 100644 --- a/internal/p2p/switch.go +++ b/internal/p2p/switch.go @@ -104,7 +104,7 @@ type Switch struct { dialing *cmap.CMap reconnecting *cmap.CMap nodeInfo types.NodeInfo // our node info - nodeKey NodeKey // our node privkey + nodeKey types.NodeKey // our node privkey addrBook AddrBook // peers addresses with whom we'll maintain constant connection persistentPeersAddrs []*NetAddress @@ -254,7 +254,7 @@ func (sw *Switch) NodeInfo() types.NodeInfo { // SetNodeKey sets the switch's private key for authenticated encryption. // NOTE: Not goroutine safe. -func (sw *Switch) SetNodeKey(nodeKey NodeKey) { +func (sw *Switch) SetNodeKey(nodeKey types.NodeKey) { sw.nodeKey = nodeKey } diff --git a/internal/p2p/test_util.go b/internal/p2p/test_util.go index 18b8c8d70..b2851646d 100644 --- a/internal/p2p/test_util.go +++ b/internal/p2p/test_util.go @@ -170,7 +170,7 @@ func MakeSwitch( opts ...SwitchOption, ) *Switch { - nodeKey := GenNodeKey() + nodeKey := types.GenNodeKey() nodeInfo := testNodeInfo(nodeKey.ID, fmt.Sprintf("node%d", i)) addr, err := types.NewNetAddressString( nodeKey.ID.AddressString(nodeInfo.ListenAddr), diff --git a/node/node.go b/node/node.go index 662f60a07..5bf13f8e4 100644 --- a/node/node.go +++ b/node/node.go @@ -59,7 +59,7 @@ type nodeImpl struct { router *p2p.Router addrBook pex.AddrBook // known peers nodeInfo types.NodeInfo - nodeKey p2p.NodeKey // our node privkey + nodeKey types.NodeKey // our node privkey isListening bool // services @@ -89,7 +89,7 @@ type nodeImpl struct { // PrivValidator, ClientCreator, GenesisDoc, and DBProvider. // It implements NodeProvider. func newDefaultNode(config *cfg.Config, logger log.Logger) (service.Service, error) { - nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) + nodeKey, err := types.LoadOrGenNodeKey(config.NodeKeyFile()) if err != nil { return nil, fmt.Errorf("failed to load or gen node key %s: %w", config.NodeKeyFile(), err) } @@ -126,7 +126,7 @@ func newDefaultNode(config *cfg.Config, logger log.Logger) (service.Service, err // makeNode returns a new, ready to go, Tendermint Node. func makeNode(config *cfg.Config, privValidator types.PrivValidator, - nodeKey p2p.NodeKey, + nodeKey types.NodeKey, clientCreator proxy.ClientCreator, genesisDocProvider genesisDocProvider, dbProvider cfg.DBProvider, @@ -458,7 +458,7 @@ func makeNode(config *cfg.Config, // makeSeedNode returns a new seed node, containing only p2p, pex reactor func makeSeedNode(config *cfg.Config, dbProvider cfg.DBProvider, - nodeKey p2p.NodeKey, + nodeKey types.NodeKey, genesisDocProvider genesisDocProvider, logger log.Logger, ) (service.Service, error) { diff --git a/node/node_test.go b/node/node_test.go index 135902716..d619d22d9 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -24,7 +24,6 @@ import ( "github.com/tendermint/tendermint/internal/evidence" "github.com/tendermint/tendermint/internal/mempool" mempoolv0 "github.com/tendermint/tendermint/internal/mempool/v0" - "github.com/tendermint/tendermint/internal/p2p" "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" @@ -486,7 +485,7 @@ func TestNodeNewSeedNode(t *testing.T) { config.Mode = cfg.ModeSeed defer os.RemoveAll(config.RootDir) - nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) + nodeKey, err := types.LoadOrGenNodeKey(config.NodeKeyFile()) require.NoError(t, err) ns, err := makeSeedNode(config, diff --git a/node/public.go b/node/public.go index e64306044..99a8226d0 100644 --- a/node/public.go +++ b/node/public.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/internal/p2p" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/service" "github.com/tendermint/tendermint/privval" @@ -32,7 +31,7 @@ func New(conf *config.Config, cf proxy.ClientCreator, gen *types.GenesisDoc, ) (service.Service, error) { - nodeKey, err := p2p.LoadOrGenNodeKey(conf.NodeKeyFile()) + nodeKey, err := types.LoadOrGenNodeKey(conf.NodeKeyFile()) if err != nil { return nil, fmt.Errorf("failed to load or gen node key %s: %w", conf.NodeKeyFile(), err) } diff --git a/node/setup.go b/node/setup.go index ac48353e3..a3d88267e 100644 --- a/node/setup.go +++ b/node/setup.go @@ -566,7 +566,7 @@ func createSwitch( evidenceReactor *p2p.ReactorShim, proxyApp proxy.AppConns, nodeInfo types.NodeInfo, - nodeKey p2p.NodeKey, + nodeKey types.NodeKey, p2pLogger log.Logger, ) *p2p.Switch { @@ -644,7 +644,7 @@ func createSwitch( } func createAddrBookAndSetOnSwitch(config *cfg.Config, sw *p2p.Switch, - p2pLogger log.Logger, nodeKey p2p.NodeKey) (pex.AddrBook, error) { + p2pLogger log.Logger, nodeKey types.NodeKey) (pex.AddrBook, error) { addrBook := pex.NewAddrBook(config.P2P.AddrBookFile(), config.P2P.AddrBookStrict) addrBook.SetLogger(p2pLogger.With("book", config.P2P.AddrBookFile())) @@ -709,7 +709,7 @@ func createPEXReactorV2( func makeNodeInfo( config *cfg.Config, - nodeKey p2p.NodeKey, + nodeKey types.NodeKey, eventSinks []indexer.EventSink, genDoc *types.GenesisDoc, state sm.State, @@ -778,7 +778,7 @@ func makeNodeInfo( func makeSeedNodeInfo( config *cfg.Config, - nodeKey p2p.NodeKey, + nodeKey types.NodeKey, genDoc *types.GenesisDoc, state sm.State, ) (types.NodeInfo, error) { diff --git a/test/e2e/runner/setup.go b/test/e2e/runner/setup.go index 1baa1f503..c2b61617e 100644 --- a/test/e2e/runner/setup.go +++ b/test/e2e/runner/setup.go @@ -20,7 +20,6 @@ import ( "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/internal/p2p" "github.com/tendermint/tendermint/privval" e2e "github.com/tendermint/tendermint/test/e2e/pkg" "github.com/tendermint/tendermint/types" @@ -106,7 +105,7 @@ func Setup(testnet *e2e.Testnet) error { return err } - err = (&p2p.NodeKey{PrivKey: node.NodeKey}).SaveAs(filepath.Join(nodeDir, "config", "node_key.json")) + err = (&types.NodeKey{PrivKey: node.NodeKey}).SaveAs(filepath.Join(nodeDir, "config", "node_key.json")) if err != nil { return err } diff --git a/internal/p2p/key.go b/types/node_key.go similarity index 91% rename from internal/p2p/key.go rename to types/node_key.go index 8249d24bb..b8277649a 100644 --- a/internal/p2p/key.go +++ b/types/node_key.go @@ -1,4 +1,4 @@ -package p2p +package types import ( "io/ioutil" @@ -7,7 +7,6 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" tmjson "github.com/tendermint/tendermint/libs/json" tmos "github.com/tendermint/tendermint/libs/os" - "github.com/tendermint/tendermint/types" ) //------------------------------------------------------------------------------ @@ -18,7 +17,7 @@ import ( // It contains the nodes private key for authentication. type NodeKey struct { // Canonical ID - hex-encoded pubkey's address (IDByteLength bytes) - ID types.NodeID `json:"id"` + ID NodeID `json:"id"` // Private key PrivKey crypto.PrivKey `json:"priv_key"` } @@ -65,7 +64,7 @@ func LoadOrGenNodeKey(filePath string) (NodeKey, error) { func GenNodeKey() NodeKey { privKey := ed25519.GenPrivKey() return NodeKey{ - ID: types.NodeIDFromPubKey(privKey.PubKey()), + ID: NodeIDFromPubKey(privKey.PubKey()), PrivKey: privKey, } } @@ -81,6 +80,6 @@ func LoadNodeKey(filePath string) (NodeKey, error) { if err != nil { return NodeKey{}, err } - nodeKey.ID = types.NodeIDFromPubKey(nodeKey.PubKey()) + nodeKey.ID = NodeIDFromPubKey(nodeKey.PubKey()) return nodeKey, nil } diff --git a/internal/p2p/key_test.go b/types/node_key_test.go similarity index 71% rename from internal/p2p/key_test.go rename to types/node_key_test.go index 5189f95cf..7c0b945c3 100644 --- a/internal/p2p/key_test.go +++ b/types/node_key_test.go @@ -1,4 +1,4 @@ -package p2p_test +package types_test import ( "os" @@ -7,17 +7,17 @@ import ( "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/internal/p2p" tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/types" ) func TestLoadOrGenNodeKey(t *testing.T) { filePath := filepath.Join(os.TempDir(), tmrand.Str(12)+"_peer_id.json") - nodeKey, err := p2p.LoadOrGenNodeKey(filePath) + nodeKey, err := types.LoadOrGenNodeKey(filePath) require.Nil(t, err) - nodeKey2, err := p2p.LoadOrGenNodeKey(filePath) + nodeKey2, err := types.LoadOrGenNodeKey(filePath) require.Nil(t, err) require.Equal(t, nodeKey, nodeKey2) } @@ -25,13 +25,13 @@ func TestLoadOrGenNodeKey(t *testing.T) { func TestLoadNodeKey(t *testing.T) { filePath := filepath.Join(os.TempDir(), tmrand.Str(12)+"_peer_id.json") - _, err := p2p.LoadNodeKey(filePath) + _, err := types.LoadNodeKey(filePath) require.True(t, os.IsNotExist(err)) - _, err = p2p.LoadOrGenNodeKey(filePath) + _, err = types.LoadOrGenNodeKey(filePath) require.NoError(t, err) - nodeKey, err := p2p.LoadNodeKey(filePath) + nodeKey, err := types.LoadNodeKey(filePath) require.NoError(t, err) require.NotNil(t, nodeKey) } @@ -40,7 +40,7 @@ func TestNodeKeySaveAs(t *testing.T) { filePath := filepath.Join(os.TempDir(), tmrand.Str(12)+"_peer_id.json") require.NoFileExists(t, filePath) - nodeKey := p2p.GenNodeKey() + nodeKey := types.GenNodeKey() require.NoError(t, nodeKey.SaveAs(filePath)) require.FileExists(t, filePath) }