use of tech.pegasys.web3signer.slashingprotection.interchange.IncrementalExporter in project web3signer by ConsenSys.
the class DeleteKeystoresProcessor method process.
public DeleteKeystoresResponse process(final DeleteKeystoresRequestBody requestBody) {
final List<DeleteKeystoreResult> results = new ArrayList<>();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (final IncrementalExporter incrementalExporter = createIncrementalExporter(outputStream)) {
// normalize incoming keys to delete
final List<String> pubkeysToDelete = requestBody.getPubkeys().stream().map(IdentifierUtils::normaliseIdentifier).collect(Collectors.toList());
for (String pubkey : pubkeysToDelete) {
results.add(processKeyToDelete(pubkey, incrementalExporter));
}
try {
incrementalExporter.finalise();
} catch (IOException ioException) {
LOG.error("Failed to export slashing data", ioException);
setAllResultsToError(results, ioException);
}
} catch (Exception e) {
// Any unhandled error we want to bubble up so that we return an internal error response
throw new RuntimeException("Error deleting keystores", e);
}
final String slashingProtectionExport = outputStream.toString(StandardCharsets.UTF_8);
return new DeleteKeystoresResponse(results, slashingProtectionExport);
}
use of tech.pegasys.web3signer.slashingprotection.interchange.IncrementalExporter in project web3signer by ConsenSys.
the class InterchangeExportIntegrationTestBase method exportingIncrementallyOnlyExportsSpecifiedValidators.
@Test
void exportingIncrementallyOnlyExportsSpecifiedValidators() throws Exception {
final Bytes32 gvr = Bytes32.fromHexString(GENESIS_VALIDATORS_ROOT);
final int VALIDATOR_COUNT = 6;
final int TOTAL_BLOCKS_SIGNED = 6;
final int TOTAL_ATTESTATIONS_SIGNED = 8;
for (int i = 0; i < VALIDATOR_COUNT; i++) {
final int validatorId = i + 1;
final Bytes validatorPublicKey = Bytes.of(validatorId);
slashingProtectionContext.getRegisteredValidators().registerValidators(List.of(validatorPublicKey));
for (int b = 0; b < TOTAL_BLOCKS_SIGNED; b++) {
insertBlockAt(UInt64.valueOf(b), validatorId);
}
for (int a = 0; a < TOTAL_ATTESTATIONS_SIGNED; a++) {
insertAttestationAt(UInt64.valueOf(a), UInt64.valueOf(a), validatorId);
}
jdbi.useTransaction(h -> {
lowWatermarkDao.updateSlotWatermarkFor(h, validatorId, UInt64.ZERO);
lowWatermarkDao.updateEpochWatermarksFor(h, validatorId, UInt64.ZERO, UInt64.ZERO);
});
}
// incrementally export only the even the public keys
final OutputStream exportOutput = new ByteArrayOutputStream();
final IncrementalExporter incrementalExporter = slashingProtectionContext.getSlashingProtection().createIncrementalExporter(exportOutput);
for (int i = 0; i < VALIDATOR_COUNT; i += 2) {
incrementalExporter.export(String.format("0x0%x", i + 1));
}
incrementalExporter.finalise();
incrementalExporter.close();
final InterchangeV5Format outputObject = mapper.readValue(exportOutput.toString(), InterchangeV5Format.class);
assertThat(outputObject.getMetadata().getFormatVersion()).isEqualTo("5");
assertThat(outputObject.getMetadata().getGenesisValidatorsRoot()).isEqualTo(gvr);
final List<SignedArtifacts> signedArtifacts = outputObject.getSignedArtifacts();
assertThat(signedArtifacts).hasSize(VALIDATOR_COUNT / 2);
for (int i = 0; i < VALIDATOR_COUNT; i += 2) {
final int validatorId = i + 1;
final SignedArtifacts signedArtifact = signedArtifacts.get(i / 2);
assertThat(signedArtifact.getPublicKey()).isEqualTo(String.format("0x0%x", validatorId));
assertThat(signedArtifact.getSignedBlocks()).hasSize(TOTAL_BLOCKS_SIGNED);
for (int b = 0; b < TOTAL_BLOCKS_SIGNED; b++) {
final tech.pegasys.web3signer.slashingprotection.interchange.model.SignedBlock block = signedArtifact.getSignedBlocks().get(b);
assertThat(block.getSigningRoot()).isEqualTo(Bytes.of(100));
assertThat(block.getSlot()).isEqualTo(UInt64.valueOf(b));
}
assertThat(signedArtifact.getSignedAttestations()).hasSize(TOTAL_ATTESTATIONS_SIGNED);
for (int a = 0; a < TOTAL_ATTESTATIONS_SIGNED; a++) {
final tech.pegasys.web3signer.slashingprotection.interchange.model.SignedAttestation attestation = signedArtifact.getSignedAttestations().get(a);
assertThat(attestation.getSigningRoot()).isEqualTo(Bytes.of(100));
assertThat(attestation.getSourceEpoch()).isEqualTo(UInt64.valueOf(a));
assertThat(attestation.getTargetEpoch()).isEqualTo(UInt64.valueOf(a));
}
}
}
use of tech.pegasys.web3signer.slashingprotection.interchange.IncrementalExporter in project web3signer by ConsenSys.
the class DeleteKeystoresProcessor method exportSlashingProtectionData.
private String exportSlashingProtectionData(final List<DeleteKeystoreResult> results, final List<String> keysToExport) {
// export slashing protection data for 'deleted' and 'not_active' keys
String slashingProtectionExport = null;
if (slashingProtection.isPresent()) {
try {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final SlashingProtection slashingProtection = this.slashingProtection.get();
try (IncrementalExporter incrementalExporter = slashingProtection.createIncrementalExporter(outputStream)) {
keysToExport.forEach(incrementalExporter::export);
incrementalExporter.finalise();
}
slashingProtectionExport = outputStream.toString(StandardCharsets.UTF_8);
} catch (Exception e) {
LOG.error("Failed to export slashing data", e);
// if export fails - set all results to error
final List<DeleteKeystoreResult> errorResults = results.stream().map(result -> new DeleteKeystoreResult(DeleteKeystoreStatus.ERROR, "Error exporting slashing data: " + e.getMessage())).collect(Collectors.toList());
results.clear();
results.addAll(errorResults);
}
}
return slashingProtectionExport;
}
Aggregations