forked from Qortal/qortal
Added API call GET /blocks/summaries
Returns summary info about a range of blocks. (Not to be confused with network-related BlockSummaries)
This commit is contained in:
parent
6f2dd6c8d0
commit
fb2c2b1d09
41
src/main/java/org/qortal/api/model/BlockInfo.java
Normal file
41
src/main/java/org/qortal/api/model/BlockInfo.java
Normal file
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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…
Reference in New Issue
Block a user