-
Notifications
You must be signed in to change notification settings - Fork 473
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: allow reading PeerId from keychain (#1552)
libp2p has a secure keychain where all items are stored in the datastore in an encrypted format, including the PeerId of the current node. If no PeerId is passed into the factory function, a new PeerId is created for the current node. Instead, if the factory function is passed a DataStore, it should try to read the PeerId from the DataStore and only create a new PeerId if reading the `self` key fails.
- Loading branch information
1 parent
b6fde93
commit 0831cd9
Showing
2 changed files
with
170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* eslint-env mocha */ | ||
|
||
import { expect } from 'aegir/chai' | ||
import { webSockets } from '@libp2p/websockets' | ||
import { plaintext } from '../../src/insecure/index.js' | ||
import { createLibp2p, Libp2p } from '../../src/index.js' | ||
import { MemoryDatastore } from 'datastore-core' | ||
|
||
describe('peer-id', () => { | ||
let libp2p: Libp2p | ||
|
||
afterEach(async () => { | ||
if (libp2p != null) { | ||
await libp2p.stop() | ||
} | ||
}) | ||
|
||
it('should create a PeerId if none is passed', async () => { | ||
libp2p = await createLibp2p({ | ||
transports: [ | ||
webSockets() | ||
], | ||
connectionEncryption: [ | ||
plaintext() | ||
] | ||
}) | ||
|
||
expect(libp2p.peerId).to.be.ok() | ||
}) | ||
|
||
it('should retrieve the PeerId from the datastore', async () => { | ||
const datastore = new MemoryDatastore() | ||
|
||
libp2p = await createLibp2p({ | ||
datastore, | ||
transports: [ | ||
webSockets() | ||
], | ||
connectionEncryption: [ | ||
plaintext() | ||
] | ||
}) | ||
|
||
// this PeerId was created by default | ||
const peerId = libp2p.peerId | ||
|
||
await libp2p.stop() | ||
|
||
// create a new node from the same datastore | ||
libp2p = await createLibp2p({ | ||
datastore, | ||
transports: [ | ||
webSockets() | ||
], | ||
connectionEncryption: [ | ||
plaintext() | ||
] | ||
}) | ||
|
||
// the new node should have read the PeerId from the datastore | ||
// instead of creating a new one | ||
expect(libp2p.peerId.toString()).to.equal(peerId.toString()) | ||
}) | ||
|
||
it('should retrieve the PeerId from the datastore with a keychain password', async () => { | ||
const datastore = new MemoryDatastore() | ||
const keychain = { | ||
pass: 'very-long-password-must-be-over-twenty-characters-long', | ||
dek: { | ||
salt: 'CpjNIxMqAZ+aJg+ezLfuzG4a' | ||
} | ||
} | ||
|
||
libp2p = await createLibp2p({ | ||
datastore, | ||
keychain, | ||
transports: [ | ||
webSockets() | ||
], | ||
connectionEncryption: [ | ||
plaintext() | ||
] | ||
}) | ||
|
||
// this PeerId was created by default | ||
const peerId = libp2p.peerId | ||
|
||
await libp2p.stop() | ||
|
||
// create a new node from the same datastore | ||
libp2p = await createLibp2p({ | ||
datastore, | ||
keychain, | ||
transports: [ | ||
webSockets() | ||
], | ||
connectionEncryption: [ | ||
plaintext() | ||
] | ||
}) | ||
|
||
// the new node should have read the PeerId from the datastore | ||
// instead of creating a new one | ||
expect(libp2p.peerId.toString()).to.equal(peerId.toString()) | ||
}) | ||
|
||
it('should fail to start if retrieving the PeerId from the datastore fails', async () => { | ||
const datastore = new MemoryDatastore() | ||
const keychain = { | ||
pass: 'very-long-password-must-be-over-twenty-characters-long', | ||
dek: { | ||
salt: 'CpjNIxMqAZ+aJg+ezLfuzG4a' | ||
} | ||
} | ||
|
||
libp2p = await createLibp2p({ | ||
datastore, | ||
keychain, | ||
transports: [ | ||
webSockets() | ||
], | ||
connectionEncryption: [ | ||
plaintext() | ||
] | ||
}) | ||
await libp2p.stop() | ||
|
||
// creating a new node from the same datastore but with the wrong keychain config should fail | ||
await expect(createLibp2p({ | ||
datastore, | ||
keychain: { | ||
pass: 'different-very-long-password-must-be-over-twenty-characters-long', | ||
dek: { | ||
salt: 'different-CpjNIxMqAZ+aJg+ezLfuzG4a' | ||
} | ||
}, | ||
transports: [ | ||
webSockets() | ||
], | ||
connectionEncryption: [ | ||
plaintext() | ||
] | ||
})).to.eventually.rejectedWith('Invalid PEM formatted message') | ||
}) | ||
}) |