diff --git a/api-tests/block.http b/api-tests/block.http new file mode 100644 index 000000000..ff72c2d64 --- /dev/null +++ b/api-tests/block.http @@ -0,0 +1,33 @@ +### +### Get block by block number +GET {{base_url}}/api/v1/blocks/2925862 + +> {% + client.test("Get block by block number", function() { + client.assert(response.status === 200, "Response status is not 200"); + client.assert(response.body.height === 2925862, "Block number is wrong" + response.body.height) + client.assert(response.body.hash === "1b57a2298737589695f7ec88da9e5b1af8f9f4479e7bd03367c10e165d5cc4bc", "Block hash is wrong" + response.body.hash) + client.assert(response.body.op_cert_counter === "6", "Expected 6 as string") + client.assert(response.body.next_block === "7d50f0dbc258ffeee329fbd61e10ccdc83d65068cb9d99e2a663c07b3a7f15fd", "Mismatch next block") + client.assert(response.body.confirmations > 1, "Confirmations should be greater than 1") + client.assert(response.body.output === "19511865", "Output mismatch") + client.assert(response.body.fees === "488135", "Fees mismatch") + }); +%} + + +### Get block by block hash +GET {{base_url}}/api/v1/blocks/1b57a2298737589695f7ec88da9e5b1af8f9f4479e7bd03367c10e165d5cc4bc + +> {% + client.test("Get block by block number", function() { + client.assert(response.status === 200, "Response status is not 200"); + client.assert(response.body.height === 2925862, "Block number is wrong" + response.body.height) + client.assert(response.body.hash === "1b57a2298737589695f7ec88da9e5b1af8f9f4479e7bd03367c10e165d5cc4bc", "Block hash is wrong" + response.body.hash) + client.assert(response.body.op_cert_counter === "6", "Expected 6 as string") + client.assert(response.body.next_block === "7d50f0dbc258ffeee329fbd61e10ccdc83d65068cb9d99e2a663c07b3a7f15fd", "Mismatch next block") + client.assert(response.body.confirmations > 1, "Confirmations should be greater than 1") + client.assert(response.body.output === "19511865", "Output mismatch") + client.assert(response.body.fees === "488135", "Fees mismatch") + }); +%} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d455484a2..d7fe9d3d1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [libraries] -yaci = "com.bloxbean.cardano:yaci:0.3.3" +yaci = "com.bloxbean.cardano:yaci:0.3.4" cardano-client-lib = "com.bloxbean.cardano:cardano-client-lib:0.6.2" cardano-client-backend = "com.bloxbean.cardano:cardano-client-backend:0.6.2" cardano-client-backend-ogmios = "com.bloxbean.cardano:cardano-client-backend-ogmios:0.6.2" diff --git a/stores-api/blocks-api/src/main/java/com/bloxbean/cardano/yaci/store/api/blocks/controller/BlockController.java b/stores-api/blocks-api/src/main/java/com/bloxbean/cardano/yaci/store/api/blocks/controller/BlockController.java index 7970c2baa..1e3866ca8 100644 --- a/stores-api/blocks-api/src/main/java/com/bloxbean/cardano/yaci/store/api/blocks/controller/BlockController.java +++ b/stores-api/blocks-api/src/main/java/com/bloxbean/cardano/yaci/store/api/blocks/controller/BlockController.java @@ -32,15 +32,31 @@ public class BlockController { @GetMapping("{numberOrHash}") @Operation(summary = "Block Information by Number or Hash", description = "Get block information by number or hash.") public ResponseEntity getBlockByNumber(@PathVariable String numberOrHash) { + BlockDto blockDto; if (NumberUtils.isParsable(numberOrHash)) { - return blockService.getBlockByNumber(Long.parseLong(numberOrHash)) - .map(block -> ResponseEntity.ok(dtoMapper.toBlockDto(block))) - .orElse(ResponseEntity.notFound().build()); + blockDto = blockService.getBlockByNumber(Long.parseLong(numberOrHash)) + .map(block -> dtoMapper.toBlockDto(block)).orElse(null); } else { - return blockService.getBlockByHash(numberOrHash) - .map(block -> ResponseEntity.ok(dtoMapper.toBlockDto(block))) - .orElse(ResponseEntity.notFound().build()); + blockDto = blockService.getBlockByHash(numberOrHash) + .map(block -> dtoMapper.toBlockDto(block)).orElse(null); } + + if (blockDto == null) { + return ResponseEntity.notFound().build(); + } + + var confirmation = blockService.getLatestBlock() + .map(latestBlock -> latestBlock.getNumber() - blockDto.getNumber()) + .orElse(0L); + + var nextBlockHash = blockService.getBlockByNumber(blockDto.getNumber() + 1) + .map(block -> block.getHash()) + .orElse(null); + + blockDto.setNextBlock(nextBlockHash); + blockDto.setConfirmations(confirmation); + + return ResponseEntity.ok(blockDto); } @GetMapping diff --git a/stores-api/blocks-api/src/main/java/com/bloxbean/cardano/yaci/store/api/blocks/dto/BlockDto.java b/stores-api/blocks-api/src/main/java/com/bloxbean/cardano/yaci/store/api/blocks/dto/BlockDto.java index 63cecc2d7..a82f466fb 100644 --- a/stores-api/blocks-api/src/main/java/com/bloxbean/cardano/yaci/store/api/blocks/dto/BlockDto.java +++ b/stores-api/blocks-api/src/main/java/com/bloxbean/cardano/yaci/store/api/blocks/dto/BlockDto.java @@ -4,14 +4,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.*; import java.math.BigInteger; @Getter +@Setter @Builder @NoArgsConstructor @AllArgsConstructor @@ -29,16 +29,19 @@ public class BlockDto { private String slotLeader; private long size; private int txCount; + @JsonSerialize(using = ToStringSerializer.class) private BigInteger output; + @JsonSerialize(using = ToStringSerializer.class) private BigInteger fees; private String blockVrf; private String opCert; + @JsonSerialize(using = ToStringSerializer.class) private Integer opCertCounter; private Integer opCertKesPeriod; private String opCertSigma; private String previousBlock; - // private String nextBlock; //TODO - // private long confirmations; //TODO + private String nextBlock; + private long confirmations; private String issuerVkey; private Vrf nonceVrf;