Search in sources :

Example 1 with DeleteKeyResult

use of tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult in project teku by ConsenSys.

the class ActiveKeyManagerTest method deleteValidator_shouldStopAndDeleteValidator.

@Test
void deleteValidator_shouldStopAndDeleteValidator() {
    final Validator activeValidator = mock(Validator.class);
    when(activeValidator.getPublicKey()).thenReturn(publicKey);
    when(activeValidator.isReadOnly()).thenReturn(false);
    when(activeValidator.getSigner()).thenReturn(signer);
    when(exporter.addPublicKeyToExport(eq(publicKey), any())).thenReturn(Optional.empty());
    when(validatorLoader.deleteLocalMutableValidator(publicKey)).thenReturn(DeleteKeyResult.success());
    final DeleteKeyResult result = keyManager.deleteValidator(activeValidator, exporter);
    verify(signer).delete();
    verify(validatorLoader).deleteLocalMutableValidator(publicKey);
    assertThat(result.getStatus()).isEqualTo(DeletionStatus.DELETED);
    assertThat(result.getMessage()).isEmpty();
    verify(channel, never()).onValidatorsAdded();
}
Also used : DeleteKeyResult(tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult) ExternalValidator(tech.pegasys.teku.validator.client.restapi.apis.schema.ExternalValidator) Test(org.junit.jupiter.api.Test)

Example 2 with DeleteKeyResult

use of tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult in project teku by ConsenSys.

the class ActiveKeyManager method deleteValidators.

/**
 * Delete a collection of validators
 *
 * <p>The response must be symmetric, the list of validators coming in dictates the response
 * order.
 *
 * <p>An individual deletion failure MUST NOT cancel the operation, but rather cause an error for
 * that specific key Validator keys that are reported as deletionStatus.deleted MUST NOT be active
 * once the result is returned.
 *
 * <p>Each failure should result in a failure message for that specific key Slashing protection
 * data MUST be returned if we have the information
 *
 * <p>- NOT_FOUND should only be returned if the key was not there, and we didn't have slashing
 * protection information
 *
 * <p>- NOT_ACTIVE indicates the key wasn't active, but we had slashing data
 *
 * <p>- DELETED indicates the key was found, and we have stopped using it and removed it.
 *
 * <p>- ERROR indicates we couldn't stop using the key (read-only might be a reason)
 *
 * <p>If an exception is thrown, it will cause a 500 error on the API, so that is an undesirable
 * outcome.
 *
 * @param validators list of validator public keys that should be removed
 * @return The result of each deletion, and slashing protection data
 */
@Override
public synchronized DeleteKeysResponse deleteValidators(final List<BLSPublicKey> validators, final Path slashingProtectionPath) {
    final List<DeleteKeyResult> deletionResults = new ArrayList<>();
    final SlashingProtectionIncrementalExporter exporter = new SlashingProtectionIncrementalExporter(slashingProtectionPath);
    for (final BLSPublicKey publicKey : validators) {
        Optional<Validator> maybeValidator = validatorLoader.getOwnedValidators().getValidator(publicKey);
        // read-only check in a non-destructive manner
        if (maybeValidator.isPresent() && maybeValidator.get().isReadOnly()) {
            deletionResults.add(DeleteKeyResult.error("Cannot remove read-only validator"));
            continue;
        }
        // delete validator from owned validators list
        maybeValidator = validatorLoader.getOwnedValidators().removeValidator(publicKey);
        if (maybeValidator.isPresent()) {
            deletionResults.add(deleteValidator(maybeValidator.get(), exporter));
        } else {
            deletionResults.add(attemptToGetSlashingDataForInactiveValidator(publicKey, exporter));
        }
    }
    String exportedData;
    try {
        exportedData = exporter.finalise();
    } catch (JsonProcessingException e) {
        LOG.error("Failed to serialize slashing export data", e);
        exportedData = EXPORT_FAILED;
    }
    return new DeleteKeysResponse(deletionResults, exportedData);
}
Also used : SlashingProtectionIncrementalExporter(tech.pegasys.teku.data.SlashingProtectionIncrementalExporter) ArrayList(java.util.ArrayList) DeleteKeyResult(tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult) DeleteKeysResponse(tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeysResponse) BLSPublicKey(tech.pegasys.teku.bls.BLSPublicKey) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) ExternalValidator(tech.pegasys.teku.validator.client.restapi.apis.schema.ExternalValidator)

Example 3 with DeleteKeyResult

use of tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult in project teku by ConsenSys.

the class ActiveKeyManager method deleteValidator.

