You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.3 KiB

  1. package p2p
  2. import (
  3. "encoding/hex"
  4. "io/ioutil"
  5. "github.com/tendermint/tendermint/crypto"
  6. "github.com/tendermint/tendermint/crypto/ed25519"
  7. tmjson "github.com/tendermint/tendermint/libs/json"
  8. tmos "github.com/tendermint/tendermint/libs/os"
  9. )
  10. // ID is a hex-encoded crypto.Address
  11. type ID string
  12. // IDByteLength is the length of a crypto.Address. Currently only 20.
  13. // TODO: support other length addresses ?
  14. const IDByteLength = crypto.AddressSize
  15. //------------------------------------------------------------------------------
  16. // Persistent peer ID
  17. // TODO: encrypt on disk
  18. // NodeKey is the persistent peer key.
  19. // It contains the nodes private key for authentication.
  20. type NodeKey struct {
  21. PrivKey crypto.PrivKey `json:"priv_key"` // our priv key
  22. }
  23. // ID returns the peer's canonical ID - the hash of its public key.
  24. func (nodeKey *NodeKey) ID() ID {
  25. return PubKeyToID(nodeKey.PubKey())
  26. }
  27. // PubKey returns the peer's PubKey
  28. func (nodeKey *NodeKey) PubKey() crypto.PubKey {
  29. return nodeKey.PrivKey.PubKey()
  30. }
  31. // PubKeyToID returns the ID corresponding to the given PubKey.
  32. // It's the hex-encoding of the pubKey.Address().
  33. func PubKeyToID(pubKey crypto.PubKey) ID {
  34. return ID(hex.EncodeToString(pubKey.Address()))
  35. }
  36. // LoadOrGenNodeKey attempts to load the NodeKey from the given filePath. If
  37. // the file does not exist, it generates and saves a new NodeKey.
  38. func LoadOrGenNodeKey(filePath string) (*NodeKey, error) {
  39. if tmos.FileExists(filePath) {
  40. nodeKey, err := LoadNodeKey(filePath)
  41. if err != nil {
  42. return nil, err
  43. }
  44. return nodeKey, nil
  45. }
  46. privKey := ed25519.GenPrivKey()
  47. nodeKey := &NodeKey{
  48. PrivKey: privKey,
  49. }
  50. if err := nodeKey.SaveAs(filePath); err != nil {
  51. return nil, err
  52. }
  53. return nodeKey, nil
  54. }
  55. // LoadNodeKey loads NodeKey located in filePath.
  56. func LoadNodeKey(filePath string) (*NodeKey, error) {
  57. jsonBytes, err := ioutil.ReadFile(filePath)
  58. if err != nil {
  59. return nil, err
  60. }
  61. nodeKey := new(NodeKey)
  62. err = tmjson.Unmarshal(jsonBytes, nodeKey)
  63. if err != nil {
  64. return nil, err
  65. }
  66. return nodeKey, nil
  67. }
  68. // SaveAs persists the NodeKey to filePath.
  69. func (nodeKey *NodeKey) SaveAs(filePath string) error {
  70. jsonBytes, err := tmjson.Marshal(nodeKey)
  71. if err != nil {
  72. return err
  73. }
  74. err = ioutil.WriteFile(filePath, jsonBytes, 0600)
  75. if err != nil {
  76. return err
  77. }
  78. return nil
  79. }