forked from Qortal/qortal
Blocks websocket now returns simpler block info
This commit is contained in:
parent
7377893050
commit
eb27b0d3e2
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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() {
|
||||||
|
@ -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());
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user