Added some API endpoints relating to penalties. Relies on some code not yet committed.

This commit is contained in:
CalDescent 2022-11-26 15:51:06 +00:00
parent ab687af4bb
commit 7003a8274b
3 changed files with 159 additions and 0 deletions

View File

@ -0,0 +1,56 @@
package org.qortal.api.model;
import org.qortal.block.SelfSponsorshipAlgoV1Block;
import org.qortal.data.account.AccountData;
import org.qortal.data.naming.NameData;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import java.util.ArrayList;
import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
public class AccountPenaltyStats {
public int totalPenalties;
public int maxPenalty;
public int minPenalty;
public String penaltyHash;
protected AccountPenaltyStats() {
}
public AccountPenaltyStats(int totalPenalties, int maxPenalty, int minPenalty, String penaltyHash) {
this.totalPenalties = totalPenalties;
this.maxPenalty = maxPenalty;
this.minPenalty = minPenalty;
this.penaltyHash = penaltyHash;
}
public static AccountPenaltyStats fromAccounts(List<AccountData> accounts) {
int totalPenalties = 0;
Integer maxPenalty = null;
Integer minPenalty = null;
List<String> addresses = new ArrayList<>();
for (AccountData accountData : accounts) {
int penalty = accountData.getBlocksMintedPenalty();
addresses.add(accountData.getAddress());
totalPenalties++;
// Penalties are expressed as a negative number, so the min and the max are reversed here
if (maxPenalty == null || penalty < maxPenalty) maxPenalty = penalty;
if (minPenalty == null || penalty > minPenalty) minPenalty = penalty;
}
String penaltyHash = SelfSponsorshipAlgoV1Block.getHash(addresses);
return new AccountPenaltyStats(totalPenalties, maxPenalty, minPenalty, penaltyHash);
}
@Override
public String toString() {
return String.format("totalPenalties: %d, maxPenalty: %d, minPenalty: %d, penaltyHash: %s", totalPenalties, maxPenalty, minPenalty, penaltyHash == null ? "null" : penaltyHash);
}
}

View File

@ -14,6 +14,7 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
@ -27,6 +28,7 @@ import org.qortal.api.ApiErrors;
import org.qortal.api.ApiException;
import org.qortal.api.ApiExceptionFactory;
import org.qortal.api.Security;
import org.qortal.api.model.AccountPenaltyStats;
import org.qortal.api.model.ApiOnlineAccount;
import org.qortal.api.model.RewardShareKeyRequest;
import org.qortal.asset.Asset;
@ -34,6 +36,7 @@ import org.qortal.controller.LiteNode;
import org.qortal.controller.OnlineAccountsManager;
import org.qortal.crypto.Crypto;
import org.qortal.data.account.AccountData;
import org.qortal.data.account.AccountPenaltyData;
import org.qortal.data.account.RewardShareData;
import org.qortal.data.network.OnlineAccountData;
import org.qortal.data.network.OnlineAccountLevel;
@ -471,6 +474,54 @@ public class AddressesResource {
}
}
@GET
@Path("/penalties")
@Operation(
summary = "Get addresses with penalties",
description = "Returns a list of accounts with a blocksMintedPenalty",
responses = {
@ApiResponse(
description = "accounts with penalties",
content = @Content(mediaType = MediaType.APPLICATION_JSON, array = @ArraySchema(schema = @Schema(implementation = AccountPenaltyData.class)))
)
}
)
@ApiErrors({ApiError.INVALID_ADDRESS, ApiError.REPOSITORY_ISSUE})
public List<AccountPenaltyData> getAccountsWithPenalties() {
try (final Repository repository = RepositoryManager.getRepository()) {
List<AccountData> accounts = repository.getAccountRepository().getPenaltyAccounts();
List<AccountPenaltyData> penalties = accounts.stream().map(a -> new AccountPenaltyData(a.getAddress(), a.getBlocksMintedPenalty())).collect(Collectors.toList());
return penalties;
} catch (DataException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
}
}
@GET
@Path("/penalties/stats")
@Operation(
summary = "Get stats about current penalties",
responses = {
@ApiResponse(
description = "aggregated stats about accounts with penalties",
content = @Content(mediaType = MediaType.APPLICATION_JSON, array = @ArraySchema(schema = @Schema(implementation = AccountPenaltyStats.class)))
)
}
)
@ApiErrors({ApiError.INVALID_ADDRESS, ApiError.REPOSITORY_ISSUE})
public AccountPenaltyStats getPenaltyStats() {
try (final Repository repository = RepositoryManager.getRepository()) {
List<AccountData> accounts = repository.getAccountRepository().getPenaltyAccounts();
return AccountPenaltyStats.fromAccounts(accounts);
} catch (DataException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
}
}
@POST
@Path("/publicize")
@Operation(

View File

@ -0,0 +1,52 @@
package org.qortal.data.account;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
// All properties to be converted to JSON via JAXB
@XmlAccessorType(XmlAccessType.FIELD)
public class AccountPenaltyData {
// Properties
private String address;
private int blocksMintedPenalty;
// Constructors
// necessary for JAXB
protected AccountPenaltyData() {
}
public AccountPenaltyData(String address, int blocksMintedPenalty) {
this.address = address;
this.blocksMintedPenalty = blocksMintedPenalty;
}
// Getters/Setters
public String getAddress() {
return this.address;
}
public int getBlocksMintedPenalty() {
return this.blocksMintedPenalty;
}
public String toString() {
return String.format("%s has penalty %d", this.address, this.blocksMintedPenalty);
}
@Override
public boolean equals(Object b) {
if (!(b instanceof AccountPenaltyData))
return false;
return this.getAddress().equals(((AccountPenaltyData) b).getAddress());
}
@Override
public int hashCode() {
return address.hashCode();
}
}