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})
|
||||
public NameData getName(@PathParam("name") String name) {
|
||||
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);
|
||||
}
|
||||
|
||||
return nameData;
|
||||
} catch (ApiException e) {
|
||||
|
@ -209,6 +209,15 @@ public class Controller extends Thread {
|
||||
}
|
||||
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 StatsSnapshot() {
|
||||
@ -1275,6 +1284,10 @@ public class Controller extends Thread {
|
||||
onNetworkGetAccountNamesMessage(peer, message);
|
||||
break;
|
||||
|
||||
case GET_NAME:
|
||||
onNetworkGetNameMessage(peer, message);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGGER.debug(() -> String.format("Unhandled %s message [ID %d] from peer %s", message.getType().name(), message.getId(), peer));
|
||||
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
|
||||
|
||||
|
@ -80,6 +80,25 @@ public class LiteNode {
|
||||
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) {
|
||||
// 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),
|
||||
|
||||
NAMES(180),
|
||||
GET_ACCOUNT_NAMES(181);
|
||||
GET_ACCOUNT_NAMES(181),
|
||||
GET_NAME(182);
|
||||
|
||||
public final int value;
|
||||
public final Method fromByteBufferMethod;
|
||||
|
Loading…
Reference in New Issue
Block a user