Blocks websocket now returns simpler block info

This commit is contained in:
catbref 2020-07-24 14:52:14 +01:00
parent 7377893050
commit eb27b0d3e2
4 changed files with 69 additions and 19 deletions

View File

@ -3,6 +3,12 @@ package org.qortal.api.model;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType; 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) @XmlAccessorType(XmlAccessType.FIELD)
public class BlockInfo { public class BlockInfo {
@ -10,16 +16,36 @@ public class BlockInfo {
private int height; private int height;
private long timestamp; private long timestamp;
private int transactionCount; private int transactionCount;
private String minterAddress;
protected BlockInfo() { protected BlockInfo() {
/* For JAXB */ /* 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.signature = signature;
this.height = height; this.height = height;
this.timestamp = timestamp; this.timestamp = timestamp;
this.transactionCount = transactionCount; 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() { public byte[] getSignature() {
@ -38,4 +64,8 @@ public class BlockInfo {
return this.transactionCount; return this.transactionCount;
} }
public String getMinterAddress() {
return this.minterAddress;
}
} }

View File

@ -2,6 +2,7 @@ package org.qortal.api.websocket;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.List;
import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketException; 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.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import org.qortal.api.ApiError; import org.qortal.api.ApiError;
import org.qortal.api.model.BlockInfo;
import org.qortal.controller.BlockNotifier; import org.qortal.controller.BlockNotifier;
import org.qortal.data.block.BlockData;
import org.qortal.repository.DataException; import org.qortal.repository.DataException;
import org.qortal.repository.Repository; import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager; import org.qortal.repository.RepositoryManager;
@ -30,7 +31,7 @@ public class BlocksWebSocket extends WebSocketServlet implements ApiWebSocket {
@OnWebSocketConnect @OnWebSocketConnect
public void onWebSocketConnect(Session session) { public void onWebSocketConnect(Session session) {
BlockNotifier.Listener listener = blockData -> onNotify(session, blockData); BlockNotifier.Listener listener = blockInfo -> onNotify(session, blockInfo);
BlockNotifier.getInstance().register(session, listener); BlockNotifier.getInstance().register(session, listener);
} }
@ -54,13 +55,19 @@ public class BlocksWebSocket extends WebSocketServlet implements ApiWebSocket {
} }
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
BlockData blockData = repository.getBlockRepository().fromSignature(signature); int height = repository.getBlockRepository().getHeightFromSignature(signature);
if (blockData == null) { if (height == 0) {
sendError(session, ApiError.BLOCK_UNKNOWN); sendError(session, ApiError.BLOCK_UNKNOWN);
return; return;
} }
onNotify(session, blockData); List<BlockInfo> 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) { } catch (DataException e) {
sendError(session, ApiError.REPOSITORY_ISSUE); sendError(session, ApiError.REPOSITORY_ISSUE);
} }
@ -83,23 +90,23 @@ public class BlocksWebSocket extends WebSocketServlet implements ApiWebSocket {
} }
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
BlockData blockData = repository.getBlockRepository().fromHeight(height); List<BlockInfo> blockInfos = repository.getBlockRepository().getBlockInfos(height, null, 1);
if (blockData == null) { if (blockInfos == null || blockInfos.isEmpty()) {
sendError(session, ApiError.BLOCK_UNKNOWN); sendError(session, ApiError.BLOCK_UNKNOWN);
return; return;
} }
onNotify(session, blockData); onNotify(session, blockInfos.get(0));
} catch (DataException e) { } catch (DataException e) {
sendError(session, ApiError.REPOSITORY_ISSUE); sendError(session, ApiError.REPOSITORY_ISSUE);
} }
} }
private void onNotify(Session session, BlockData blockData) { private void onNotify(Session session, BlockInfo blockInfo) {
StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter();
try { try {
this.marshall(stringWriter, blockData); this.marshall(stringWriter, blockInfo);
session.getRemote().sendStringByFuture(stringWriter.toString()); session.getRemote().sendStringByFuture(stringWriter.toString());
} catch (IOException | WebSocketException e) { } catch (IOException | WebSocketException e) {

View File

@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.Session;
import org.qortal.api.model.BlockInfo;
import org.qortal.data.block.BlockData; import org.qortal.data.block.BlockData;
public class BlockNotifier { public class BlockNotifier {
@ -14,7 +15,7 @@ public class BlockNotifier {
@FunctionalInterface @FunctionalInterface
public interface Listener { public interface Listener {
void notify(BlockData blockData); void notify(BlockInfo blockInfo);
} }
private Map<Session, Listener> listenersBySession = new HashMap<>(); private Map<Session, Listener> listenersBySession = new HashMap<>();
@ -42,8 +43,11 @@ public class BlockNotifier {
} }
public void onNewBlock(BlockData blockData) { public void onNewBlock(BlockData blockData) {
// Convert BlockData to BlockInfo
BlockInfo blockInfo = new BlockInfo(blockData);
for (Listener listener : getAllListeners()) for (Listener listener : getAllListeners())
listener.notify(blockData); listener.notify(blockInfo);
} }
private Collection<Listener> getAllListeners() { private Collection<Listener> getAllListeners() {

View File

@ -364,7 +364,7 @@ public class HSQLDBBlockRepository implements BlockRepository {
@Override @Override
public List<BlockInfo> getBlockInfos(Integer startHeight, Integer endHeight, Integer count) throws DataException { public List<BlockInfo> getBlockInfos(Integer startHeight, Integer endHeight, Integer count) throws DataException {
StringBuilder sql = new StringBuilder(512); 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 * start end count result
@ -380,7 +380,9 @@ public class HSQLDBBlockRepository implements BlockRepository {
*/ */
if (startHeight != null && endHeight != null) { 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(startHeight);
sql.append(" AND "); sql.append(" AND ");
sql.append(endHeight - 1); 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("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("JOIN Blocks ON height BETWEEN (max_height - ");
sql.append(count); 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 { } 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(endHeight - count);
sql.append(" AND "); sql.append(" AND ");
sql.append(endHeight - 1); sql.append(endHeight - 1);
} }
} else { } else {
// we are going to return blocks from the start of the chain // we are going to return blocks from the start of the chain
if (startHeight == null) if (startHeight == null)
@ -408,7 +414,9 @@ public class HSQLDBBlockRepository implements BlockRepository {
if (count == null) if (count == null)
count = 50; 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(startHeight);
sql.append(" AND "); sql.append(" AND ");
sql.append(startHeight + count - 1); sql.append(startHeight + count - 1);
@ -425,8 +433,9 @@ public class HSQLDBBlockRepository implements BlockRepository {
int height = resultSet.getInt(2); int height = resultSet.getInt(2);
long timestamp = resultSet.getLong(3); long timestamp = resultSet.getLong(3);
int transactionCount = resultSet.getInt(4); 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); blockInfos.add(blockInfo);
} while (resultSet.next()); } while (resultSet.next());