diff --git a/src/main/java/org/qortal/api/model/BlockInfo.java b/src/main/java/org/qortal/api/model/BlockInfo.java index 6076cf43..5d288e7f 100644 --- a/src/main/java/org/qortal/api/model/BlockInfo.java +++ b/src/main/java/org/qortal/api/model/BlockInfo.java @@ -3,6 +3,12 @@ package org.qortal.api.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; +import org.qortal.data.account.RewardShareData; +import org.qortal.data.block.BlockData; +import org.qortal.repository.DataException; +import org.qortal.repository.Repository; +import org.qortal.repository.RepositoryManager; + @XmlAccessorType(XmlAccessType.FIELD) public class BlockInfo { @@ -10,16 +16,36 @@ public class BlockInfo { private int height; private long timestamp; private int transactionCount; + private String minterAddress; protected BlockInfo() { /* For JAXB */ } - public BlockInfo(byte[] signature, int height, long timestamp, int transactionCount) { + public BlockInfo(byte[] signature, int height, long timestamp, int transactionCount, String minterAddress) { this.signature = signature; this.height = height; this.timestamp = timestamp; this.transactionCount = transactionCount; + this.minterAddress = minterAddress; + } + + public BlockInfo(BlockData blockData) { + // Convert BlockData to BlockInfo, using additional data + this.minterAddress = "unknown?"; + + try (final Repository repository = RepositoryManager.getRepository()) { + RewardShareData rewardShareData = repository.getAccountRepository().getRewardShare(blockData.getMinterPublicKey()); + if (rewardShareData != null) + this.minterAddress = rewardShareData.getMintingAccount(); + } catch (DataException e) { + // We'll carry on with placeholder minterAddress then... + } + + this.signature = blockData.getSignature(); + this.height = blockData.getHeight(); + this.timestamp = blockData.getTimestamp(); + this.transactionCount = blockData.getTransactionCount(); } public byte[] getSignature() { @@ -38,4 +64,8 @@ public class BlockInfo { return this.transactionCount; } + public String getMinterAddress() { + return this.minterAddress; + } + } diff --git a/src/main/java/org/qortal/api/websocket/BlocksWebSocket.java b/src/main/java/org/qortal/api/websocket/BlocksWebSocket.java index 3339f794..1a8adff2 100644 --- a/src/main/java/org/qortal/api/websocket/BlocksWebSocket.java +++ b/src/main/java/org/qortal/api/websocket/BlocksWebSocket.java @@ -2,6 +2,7 @@ package org.qortal.api.websocket; import java.io.IOException; import java.io.StringWriter; +import java.util.List; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketException; @@ -12,8 +13,8 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket; import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.qortal.api.ApiError; +import org.qortal.api.model.BlockInfo; import org.qortal.controller.BlockNotifier; -import org.qortal.data.block.BlockData; import org.qortal.repository.DataException; import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; @@ -30,7 +31,7 @@ public class BlocksWebSocket extends WebSocketServlet implements ApiWebSocket { @OnWebSocketConnect public void onWebSocketConnect(Session session) { - BlockNotifier.Listener listener = blockData -> onNotify(session, blockData); + BlockNotifier.Listener listener = blockInfo -> onNotify(session, blockInfo); BlockNotifier.getInstance().register(session, listener); } @@ -54,13 +55,19 @@ public class BlocksWebSocket extends WebSocketServlet implements ApiWebSocket { } try (final Repository repository = RepositoryManager.getRepository()) { - BlockData blockData = repository.getBlockRepository().fromSignature(signature); - if (blockData == null) { + int height = repository.getBlockRepository().getHeightFromSignature(signature); + if (height == 0) { sendError(session, ApiError.BLOCK_UNKNOWN); return; } - onNotify(session, blockData); + List blockInfos = repository.getBlockRepository().getBlockInfos(height, null, 1); + if (blockInfos == null || blockInfos.isEmpty()) { + sendError(session, ApiError.BLOCK_UNKNOWN); + return; + } + + onNotify(session, blockInfos.get(0)); } catch (DataException e) { sendError(session, ApiError.REPOSITORY_ISSUE); } @@ -83,23 +90,23 @@ public class BlocksWebSocket extends WebSocketServlet implements ApiWebSocket { } try (final Repository repository = RepositoryManager.getRepository()) { - BlockData blockData = repository.getBlockRepository().fromHeight(height); - if (blockData == null) { + List blockInfos = repository.getBlockRepository().getBlockInfos(height, null, 1); + if (blockInfos == null || blockInfos.isEmpty()) { sendError(session, ApiError.BLOCK_UNKNOWN); return; } - onNotify(session, blockData); + onNotify(session, blockInfos.get(0)); } catch (DataException e) { sendError(session, ApiError.REPOSITORY_ISSUE); } } - private void onNotify(Session session, BlockData blockData) { + private void onNotify(Session session, BlockInfo blockInfo) { StringWriter stringWriter = new StringWriter(); try { - this.marshall(stringWriter, blockData); + this.marshall(stringWriter, blockInfo); session.getRemote().sendStringByFuture(stringWriter.toString()); } catch (IOException | WebSocketException e) { diff --git a/src/main/java/org/qortal/controller/BlockNotifier.java b/src/main/java/org/qortal/controller/BlockNotifier.java index 742985ae..ad742a82 100644 --- a/src/main/java/org/qortal/controller/BlockNotifier.java +++ b/src/main/java/org/qortal/controller/BlockNotifier.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.Map; import org.eclipse.jetty.websocket.api.Session; +import org.qortal.api.model.BlockInfo; import org.qortal.data.block.BlockData; public class BlockNotifier { @@ -14,7 +15,7 @@ public class BlockNotifier { @FunctionalInterface public interface Listener { - void notify(BlockData blockData); + void notify(BlockInfo blockInfo); } private Map listenersBySession = new HashMap<>(); @@ -42,8 +43,11 @@ public class BlockNotifier { } public void onNewBlock(BlockData blockData) { + // Convert BlockData to BlockInfo + BlockInfo blockInfo = new BlockInfo(blockData); + for (Listener listener : getAllListeners()) - listener.notify(blockData); + listener.notify(blockInfo); } private Collection getAllListeners() { diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java index 39de4cc7..ccca6832 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java @@ -364,7 +364,7 @@ public class HSQLDBBlockRepository implements BlockRepository { @Override public List getBlockInfos(Integer startHeight, Integer endHeight, Integer count) throws DataException { StringBuilder sql = new StringBuilder(512); - sql.append("SELECT signature, height, minted_when, transaction_count "); + sql.append("SELECT signature, height, minted_when, transaction_count, RewardShares.minter "); /* * start end count result @@ -380,7 +380,9 @@ public class HSQLDBBlockRepository implements BlockRepository { */ if (startHeight != null && endHeight != null) { - sql.append("FROM Blocks WHERE height BETWEEN "); + sql.append("FROM Blocks "); + sql.append("JOIN RewardShares ON RewardShares.reward_share_public_key = Blocks.minter "); + sql.append("WHERE height BETWEEN "); sql.append(startHeight); sql.append(" AND "); sql.append(endHeight - 1); @@ -393,13 +395,17 @@ public class HSQLDBBlockRepository implements BlockRepository { 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"); + sql.append(" + 1) AND max_height "); + sql.append("JOIN RewardShares ON RewardShares.reward_share_public_key = Blocks.minter"); } else { - sql.append("FROM Blocks WHERE height BETWEEN "); + sql.append("FROM Blocks "); + sql.append("JOIN RewardShares ON RewardShares.reward_share_public_key = Blocks.minter "); + sql.append("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) @@ -408,7 +414,9 @@ public class HSQLDBBlockRepository implements BlockRepository { if (count == null) count = 50; - sql.append("FROM Blocks WHERE height BETWEEN "); + sql.append("FROM Blocks "); + sql.append("JOIN RewardShares ON RewardShares.reward_share_public_key = Blocks.minter "); + sql.append("WHERE height BETWEEN "); sql.append(startHeight); sql.append(" AND "); sql.append(startHeight + count - 1); @@ -425,8 +433,9 @@ public class HSQLDBBlockRepository implements BlockRepository { int height = resultSet.getInt(2); long timestamp = resultSet.getLong(3); int transactionCount = resultSet.getInt(4); + String minterAddress = resultSet.getString(5); - BlockInfo blockInfo = new BlockInfo(signature, height, timestamp, transactionCount); + BlockInfo blockInfo = new BlockInfo(signature, height, timestamp, transactionCount, minterAddress); blockInfos.add(blockInfo); } while (resultSet.next());