diff --git a/src/main/java/org/qortal/api/resource/BlocksResource.java b/src/main/java/org/qortal/api/resource/BlocksResource.java index b8b4715e..10264a37 100644 --- a/src/main/java/org/qortal/api/resource/BlocksResource.java +++ b/src/main/java/org/qortal/api/resource/BlocksResource.java @@ -28,6 +28,7 @@ import org.qortal.api.model.BlockMinterSummary; import org.qortal.crypto.Crypto; import org.qortal.data.account.AccountData; import org.qortal.data.block.BlockData; +import org.qortal.data.block.BlockSummaryData; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; @@ -423,14 +424,14 @@ public class BlocksResource { @GET @Path("/minter/{address}") @Operation( - summary = "Fetch blocks minted by address", + summary = "Fetch block summaries for blocks minted by address", responses = { @ApiResponse( - description = "blocks", + description = "block summaries", content = @Content( array = @ArraySchema( schema = @Schema( - implementation = BlockData.class + implementation = BlockSummaryData.class ) ) ) @@ -438,7 +439,7 @@ public class BlocksResource { } ) @ApiErrors({ApiError.INVALID_ADDRESS, ApiError.PUBLIC_KEY_NOT_FOUND, ApiError.REPOSITORY_ISSUE}) - public List getBlocksByMinter(@PathParam("address") String address, @Parameter( + public List getBlockSummariesByMinter(@PathParam("address") String address, @Parameter( ref = "limit" ) @QueryParam("limit") Integer limit, @Parameter( ref = "offset" @@ -454,7 +455,7 @@ public class BlocksResource { if (accountData == null || accountData.getPublicKey() == null) throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.PUBLIC_KEY_NOT_FOUND); - return repository.getBlockRepository().getBlocksByMinter(accountData.getPublicKey(), limit, offset, reverse); + return repository.getBlockRepository().getBlockSummariesByMinter(accountData.getPublicKey(), limit, offset, reverse); } catch (ApiException e) { throw e; } catch (DataException e) { diff --git a/src/main/java/org/qortal/data/block/BlockSummaryData.java b/src/main/java/org/qortal/data/block/BlockSummaryData.java index 5599c959..3d789dd6 100644 --- a/src/main/java/org/qortal/data/block/BlockSummaryData.java +++ b/src/main/java/org/qortal/data/block/BlockSummaryData.java @@ -1,7 +1,11 @@ package org.qortal.data.block; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + import org.qortal.transform.block.BlockTransformer; +@XmlAccessorType(XmlAccessType.FIELD) public class BlockSummaryData { // Properties @@ -14,6 +18,10 @@ public class BlockSummaryData { private Integer minterLevel; // Constructors + + protected BlockSummaryData() { + } + public BlockSummaryData(int height, byte[] signature, byte[] minterPublicKey, int onlineAccountsCount) { this.height = height; this.signature = signature; diff --git a/src/main/java/org/qortal/repository/BlockRepository.java b/src/main/java/org/qortal/repository/BlockRepository.java index db65d261..a7f8e1f9 100644 --- a/src/main/java/org/qortal/repository/BlockRepository.java +++ b/src/main/java/org/qortal/repository/BlockRepository.java @@ -114,9 +114,9 @@ public interface BlockRepository { public List getBlockMinters(List addresses, Integer limit, Integer offset, Boolean reverse) throws DataException; /** - * Returns blocks with passed minter public key. + * Returns block summaries for blocks minted by passed public key, or reward-share with minter with passed public key. */ - public List getBlocksByMinter(byte[] minterPublicKey, Integer limit, Integer offset, Boolean reverse) throws DataException; + public List getBlockSummariesByMinter(byte[] minterPublicKey, Integer limit, Integer offset, Boolean reverse) throws DataException; /** * Returns blocks within height range. diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java index 85d8b31e..8063d417 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java @@ -258,27 +258,41 @@ public class HSQLDBBlockRepository implements BlockRepository { } @Override - public List getBlocksByMinter(byte[] minterPublicKey, Integer limit, Integer offset, Boolean reverse) throws DataException { + public List getBlockSummariesByMinter(byte[] minterPublicKey, Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(512); - sql.append("SELECT " + BLOCK_DB_COLUMNS + " FROM Blocks WHERE minter = ? ORDER BY height "); + sql.append("SELECT signature, height, minter, online_accounts_count FROM "); + + // List of minter account's public key and reward-share public keys with minter's public key + sql.append("(SELECT * FROM (VALUES (CAST(? AS QortalPublicKey))) UNION (SELECT reward_share_public_key FROM RewardShares WHERE minter_public_key = ?)) AS PublicKeys (public_key) "); + + // Match Blocks signed with public key from above list + sql.append("JOIN Blocks ON minter = public_key "); + + sql.append("ORDER BY Blocks.height "); if (reverse != null && reverse) - sql.append(" DESC"); + sql.append("DESC "); HSQLDBRepository.limitOffsetSql(sql, limit, offset); - List blockData = new ArrayList<>(); + List blockSummaries = new ArrayList<>(); - try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), minterPublicKey)) { + try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), minterPublicKey, minterPublicKey)) { if (resultSet == null) - return blockData; + return blockSummaries; do { - blockData.add(getBlockFromResultSet(resultSet)); + byte[] signature = resultSet.getBytes(1); + int height = resultSet.getInt(2); + byte[] blockMinterPublicKey = resultSet.getBytes(3); + int onlineAccountsCount = resultSet.getInt(4); + + BlockSummaryData blockSummary = new BlockSummaryData(height, signature, blockMinterPublicKey, onlineAccountsCount); + blockSummaries.add(blockSummary); } while (resultSet.next()); - return blockData; + return blockSummaries; } catch (SQLException e) { - throw new DataException("Unable to fetch minter's blocks from repository", e); + throw new DataException("Unable to fetch minter's block summaries from repository", e); } } diff --git a/src/test/java/org/qortal/test/api/BlockApiTests.java b/src/test/java/org/qortal/test/api/BlockApiTests.java index 8dea8eea..4d9d5320 100644 --- a/src/test/java/org/qortal/test/api/BlockApiTests.java +++ b/src/test/java/org/qortal/test/api/BlockApiTests.java @@ -26,7 +26,7 @@ public class BlockApiTests extends ApiCommon { } @Test - public void testGetBlockForgers() { + public void testGetBlockMinters() { List addresses = Arrays.asList(aliceAddress, aliceAddress); assertNotNull(this.blocksResource.getBlockMinters(Collections.emptyList(), null, null, null)); @@ -36,9 +36,9 @@ public class BlockApiTests extends ApiCommon { } @Test - public void testGetBlocksByForger() { - assertNotNull(this.blocksResource.getBlocksByMinter(aliceAddress, null, null, null)); - assertNotNull(this.blocksResource.getBlocksByMinter(aliceAddress, 1, 1, true)); + public void testGetBlockSummariesByMinter() { + assertNotNull(this.blocksResource.getBlockSummariesByMinter(aliceAddress, null, null, null)); + assertNotNull(this.blocksResource.getBlockSummariesByMinter(aliceAddress, 1, 1, true)); } } diff --git a/src/test/java/org/qortal/test/group/GroupApprovalTests.java b/src/test/java/org/qortal/test/group/GroupApprovalTests.java index c476e40f..e5c34ab0 100644 --- a/src/test/java/org/qortal/test/group/GroupApprovalTests.java +++ b/src/test/java/org/qortal/test/group/GroupApprovalTests.java @@ -110,7 +110,7 @@ public class GroupApprovalTests extends Common { // Transaction fee should have ended up in forging account BigDecimal alicePostAssetBalance = aliceAccount.getConfirmedBalance(Asset.QORT); - Common.assertEqualBigDecimals("block forger's balance incorrect", aliceOriginalBalance.add(blockReward).add(fee), alicePostAssetBalance); + Common.assertEqualBigDecimals("block minter's balance incorrect", aliceOriginalBalance.add(blockReward).add(fee), alicePostAssetBalance); // Have Bob do a non-approval transaction to change his last-reference Transaction bobPaymentTransaction = buildPaymentTransaction(repository, "bob", "chloe", amount, Group.NO_GROUP); @@ -122,7 +122,7 @@ public class GroupApprovalTests extends Common { // Have Alice approve Bob's approval-needed transaction GroupUtils.approveTransaction(repository, "alice", bobAssetTransaction.getTransactionData().getSignature(), true); - // Now forge a few blocks so transaction is approved + // Now mint a few blocks so transaction is approved for (int blockCount = 0; blockCount < minBlockDelay; ++blockCount) BlockUtils.mintBlock(repository); @@ -195,7 +195,7 @@ public class GroupApprovalTests extends Common { // Have Alice approve Bob's approval-needed transaction GroupUtils.approveTransaction(repository, "alice", bobAssetTransaction.getTransactionData().getSignature(), true); - // Now forge a few blocks so transaction is approved + // Now mint a few blocks so transaction is approved for (int blockCount = 0; blockCount < minBlockDelay; ++blockCount) BlockUtils.mintBlock(repository); @@ -256,7 +256,7 @@ public class GroupApprovalTests extends Common { // Have Alice reject Bob's approval-needed transaction GroupUtils.approveTransaction(repository, "alice", bobAssetTransaction.getTransactionData().getSignature(), false); - // Now forge a few blocks so transaction is approved + // Now mint a few blocks so transaction is approved for (int blockCount = 0; blockCount < minBlockDelay; ++blockCount) BlockUtils.mintBlock(repository); @@ -314,7 +314,7 @@ public class GroupApprovalTests extends Common { Integer approvalHeight = GroupUtils.getApprovalHeight(repository, bobAssetTransaction.getTransactionData().getSignature()); assertNull("group-approval decision height should be null", approvalHeight); - // Now forge a few blocks so group-approval for transaction expires + // Now mint a few blocks so group-approval for transaction expires for (int blockCount = 0; blockCount <= maxBlockDelay; ++blockCount) BlockUtils.mintBlock(repository); @@ -374,7 +374,7 @@ public class GroupApprovalTests extends Common { approvalStatus = GroupUtils.getApprovalStatus(repository, aliceAssetTransaction.getTransactionData().getSignature()); assertEquals("incorrect transaction approval status", ApprovalStatus.NOT_REQUIRED, approvalStatus); - // Now forge a few blocks so transaction is approved + // Now mint a few blocks so transaction is approved for (int blockCount = 0; blockCount < minBlockDelay; ++blockCount) BlockUtils.mintBlock(repository);