Skip to content

Commit

Permalink
Merge pull request #124 from ChainSafe/cayman/fast-create-peer-id
Browse files Browse the repository at this point in the history
Optimize createPeerIdFromKeypair
  • Loading branch information
wemeetagain committed Jul 26, 2021
2 parents e676179 + ab2bd93 commit f534f5a
Show file tree
Hide file tree
Showing 6 changed files with 874 additions and 340 deletions.
17 changes: 17 additions & 0 deletions bench/keypair/index.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {itBench, setBenchOpts} from "@dapplion/benchmark";
import {createPeerIdFromKeypair, generateKeypair, KeypairType} from "../../src/keypair";

describe("createPeerIdFromKeypair", function() {
setBenchOpts({runs: 4000});

const keypairWithPrivateKey = generateKeypair(KeypairType.secp256k1);
const keypairWithoutPrivateKey = generateKeypair(KeypairType.secp256k1);
delete (keypairWithoutPrivateKey as any)._privateKey;

itBench("createPeerIdFromKeypair - private key", () => {
return createPeerIdFromKeypair(keypairWithPrivateKey);
});
itBench("createPeerIdFromKeypair - no private key", () => {
return createPeerIdFromKeypair(keypairWithoutPrivateKey);
});
});
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,21 @@
},
"homepage": "https://github.com/ChainSafe/discv5#readme",
"devDependencies": {
"@dapplion/benchmark": "^0.1.6",
"@types/bn.js": "^4.11.5",
"@types/chai": "^4.2.0",
"@types/debug": "^4.1.5",
"@types/eslint": "^6.1.3",
"@types/ip6addr": "^0.2.0",
"@types/mocha": "^5.2.7",
"@types/mocha": "^8.0.3",
"@types/node": "^12.0.10",
"@typescript-eslint/eslint-plugin": "^2.7.0",
"@typescript-eslint/parser": "^2.7.0",
"chai": "^4.2.0",
"eslint": "^6.6.0",
"eslint-plugin-prettier": "^3.1.4",
"karma": "^4.3.0",
"mocha": "^6.2.0",
"mocha": "^8.3.0",
"nyc": "^14.1.1",
"prettier": "^2.0.5",
"ts-node": "^8.3.0",
Expand Down
19 changes: 11 additions & 8 deletions src/keypair/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { IKeypair, KeypairType } from "./types";
import { ERR_TYPE_NOT_IMPLEMENTED } from "./constants";
import { Secp256k1Keypair } from "./secp256k1";
import { toBuffer } from "../util";
import mh from "multihashes";

export * from "./types";
export * from "./secp256k1";
Expand All @@ -30,14 +31,16 @@ export function createKeypair(type: KeypairType, privateKey?: Buffer, publicKey?

export async function createPeerIdFromKeypair(keypair: IKeypair): Promise<PeerId> {
switch (keypair.type) {
case KeypairType.secp256k1:
try {
return await PeerId.createFromPrivKey(
new supportedKeys.secp256k1.Secp256k1PrivateKey(keypair.privateKey, keypair.publicKey).bytes
);
} catch (e) {
return await PeerId.createFromPubKey(new supportedKeys.secp256k1.Secp256k1PublicKey(keypair.publicKey).bytes);
}
case KeypairType.secp256k1: {
// manually create a peer id to avoid expensive ops
const privKey = keypair.hasPrivateKey()
? new supportedKeys.secp256k1.Secp256k1PrivateKey(keypair.privateKey, keypair.publicKey)
: // TODO: this is a workaround for https://github.com/libp2p/js-peer-id/pull/154, change once peer-id updated
((null as unknown) as undefined);
const pubKey = new supportedKeys.secp256k1.Secp256k1PublicKey(keypair.publicKey);
const id = mh.encode(pubKey.bytes, "identity");
return new PeerId(id, privKey, pubKey);
}
default:
throw new Error(ERR_TYPE_NOT_IMPLEMENTED);
}
Expand Down
4 changes: 4 additions & 0 deletions src/keypair/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface IKeypair {
sign(msg: Buffer): Buffer;
verify(msg: Buffer, sig: Buffer): boolean;
deriveSecret(keypair: IKeypair): Buffer;
hasPrivateKey(): boolean;
}

export interface IKeypairClass {
Expand Down Expand Up @@ -49,4 +50,7 @@ export abstract class AbstractKeypair {
publicKeyVerify(): boolean {
return true;
}
hasPrivateKey(): boolean {
return Boolean(this._privateKey);
}
}
27 changes: 27 additions & 0 deletions test/keypair/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { expect } from "chai";
import PeerId from "peer-id";
import { keys } from "libp2p-crypto";
import { createPeerIdFromKeypair, generateKeypair, KeypairType } from "../../src/keypair";
const { keysPBM, supportedKeys } = keys;

describe("createPeerIdFromKeypair", function() {
it("should properly create a PeerId from a secp256k1 keypair with private key", async function() {
const keypair = generateKeypair(KeypairType.secp256k1);
const privKey = new supportedKeys.secp256k1.Secp256k1PrivateKey(keypair.privateKey, keypair.publicKey);

const expectedPeerId = await PeerId.createFromPrivKey(privKey.bytes);
const actualPeerId = await createPeerIdFromKeypair(keypair);

expect(actualPeerId).to.be.deep.equal(expectedPeerId);
});
it("should properly create a PeerId from a secp256k1 keypair without private key", async function() {
const keypair = generateKeypair(KeypairType.secp256k1);
delete (keypair as any)._privateKey;
const pubKey = new supportedKeys.secp256k1.Secp256k1PublicKey(keypair.publicKey);

const expectedPeerId = await PeerId.createFromPubKey(pubKey.bytes);
const actualPeerId = await createPeerIdFromKeypair(keypair);

expect(actualPeerId).to.be.deep.equal(expectedPeerId);
});
});
Loading

0 comments on commit f534f5a

Please sign in to comment.