forked from Qortal/qortal
Added GET_NAME message to allow lookups from name to owner (or any other name data).
This commit is contained in:
parent
276f1b7e68
commit
59119ebc3b
@ -134,10 +134,18 @@ public class NamesResource {
|
|||||||
@ApiErrors({ApiError.NAME_UNKNOWN, ApiError.REPOSITORY_ISSUE})
|
@ApiErrors({ApiError.NAME_UNKNOWN, ApiError.REPOSITORY_ISSUE})
|
||||||
public NameData getName(@PathParam("name") String name) {
|
public NameData getName(@PathParam("name") String name) {
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
NameData nameData = repository.getNameRepository().fromName(name);
|
NameData nameData;
|
||||||
|
|
||||||
if (nameData == null)
|
if (Settings.getInstance().isLite()) {
|
||||||
|
nameData = LiteNode.getInstance().fetchNameData(name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nameData = repository.getNameRepository().fromName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nameData == null) {
|
||||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.NAME_UNKNOWN);
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.NAME_UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
return nameData;
|
return nameData;
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
|
@ -209,6 +209,15 @@ public class Controller extends Thread {
|
|||||||
}
|
}
|
||||||
public GetAccountNamesMessageStats getAccountNamesMessageStats = new GetAccountNamesMessageStats();
|
public GetAccountNamesMessageStats getAccountNamesMessageStats = new GetAccountNamesMessageStats();
|
||||||
|
|
||||||
|
public static class GetNameMessageStats {
|
||||||
|
public AtomicLong requests = new AtomicLong();
|
||||||
|
public AtomicLong unknownAccounts = new AtomicLong();
|
||||||
|
|
||||||
|
public GetNameMessageStats() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public GetNameMessageStats getNameMessageStats = new GetNameMessageStats();
|
||||||
|
|
||||||
public AtomicLong latestBlocksCacheRefills = new AtomicLong();
|
public AtomicLong latestBlocksCacheRefills = new AtomicLong();
|
||||||
|
|
||||||
public StatsSnapshot() {
|
public StatsSnapshot() {
|
||||||
@ -1275,6 +1284,10 @@ public class Controller extends Thread {
|
|||||||
onNetworkGetAccountNamesMessage(peer, message);
|
onNetworkGetAccountNamesMessage(peer, message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GET_NAME:
|
||||||
|
onNetworkGetNameMessage(peer, message);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOGGER.debug(() -> String.format("Unhandled %s message [ID %d] from peer %s", message.getType().name(), message.getId(), peer));
|
LOGGER.debug(() -> String.format("Unhandled %s message [ID %d] from peer %s", message.getType().name(), message.getId(), peer));
|
||||||
break;
|
break;
|
||||||
@ -1632,6 +1645,41 @@ public class Controller extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onNetworkGetNameMessage(Peer peer, Message message) {
|
||||||
|
GetNameMessage getNameMessage = (GetNameMessage) message;
|
||||||
|
String name = getNameMessage.getName();
|
||||||
|
this.stats.getNameMessageStats.requests.incrementAndGet();
|
||||||
|
|
||||||
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
|
NameData nameData = repository.getNameRepository().fromName(name);
|
||||||
|
|
||||||
|
if (nameData == null) {
|
||||||
|
// We don't have this account
|
||||||
|
this.stats.getNameMessageStats.unknownAccounts.getAndIncrement();
|
||||||
|
|
||||||
|
// Send valid, yet unexpected message type in response, so peer doesn't have to wait for timeout
|
||||||
|
LOGGER.debug(() -> String.format("Sending 'name unknown' response to peer %s for GET_NAME request for unknown name %s", peer, name));
|
||||||
|
|
||||||
|
// We'll send empty block summaries message as it's very short
|
||||||
|
Message nameUnknownMessage = new BlockSummariesMessage(Collections.emptyList());
|
||||||
|
nameUnknownMessage.setId(message.getId());
|
||||||
|
if (!peer.sendMessage(nameUnknownMessage))
|
||||||
|
peer.disconnect("failed to send name-unknown response");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NamesMessage namesMessage = new NamesMessage(Arrays.asList(nameData));
|
||||||
|
namesMessage.setId(message.getId());
|
||||||
|
|
||||||
|
if (!peer.sendMessage(namesMessage)) {
|
||||||
|
peer.disconnect("failed to send name data");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (DataException e) {
|
||||||
|
LOGGER.error(String.format("Repository issue while send name %s to peer %s", name, peer), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
|
|
||||||
|
@ -80,6 +80,25 @@ public class LiteNode {
|
|||||||
return namesMessage.getNameDataList();
|
return namesMessage.getNameDataList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch info about a registered name
|
||||||
|
* @param name - the name to query
|
||||||
|
* @return a NameData object, or null if not retrieved
|
||||||
|
*/
|
||||||
|
public NameData fetchNameData(String name) {
|
||||||
|
GetNameMessage getNameMessage = new GetNameMessage(name);
|
||||||
|
NamesMessage namesMessage = (NamesMessage) this.sendMessage(getNameMessage, NAMES);
|
||||||
|
if (namesMessage == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<NameData> nameDataList = namesMessage.getNameDataList();
|
||||||
|
if (nameDataList == null || nameDataList.size() != 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// We are only expecting a single item in the list
|
||||||
|
return nameDataList.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private Message sendMessage(Message message, MessageType expectedResponseMessageType) {
|
private Message sendMessage(Message message, MessageType expectedResponseMessageType) {
|
||||||
// This asks a random peer for the data
|
// This asks a random peer for the data
|
||||||
|
55
src/main/java/org/qortal/network/message/GetNameMessage.java
Normal file
55
src/main/java/org/qortal/network/message/GetNameMessage.java
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package org.qortal.network.message;
|
||||||
|
|
||||||
|
import org.qortal.naming.Name;
|
||||||
|
import org.qortal.transform.TransformationException;
|
||||||
|
import org.qortal.transform.Transformer;
|
||||||
|
import org.qortal.utils.Serialization;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class GetNameMessage extends Message {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public GetNameMessage(String address) {
|
||||||
|
this(-1, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GetNameMessage(int id, String name) {
|
||||||
|
super(id, MessageType.GET_NAME);
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Message fromByteBuffer(int id, ByteBuffer bytes) throws UnsupportedEncodingException {
|
||||||
|
try {
|
||||||
|
String name = Serialization.deserializeSizedStringV2(bytes, Name.MAX_NAME_SIZE);
|
||||||
|
|
||||||
|
return new GetNameMessage(id, name);
|
||||||
|
} catch (TransformationException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected byte[] toData() {
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
Serialization.serializeSizedStringV2(bytes, this.name);
|
||||||
|
|
||||||
|
return bytes.toByteArray();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -109,7 +109,8 @@ public abstract class Message {
|
|||||||
GET_ACCOUNT_BALANCE(171),
|
GET_ACCOUNT_BALANCE(171),
|
||||||
|
|
||||||
NAMES(180),
|
NAMES(180),
|
||||||
GET_ACCOUNT_NAMES(181);
|
GET_ACCOUNT_NAMES(181),
|
||||||
|
GET_NAME(182);
|
||||||
|
|
||||||
public final int value;
|
public final int value;
|
||||||
public final Method fromByteBufferMethod;
|
public final Method fromByteBufferMethod;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user