Added version query string param to /blocks/signature/{signature}/data API endpoint, to allow for optional V2 block serialization (with a single combined AT states hash).

Version can only be specified when querying unarchived blocks; archived blocks require V1 for now (and possibly V2 in the future).
This commit is contained in:
CalDescent 2022-07-04 19:57:54 +01:00
parent d7e7c1f48c
commit 6b91b0477d

View File

@ -114,7 +114,7 @@ public class BlocksResource {
@Path("/signature/{signature}/data") @Path("/signature/{signature}/data")
@Operation( @Operation(
summary = "Fetch serialized, base58 encoded block data using base58 signature", summary = "Fetch serialized, base58 encoded block data using base58 signature",
description = "Returns serialized data for the block that matches the given signature", description = "Returns serialized data for the block that matches the given signature, and an optional block serialization version",
responses = { responses = {
@ApiResponse( @ApiResponse(
description = "the block data", description = "the block data",
@ -125,7 +125,7 @@ public class BlocksResource {
@ApiErrors({ @ApiErrors({
ApiError.INVALID_SIGNATURE, ApiError.BLOCK_UNKNOWN, ApiError.INVALID_DATA, ApiError.REPOSITORY_ISSUE ApiError.INVALID_SIGNATURE, ApiError.BLOCK_UNKNOWN, ApiError.INVALID_DATA, ApiError.REPOSITORY_ISSUE
}) })
public String getSerializedBlockData(@PathParam("signature") String signature58) { public String getSerializedBlockData(@PathParam("signature") String signature58, @QueryParam("version") Integer version) {
// Decode signature // Decode signature
byte[] signature; byte[] signature;
try { try {
@ -136,19 +136,40 @@ public class BlocksResource {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
// Default to version 1
if (version == null) {
version = 1;
}
// Check the database first // Check the database first
BlockData blockData = repository.getBlockRepository().fromSignature(signature); BlockData blockData = repository.getBlockRepository().fromSignature(signature);
if (blockData != null) { if (blockData != null) {
Block block = new Block(repository, blockData); Block block = new Block(repository, blockData);
ByteArrayOutputStream bytes = new ByteArrayOutputStream(); ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bytes.write(Ints.toByteArray(block.getBlockData().getHeight())); bytes.write(Ints.toByteArray(block.getBlockData().getHeight()));
switch (version) {
case 1:
bytes.write(BlockTransformer.toBytes(block)); bytes.write(BlockTransformer.toBytes(block));
break;
case 2:
bytes.write(BlockTransformer.toBytesV2(block));
break;
default:
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
}
return Base58.encode(bytes.toByteArray()); return Base58.encode(bytes.toByteArray());
} }
// Not found, so try the block archive // Not found, so try the block archive
byte[] bytes = BlockArchiveReader.getInstance().fetchSerializedBlockBytesForSignature(signature, false, repository); byte[] bytes = BlockArchiveReader.getInstance().fetchSerializedBlockBytesForSignature(signature, false, repository);
if (bytes != null) { if (bytes != null) {
if (version != 1) {
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, "Archived blocks require version 1");
}
return Base58.encode(bytes); return Base58.encode(bytes);
} }