Browse Source

Added API call GET /blocks/summaries

Returns summary info about a range of blocks.

(Not to be confused with network-related BlockSummaries)
pull/16/head
catbref 4 years ago
parent
commit
fb2c2b1d09
  1. 41
      src/main/java/org/qortal/api/model/BlockInfo.java
  2. 41
      src/main/java/org/qortal/api/resource/BlocksResource.java
  3. 6
      src/main/java/org/qortal/repository/BlockRepository.java
  4. 76
      src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java

41
src/main/java/org/qortal/api/model/BlockInfo.java

@ -0,0 +1,41 @@
package org.qortal.api.model;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@XmlAccessorType(XmlAccessType.FIELD)
public class BlockInfo {
private byte[] signature;
private int height;
private long timestamp;
private int transactionCount;
protected BlockInfo() {
/* For JAXB */
}
public BlockInfo(byte[] signature, int height, long timestamp, int transactionCount) {
this.signature = signature;
this.height = height;
this.timestamp = timestamp;
this.transactionCount = transactionCount;
}
public byte[] getSignature() {
return this.signature;
}
public int getHeight() {
return this.height;
}
public long getTimestamp() {
return this.timestamp;
}
public int getTransactionCount() {
return this.transactionCount;
}
}

41
src/main/java/org/qortal/api/resource/BlocksResource.java

@ -23,6 +23,7 @@ import javax.ws.rs.core.MediaType;
import org.qortal.api.ApiError;
import org.qortal.api.ApiErrors;
import org.qortal.api.ApiExceptionFactory;
import org.qortal.api.model.BlockInfo;
import org.qortal.api.model.BlockSignerSummary;
import org.qortal.crypto.Crypto;
import org.qortal.data.account.AccountData;
@ -480,4 +481,44 @@ public class BlocksResource {
}
}
@GET
@Path("/summaries")
@Operation(
summary = "Fetch only summary info about a range of blocks",
description = "Specify up to 2 out 3 of: start, end and count. If neither start nor end are specified, then end is assumed to be latest block. Where necessary, count is assumed to be 50.",
responses = {
@ApiResponse(
description = "blocks",
content = @Content(
array = @ArraySchema(
schema = @Schema(
implementation = BlockInfo.class
)
)
)
)
}
)
@ApiErrors({
ApiError.REPOSITORY_ISSUE
})
public List<BlockInfo> getBlockRange(
@QueryParam("start") Integer startHeight,
@QueryParam("end") Integer endHeight,
@Parameter(ref = "count") @QueryParam("count") Integer count) {
// Check up to 2 out of 3 params
if (startHeight != null && endHeight != null && count != null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
// Check values
if ((startHeight != null && startHeight < 1) || (endHeight != null && endHeight < 1) || (count != null && count < 1))
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
try (final Repository repository = RepositoryManager.getRepository()) {
return repository.getBlockRepository().getBlockInfos(startHeight, endHeight, count);
} catch (DataException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
}
}
}

6
src/main/java/org/qortal/repository/BlockRepository.java

@ -2,6 +2,7 @@ package org.qortal.repository;
import java.util.List;
import org.qortal.api.model.BlockInfo;
import org.qortal.api.model.BlockSignerSummary;
import org.qortal.data.block.BlockData;
import org.qortal.data.block.BlockSummaryData;
@ -128,6 +129,11 @@ public interface BlockRepository {
*/
public List<BlockSummaryData> getBlockSummaries(int firstBlockHeight, int lastBlockHeight) throws DataException;
/**
* Returns block infos for the passed height range, for API use.
*/
public List<BlockInfo> getBlockInfos(Integer startHeight, Integer endHeight, Integer count) throws DataException;
/**
* Trim online accounts signatures from blocks older than passed timestamp.
*

76
src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java

@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.qortal.api.model.BlockInfo;
import org.qortal.api.model.BlockSignerSummary;
import org.qortal.data.block.BlockData;
import org.qortal.data.block.BlockSummaryData;
@ -360,6 +361,81 @@ public class HSQLDBBlockRepository implements BlockRepository {
}
}
@Override
public List<BlockInfo> getBlockInfos(Integer startHeight, Integer endHeight, Integer count) throws DataException {
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT signature, height, minted_when, transaction_count ");
/*
* start end count result
* 10 40 null blocks 10 to 39 (excludes end block, ignore count)
*
* null null null blocks 1 to 50 (assume count=50, maybe start=1)
* 30 null null blocks 30 to 79 (assume count=50)
* 30 null 10 blocks 30 to 39
*
* null null 50 last 50 blocks? so if max(blocks.height) is 200, then blocks 151 to 200
* null 200 null blocks 150 to 199 (excludes end block, assume count=50)
* null 200 10 blocks 190 to 199 (excludes end block)
*/
if (startHeight != null && endHeight != null) {
sql.append("FROM Blocks WHERE height BETWEEN ");
sql.append(startHeight);
sql.append(" AND ");
sql.append(endHeight - 1);
} else if (endHeight != null || (startHeight == null && count != null)) {
// we are going to return blocks from the end of the chain
if (count == null)
count = 50;
if (endHeight == null) {
sql.append("FROM (SELECT height FROM Blocks ORDER BY height DESC LIMIT 1) AS MaxHeights (max_height) ");
sql.append("JOIN Blocks ON height BETWEEN (max_height - ");
sql.append(count);
sql.append(" + 1) AND max_height");
} else {
sql.append("FROM Blocks WHERE height BETWEEN ");
sql.append(endHeight - count);
sql.append(" AND ");
sql.append(endHeight - 1);
}
} else {
// we are going to return blocks from the start of the chain
if (startHeight == null)
startHeight = 1;
if (count == null)
count = 50;
sql.append("FROM Blocks WHERE height BETWEEN ");
sql.append(startHeight);
sql.append(" AND ");
sql.append(startHeight + count - 1);
}
List<BlockInfo> blockInfos = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
if (resultSet == null)
return blockInfos;
do {
byte[] signature = resultSet.getBytes(1);
int height = resultSet.getInt(2);
long timestamp = resultSet.getLong(3);
int transactionCount = resultSet.getInt(4);
BlockInfo blockInfo = new BlockInfo(signature, height, timestamp, transactionCount);
blockInfos.add(blockInfo);
} while (resultSet.next());
return blockInfos;
} catch (SQLException e) {
throw new DataException("Unable to fetch height-ranged block infos from repository", e);
}
}
@Override
public int trimOldOnlineAccountsSignatures(long timestamp) throws DataException {
String sql = "UPDATE Blocks set online_accounts_signatures = NULL WHERE minted_when < ? AND online_accounts_signatures IS NOT NULL";

Loading…
Cancel
Save