@VisibleForTesting
DeleteKeyResult deleteValidator(final Validator activeValidator, final SlashingProtectionIncrementalExporter exporter) {
    final Signer signer = activeValidator.getSigner();
    signer.delete();
    LOG.info("Removed validator: {}", activeValidator.getPublicKey().toString());
    final DeleteKeyResult deleteKeyResult = validatorLoader.deleteLocalMutableValidator(activeValidator.getPublicKey());
    if (deleteKeyResult.getStatus() == DeletionStatus.DELETED) {
        Optional<String> error = exporter.addPublicKeyToExport(activeValidator.getPublicKey(), LOG::debug);
        if (error.isPresent()) {
            return DeleteKeyResult.error(error.get());
        }
    }
    return deleteKeyResult;
}
Also used : Signer(tech.pegasys.teku.core.signatures.Signer) DeleteKeyResult(tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 4 with DeleteKeyResult

use of tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult in project teku by ConsenSys.

the class ActiveKeyManager method deleteExternalValidators.

@Override
public DeleteRemoteKeysResponse deleteExternalValidators(List<BLSPublicKey> validators) {
    final List<DeleteKeyResult> deletionResults = new ArrayList<>();
    for (final BLSPublicKey publicKey : validators) {
        Optional<Validator> maybeValidator = validatorLoader.getOwnedValidators().getValidator(publicKey);
        // read-only check in a non-destructive manner
        if (maybeValidator.isPresent() && maybeValidator.get().isReadOnly()) {
            deletionResults.add(DeleteKeyResult.error("Cannot remove read-only validator"));
            continue;
        }
        // delete validator from owned validators list
        maybeValidator = validatorLoader.getOwnedValidators().getValidator(publicKey);
        if (maybeValidator.isPresent()) {
            DeleteKeyResult result = deleteExternalValidator(maybeValidator.get());
            deletionResults.add(result);
            if (result.equals(DeleteKeyResult.success())) {
                validatorLoader.getOwnedValidators().removeValidator(publicKey);
            }
        } else {
            deletionResults.add(DeleteKeyResult.notFound());
        }
    }
    return new DeleteRemoteKeysResponse(deletionResults);
}
Also used : DeleteRemoteKeysResponse(tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteRemoteKeysResponse) ArrayList(java.util.ArrayList) DeleteKeyResult(tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult) BLSPublicKey(tech.pegasys.teku.bls.BLSPublicKey) ExternalValidator(tech.pegasys.teku.validator.client.restapi.apis.schema.ExternalValidator)

Example 5 with DeleteKeyResult

use of tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult in project teku by ConsenSys.

the class LocalValidatorSource method deleteValidator.

@Override
public DeleteKeyResult deleteValidator(final BLSPublicKey publicKey) {
    if (!canUpdateValidators()) {
        return DeleteKeyResult.error("Cannot delete validator from read-only local validator source.");
    }
    final ActiveLocalValidatorSource source = localValidatorSourceMap.remove(publicKey);
    if (source == null) {
        return DeleteKeyResult.error("Could not find " + publicKey.toBytesCompressed().toShortHexString() + " to delete");
    }
    final DeleteKeyResult result = source.delete();
    if (result.getStatus() == DeletionStatus.DELETED) {
        keystoreLocker.unlockKeystore(getKeystorePath(publicKey));
    }
    return result;
}
Also used : DeleteKeyResult(tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult)

Aggregations

DeleteKeyResult (tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeyResult)14 Test (org.junit.jupiter.api.Test)10 BLSPublicKey (tech.pegasys.teku.bls.BLSPublicKey)4 ExternalValidator (tech.pegasys.teku.validator.client.restapi.apis.schema.ExternalValidator)4 Path (java.nio.file.Path)2 ArrayList (java.util.ArrayList)2 SimpleDataDirLayout (tech.pegasys.techu.service.serviceutils.layout.SimpleDataDirLayout)2 SlashingProtectionIncrementalExporter (tech.pegasys.teku.data.SlashingProtectionIncrementalExporter)2 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 URL (java.net.URL)1 KeyStoreData (tech.pegasys.signers.bls.keystore.model.KeyStoreData)1 Signer (tech.pegasys.teku.core.signatures.Signer)1 ValidatorConfig (tech.pegasys.teku.validator.api.ValidatorConfig)1 DeleteKeysResponse (tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteKeysResponse)1 DeleteRemoteKeysResponse (tech.pegasys.teku.validator.client.restapi.apis.schema.DeleteRemoteKeysResponse)1