Skip to content

Commit

Permalink
feat: decrypt keystores imported through API in thread pool (#5624)
Browse files Browse the repository at this point in the history
* Decrypt keystores imported through API in thread pool

* Remove inner try-catch
  • Loading branch information
nflaig authored Jun 12, 2023
1 parent f245849 commit 09ecf99
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 20 deletions.
7 changes: 6 additions & 1 deletion packages/cli/src/cmds/validator/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,12 @@ export async function validatorHandler(args: IValidatorCliArgs & GlobalArgs): Pr
);
}

const keymanagerApi = new KeymanagerApi(validator, persistedKeysBackend, proposerConfigWriteDisabled);
const keymanagerApi = new KeymanagerApi(
validator,
persistedKeysBackend,
abortController.signal,
proposerConfigWriteDisabled
);
const keymanagerServer = new KeymanagerRestApiServer(
{
address: args["keymanager.address"],
Expand Down
50 changes: 31 additions & 19 deletions packages/cli/src/cmds/validator/keymanager/impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {Interchange, SignerType, Validator} from "@lodestar/validator";
import {ServerApi} from "@lodestar/api";
import {getPubkeyHexFromKeystore, isValidatePubkeyHex, isValidHttpUrl} from "../../../util/format.js";
import {parseFeeRecipient} from "../../../util/index.js";
import {DecryptKeystoresThreadPool} from "./decryptKeystores/index.js";
import {IPersistedKeysBackend} from "./interface.js";

type Api = ServerApi<KeyManagerClientApi>;
Expand All @@ -25,6 +26,7 @@ export class KeymanagerApi implements Api {
constructor(
private readonly validator: Validator,
private readonly persistedKeysBackend: IPersistedKeysBackend,
private readonly signal: AbortSignal,
private readonly proposerConfigWriteDisabled?: boolean
) {}

Expand Down Expand Up @@ -124,6 +126,7 @@ export class KeymanagerApi implements Api {
}

const statuses: {status: ImportStatus; message?: string}[] = [];
const decryptKeystores = new DecryptKeystoresThreadPool(keystoresStr.length, this.signal);

for (let i = 0; i < keystoresStr.length; i++) {
try {
Expand All @@ -142,30 +145,39 @@ export class KeymanagerApi implements Api {
continue;
}

// Attempt to decrypt before writing to disk
const secretKey = bls.SecretKey.fromBytes(await keystore.decrypt(password));

// Persist the key to disk for restarts, before adding to in-memory store
// If the keystore exist and has a lock it will throw
this.persistedKeysBackend.writeKeystore({
keystoreStr,
password,
// Lock immediately since it's gonna be used
lockBeforeWrite: true,
// Always write, even if it's already persisted for consistency.
// The in-memory validatorStore is the ground truth to decide duplicates
persistIfDuplicate: true,
});

// Add to in-memory store to start validating immediately
this.validator.validatorStore.addSigner({type: SignerType.Local, secretKey});

statuses[i] = {status: ImportStatus.imported};
decryptKeystores.queue(
{keystoreStr, password},
(secretKeyBytes: Uint8Array) => {
const secretKey = bls.SecretKey.fromBytes(secretKeyBytes);

// Persist the key to disk for restarts, before adding to in-memory store
// If the keystore exist and has a lock it will throw
this.persistedKeysBackend.writeKeystore({
keystoreStr,
password,
// Lock immediately since it's gonna be used
lockBeforeWrite: true,
// Always write, even if it's already persisted for consistency.
// The in-memory validatorStore is the ground truth to decide duplicates
persistIfDuplicate: true,
});

// Add to in-memory store to start validating immediately
this.validator.validatorStore.addSigner({type: SignerType.Local, secretKey});

statuses[i] = {status: ImportStatus.imported};
},
(e: Error) => {
statuses[i] = {status: ImportStatus.error, message: e.message};
}
);
} catch (e) {
statuses[i] = {status: ImportStatus.error, message: (e as Error).message};
}
}

await decryptKeystores.completed();

return {data: statuses};
}

Expand Down

0 comments on commit 09ecf99

Please sign in to comment.