forked from Qortal/qortal
Code clean-up thanks to SonarLint & bugfix for ByteArray::compareTo!
This commit is contained in:
parent
a3751823eb
commit
5798c69449
@ -3,7 +3,6 @@ package org.hsqldb.jdbc;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hsqldb.jdbc.JDBCPool;
|
||||
import org.hsqldb.jdbc.pool.JDBCPooledConnection;
|
||||
|
||||
public class HSQLDBPool extends JDBCPool {
|
||||
|
@ -34,10 +34,10 @@ public class ApplyUpdate {
|
||||
private static final String NEW_JAR_FILENAME = AutoUpdate.NEW_JAR_FILENAME;
|
||||
private static final String WINDOWS_EXE_LAUNCHER = "qora-core.exe";
|
||||
|
||||
private static final long CHECK_INTERVAL = 5 * 1000; // ms
|
||||
private static final long CHECK_INTERVAL = 5 * 1000L; // ms
|
||||
private static final int MAX_ATTEMPTS = 5;
|
||||
|
||||
public static void main(String args[]) {
|
||||
public static void main(String[] args) {
|
||||
Security.insertProviderAt(new BouncyCastleProvider(), 0);
|
||||
Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
|
||||
|
||||
@ -114,6 +114,7 @@ public class ApplyUpdate {
|
||||
try {
|
||||
Thread.sleep(CHECK_INTERVAL);
|
||||
} catch (InterruptedException e) {
|
||||
// Doggedly retry
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.qora;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.Security;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
@ -17,15 +16,15 @@ public class ProxyKeys {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
public static void main(String argv[]) throws IOException {
|
||||
if (argv.length != 2)
|
||||
public static void main(String[] args) {
|
||||
if (args.length != 2)
|
||||
usage();
|
||||
|
||||
Security.insertProviderAt(new BouncyCastleProvider(), 0);
|
||||
Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
|
||||
|
||||
PrivateKeyAccount privateAccount = new PrivateKeyAccount(null, Base58.decode(argv[0]));
|
||||
PublicKeyAccount publicAccount = new PublicKeyAccount(null, Base58.decode(argv[1]));
|
||||
PrivateKeyAccount privateAccount = new PrivateKeyAccount(null, Base58.decode(args[0]));
|
||||
PublicKeyAccount publicAccount = new PublicKeyAccount(null, Base58.decode(args[1]));
|
||||
|
||||
byte[] proxyPrivateKey = privateAccount.getProxyPrivateKey(publicAccount.getPublicKey());
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.qora;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.Random;
|
||||
@ -59,22 +58,22 @@ public class VanityGen {
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String argv[]) throws IOException {
|
||||
if (argv.length == 0)
|
||||
public static void main(String[] args) {
|
||||
if (args.length == 0)
|
||||
usage();
|
||||
|
||||
int threadCount = 1;
|
||||
|
||||
int argIndex = 0;
|
||||
while (argIndex < argv.length) {
|
||||
String arg = argv[argIndex++];
|
||||
while (argIndex < args.length) {
|
||||
String arg = args[argIndex++];
|
||||
|
||||
if (arg.equals("-t")) {
|
||||
if (argIndex >= argv.length)
|
||||
if (argIndex >= args.length)
|
||||
usage();
|
||||
|
||||
try {
|
||||
threadCount = Integer.parseInt(argv[argIndex++]);
|
||||
threadCount = Integer.parseInt(args[argIndex++]);
|
||||
} catch (NumberFormatException e) {
|
||||
usage();
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ public class XorUpdate {
|
||||
|
||||
private static final byte XOR_VALUE = AutoUpdate.XOR_VALUE;
|
||||
|
||||
public static void main(String args[]) {
|
||||
public static void main(String[] args) {
|
||||
if (args.length != 2) {
|
||||
System.err.println("usage: XorUpdate <input-file> <output-file>");
|
||||
System.exit(1);
|
||||
|
@ -142,9 +142,9 @@ public class Account {
|
||||
byte[] reference = null;
|
||||
|
||||
for (TransactionData transactionData : unconfirmedTransactions) {
|
||||
String address = PublicKeyAccount.getAddress(transactionData.getCreatorPublicKey());
|
||||
String unconfirmedTransactionAddress = PublicKeyAccount.getAddress(transactionData.getCreatorPublicKey());
|
||||
|
||||
if (address.equals(this.address))
|
||||
if (unconfirmedTransactionAddress.equals(this.address))
|
||||
reference = transactionData.getSignature();
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ public enum ApiError {
|
||||
// Groups
|
||||
GROUP_UNKNOWN(1101, 404);
|
||||
|
||||
private final static Map<Integer, ApiError> map = stream(ApiError.values()).collect(toMap(apiError -> apiError.code, apiError -> apiError));
|
||||
private static final Map<Integer, ApiError> map = stream(ApiError.values()).collect(toMap(apiError -> apiError.code, apiError -> apiError));
|
||||
|
||||
private final int code; // API error code
|
||||
private final int status; // HTTP status code
|
||||
|
@ -10,12 +10,12 @@ public class ApiException extends WebApplicationException {
|
||||
private static final long serialVersionUID = 4619299036312089050L;
|
||||
|
||||
// HTTP status code
|
||||
public int status;
|
||||
public final int status;
|
||||
|
||||
// API error code
|
||||
public int error;
|
||||
public final int error;
|
||||
|
||||
public String message;
|
||||
public final String message;
|
||||
|
||||
public ApiException(int status, int error, String message) {
|
||||
this(status, error, message, null);
|
||||
|
@ -47,7 +47,6 @@ public class ApiService {
|
||||
}
|
||||
|
||||
public Iterable<Class<?>> getResources() {
|
||||
// return resources;
|
||||
return this.config.getClasses();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.qora.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@ -17,7 +17,7 @@ public class TransactionCountMapXmlAdapter extends XmlAdapter<TransactionCountMa
|
||||
|
||||
public static class StringIntegerMap {
|
||||
@XmlVariableNode("key")
|
||||
List<MapEntry> entries = new ArrayList<MapEntry>();
|
||||
List<MapEntry> entries = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static class MapEntry {
|
||||
@ -30,7 +30,7 @@ public class TransactionCountMapXmlAdapter extends XmlAdapter<TransactionCountMa
|
||||
|
||||
@Override
|
||||
public Map<TransactionType, Integer> unmarshal(StringIntegerMap stringIntegerMap) throws Exception {
|
||||
Map<TransactionType, Integer> map = new HashMap<>(stringIntegerMap.entries.size());
|
||||
Map<TransactionType, Integer> map = new EnumMap<>(TransactionType.class);
|
||||
|
||||
for (MapEntry entry : stringIntegerMap.entries)
|
||||
map.put(TransactionType.valueOf(entry.key), entry.value);
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.qora.api.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
@ -20,9 +20,10 @@ public class ActivitySummary {
|
||||
|
||||
// Assuming TransactionType values are contiguous so 'length' equals count
|
||||
@XmlJavaTypeAdapter(TransactionCountMapXmlAdapter.class)
|
||||
public Map<TransactionType, Integer> transactionCountByType = new HashMap<>();
|
||||
public Map<TransactionType, Integer> transactionCountByType = new EnumMap<>(TransactionType.class);
|
||||
|
||||
public ActivitySummary() {
|
||||
// Needed for JAXB
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ import org.qora.api.ApiException;
|
||||
import org.qora.api.ApiExceptionFactory;
|
||||
import org.qora.api.model.ApiOnlineAccount;
|
||||
import org.qora.api.model.ProxyKeyRequest;
|
||||
import org.qora.api.resource.TransactionsResource;
|
||||
import org.qora.asset.Asset;
|
||||
import org.qora.controller.Controller;
|
||||
import org.qora.crypto.Crypto;
|
||||
|
@ -134,9 +134,7 @@ public class AdminResource {
|
||||
public String shutdown() {
|
||||
Security.checkApiCallAllowed(request);
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new Thread(() -> {
|
||||
// Short sleep to allow HTTP response body to be emitted
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
@ -145,7 +143,6 @@ public class AdminResource {
|
||||
}
|
||||
|
||||
Controller.getInstance().shutdownAndExit();
|
||||
}
|
||||
}).start();
|
||||
|
||||
return "true";
|
||||
|
@ -66,7 +66,7 @@ public class AnnotationPostProcessor implements ReaderListener {
|
||||
if (apiErrors == null)
|
||||
continue;
|
||||
|
||||
LOGGER.trace("Found @ApiErrors annotation on " + clazz.getSimpleName() + "." + method.getName());
|
||||
LOGGER.trace(() -> String.format("Found @ApiErrors annotation on %s.%s", clazz.getSimpleName(), method.getName()));
|
||||
PathItem pathItem = getPathItemFromMethod(openAPI, classPathString, method);
|
||||
|
||||
if (pathItem == null) {
|
||||
|
@ -282,7 +282,7 @@ public class AssetsResource {
|
||||
List<OrderData> orders = repository.getAssetRepository().getAggregatedOpenOrders(assetId, otherAssetId, limit, offset, reverse);
|
||||
|
||||
// Map to aggregated form
|
||||
return orders.stream().map(orderData -> new AggregatedOrder(orderData)).collect(Collectors.toList());
|
||||
return orders.stream().map(AggregatedOrder::new).collect(Collectors.toList());
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
|
@ -98,9 +98,7 @@ public class GroupsResource {
|
||||
ref = "reverse"
|
||||
) @QueryParam("reverse") Boolean reverse) {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
List<GroupData> groups = repository.getGroupRepository().getAllGroups(limit, offset, reverse);
|
||||
|
||||
return groups;
|
||||
return repository.getGroupRepository().getAllGroups(limit, offset, reverse);
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
@ -126,9 +124,7 @@ public class GroupsResource {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ADDRESS);
|
||||
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
List<GroupData> groups = repository.getGroupRepository().getGroupsByOwner(owner);
|
||||
|
||||
return groups;
|
||||
return repository.getGroupRepository().getGroupsByOwner(owner);
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
@ -154,9 +150,7 @@ public class GroupsResource {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ADDRESS);
|
||||
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
List<GroupData> groups = repository.getGroupRepository().getGroupsWithMember(member);
|
||||
|
||||
return groups;
|
||||
return repository.getGroupRepository().getGroupsWithMember(member);
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public class NamesResource {
|
||||
List<NameData> names = repository.getNameRepository().getAllNames(limit, offset, reverse);
|
||||
|
||||
// Convert to summary
|
||||
return names.stream().map(nameData -> new NameSummary(nameData)).collect(Collectors.toList());
|
||||
return names.stream().map(NameSummary::new).collect(Collectors.toList());
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
@ -102,7 +102,7 @@ public class NamesResource {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
List<NameData> names = repository.getNameRepository().getNamesByOwner(address, limit, offset, reverse);
|
||||
|
||||
return names.stream().map(nameData -> new NameSummary(nameData)).collect(Collectors.toList());
|
||||
return names.stream().map(NameSummary::new).collect(Collectors.toList());
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class PeersResource {
|
||||
}
|
||||
)
|
||||
public List<ConnectedPeer> getPeers() {
|
||||
return Network.getInstance().getConnectedPeers().stream().map(peer -> new ConnectedPeer(peer)).collect(Collectors.toList());
|
||||
return Network.getInstance().getConnectedPeers().stream().map(ConnectedPeer::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@GET
|
||||
|
@ -311,7 +311,7 @@ public class TransactionsResource {
|
||||
txTypes, null, address, confirmationStatus, limit, offset, reverse);
|
||||
|
||||
// Expand signatures to transactions
|
||||
List<TransactionData> transactions = new ArrayList<TransactionData>(signatures.size());
|
||||
List<TransactionData> transactions = new ArrayList<>(signatures.size());
|
||||
for (byte[] signature : signatures)
|
||||
transactions.add(repository.getTransactionRepository().fromSignature(signature));
|
||||
|
||||
|
@ -229,14 +229,15 @@ public class Order {
|
||||
|
||||
final boolean isOrderNewAssetPricing = orderData.getTimestamp() >= BlockChain.getInstance().getNewAssetPricingTimestamp();
|
||||
|
||||
final long haveAssetId = orderData.getHaveAssetId();
|
||||
final long wantAssetId = orderData.getWantAssetId();
|
||||
// Cached for readability
|
||||
final long _haveAssetId = orderData.getHaveAssetId();
|
||||
final long _wantAssetId = orderData.getWantAssetId();
|
||||
|
||||
final AssetData haveAssetData = this.repository.getAssetRepository().fromAssetId(haveAssetId);
|
||||
final AssetData wantAssetData = this.repository.getAssetRepository().fromAssetId(wantAssetId);
|
||||
final AssetData haveAssetData = this.repository.getAssetRepository().fromAssetId(_haveAssetId);
|
||||
final AssetData wantAssetData = this.repository.getAssetRepository().fromAssetId(_wantAssetId);
|
||||
|
||||
final long amountAssetId = (isOurOrderNewPricing && wantAssetId > haveAssetId) ? wantAssetId : haveAssetId;
|
||||
final long returnAssetId = (isOurOrderNewPricing && haveAssetId < wantAssetId) ? haveAssetId : wantAssetId;
|
||||
final long amountAssetId = (isOurOrderNewPricing && _wantAssetId > _haveAssetId) ? _wantAssetId : _haveAssetId;
|
||||
final long returnAssetId = (isOurOrderNewPricing && _haveAssetId < _wantAssetId) ? _haveAssetId : _wantAssetId;
|
||||
|
||||
final AssetData amountAssetData = this.repository.getAssetRepository().fromAssetId(amountAssetId);
|
||||
final AssetData returnAssetData = this.repository.getAssetRepository().fromAssetId(returnAssetId);
|
||||
|
@ -45,7 +45,7 @@ public class AT {
|
||||
|
||||
byte[] creationBytes = deployATTransactionData.getCreationBytes();
|
||||
long assetId = deployATTransactionData.getAssetId();
|
||||
short version = (short) (creationBytes[0] | (creationBytes[1] << 8)); // Little-endian
|
||||
short version = (short) ((creationBytes[0] & 0xff) | (creationBytes[1] << 8)); // Little-endian
|
||||
|
||||
if (version >= 2) {
|
||||
MachineState machineState = new MachineState(deployATTransactionData.getCreationBytes());
|
||||
@ -78,7 +78,7 @@ public class AT {
|
||||
|
||||
// Extract actual code length, stored in minimal-size form (byte, short or int)
|
||||
if (numCodePages * 256 < 257) {
|
||||
codeLen = (int) (byteBuffer.get() & 0xff);
|
||||
codeLen = byteBuffer.get() & 0xff;
|
||||
} else if (numCodePages * 256 < Short.MAX_VALUE + 1) {
|
||||
codeLen = byteBuffer.getShort() & 0xffff;
|
||||
} else if (numCodePages * 256 <= Integer.MAX_VALUE) {
|
||||
@ -135,14 +135,14 @@ public class AT {
|
||||
byte[] codeBytes = this.atData.getCodeBytes();
|
||||
|
||||
// Fetch latest ATStateData for this AT (if any)
|
||||
ATStateData atStateData = this.repository.getATRepository().getLatestATState(atAddress);
|
||||
ATStateData latestAtStateData = this.repository.getATRepository().getLatestATState(atAddress);
|
||||
|
||||
// There should be at least initial AT state data
|
||||
if (atStateData == null)
|
||||
if (latestAtStateData == null)
|
||||
throw new IllegalStateException("No initial AT state data found");
|
||||
|
||||
// [Re]create AT machine state using AT state data or from scratch as applicable
|
||||
MachineState state = MachineState.fromBytes(api, logger, atStateData.getStateData(), codeBytes);
|
||||
MachineState state = MachineState.fromBytes(api, logger, latestAtStateData.getStateData(), codeBytes);
|
||||
state.execute();
|
||||
|
||||
int height = this.repository.getBlockRepository().getBlockchainHeight() + 1;
|
||||
|
@ -115,7 +115,7 @@ public enum BlockchainAPI {
|
||||
|
||||
public final int value;
|
||||
|
||||
private final static Map<Integer, BlockchainAPI> map = stream(BlockchainAPI.values()).collect(toMap(type -> type.value, type -> type));
|
||||
private static final Map<Integer, BlockchainAPI> map = stream(BlockchainAPI.values()).collect(toMap(type -> type.value, type -> type));
|
||||
|
||||
BlockchainAPI(int value) {
|
||||
this.value = value;
|
||||
|
@ -52,7 +52,7 @@ public class QoraATAPI extends API {
|
||||
public QoraATAPI(Repository repository, ATData atData, long blockTimestamp) {
|
||||
this.repository = repository;
|
||||
this.atData = atData;
|
||||
this.transactions = new ArrayList<AtTransaction>();
|
||||
this.transactions = new ArrayList<>();
|
||||
this.blockTimestamp = blockTimestamp;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package org.qora.at;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.qora.at.AT;
|
||||
|
||||
public class QoraATLogger implements org.ciyam.at.LoggerInterface {
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.qora.at;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@ -37,14 +37,10 @@ public enum QoraFunctionCode {
|
||||
protected void postCheckExecute(FunctionData functionData, MachineState state, short rawFunctionCode) throws ExecutionException {
|
||||
Timestamp timestamp = new Timestamp(functionData.value2);
|
||||
|
||||
try {
|
||||
String recipient = new String(state.getB(), "UTF-8");
|
||||
String recipient = new String(state.getB(), StandardCharsets.UTF_8);
|
||||
|
||||
BlockchainAPI blockchainAPI = BlockchainAPI.valueOf(timestamp.blockchainId);
|
||||
blockchainAPI.putTransactionFromRecipientAfterTimestampInA(recipient, timestamp, state);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new ExecutionException("Couldn't parse recipient from B", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -102,6 +98,6 @@ public enum QoraFunctionCode {
|
||||
}
|
||||
|
||||
/** Actually execute function */
|
||||
abstract protected void postCheckExecute(FunctionData functionData, MachineState state, short rawFunctionCode) throws ExecutionException;
|
||||
protected abstract void postCheckExecute(FunctionData functionData, MachineState state, short rawFunctionCode) throws ExecutionException;
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package org.qora.block;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@ -204,7 +205,7 @@ public class BlockGenerator extends Thread {
|
||||
ValidationResult validationResult = newBlock.isValid();
|
||||
if (validationResult != ValidationResult.OK) {
|
||||
// No longer valid? Report and discard
|
||||
LOGGER.error("Valid, generated block now invalid '" + validationResult.name() + "' after adding unconfirmed transactions?");
|
||||
LOGGER.error(String.format("Valid, generated block now invalid '%s' after adding unconfirmed transactions?", validationResult.name()));
|
||||
|
||||
// Rebuild block candidates, just to be sure
|
||||
newBlocks.clear();
|
||||
@ -215,7 +216,7 @@ public class BlockGenerator extends Thread {
|
||||
try {
|
||||
newBlock.process();
|
||||
|
||||
LOGGER.info("Generated new block: " + newBlock.getBlockData().getHeight());
|
||||
LOGGER.info(String.format("Generated new block: %d", newBlock.getBlockData().getHeight()));
|
||||
repository.saveChanges();
|
||||
|
||||
ProxyForgerData proxyForgerData = repository.getAccountRepository().getProxyForgeData(newBlock.getBlockData().getGeneratorPublicKey());
|
||||
@ -292,24 +293,15 @@ public class BlockGenerator extends Thread {
|
||||
// Grab all valid unconfirmed transactions (already sorted)
|
||||
List<TransactionData> unconfirmedTransactions = Transaction.getUnconfirmedTransactions(repository);
|
||||
|
||||
for (int i = 0; i < unconfirmedTransactions.size(); ++i) {
|
||||
TransactionData transactionData = unconfirmedTransactions.get(i);
|
||||
Iterator<TransactionData> unconfirmedTransactionsIterator = unconfirmedTransactions.iterator();
|
||||
final long newBlockTimestamp = newBlock.getBlockData().getTimestamp();
|
||||
while (unconfirmedTransactionsIterator.hasNext()) {
|
||||
TransactionData transactionData = unconfirmedTransactionsIterator.next();
|
||||
|
||||
// Ignore transactions that have timestamp later than block's timestamp (not yet valid)
|
||||
if (transactionData.getTimestamp() > newBlock.getBlockData().getTimestamp()) {
|
||||
unconfirmedTransactions.remove(i);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
|
||||
Transaction transaction = Transaction.fromData(repository, transactionData);
|
||||
|
||||
// Ignore transactions that have expired before this block - they will be cleaned up later
|
||||
if (transaction.getDeadline() <= newBlock.getBlockData().getTimestamp()) {
|
||||
unconfirmedTransactions.remove(i);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
if (transactionData.getTimestamp() > newBlockTimestamp || Transaction.getDeadline(transactionData) <= newBlockTimestamp)
|
||||
unconfirmedTransactionsIterator.remove();
|
||||
}
|
||||
|
||||
// Sign to create block's signature, needed by Block.isValid()
|
||||
@ -324,7 +316,7 @@ public class BlockGenerator extends Thread {
|
||||
// If newBlock is no longer valid then we can't use transaction
|
||||
ValidationResult validationResult = newBlock.isValid();
|
||||
if (validationResult != ValidationResult.OK) {
|
||||
LOGGER.debug("Skipping invalid transaction " + Base58.encode(transactionData.getSignature()) + " during block generation");
|
||||
LOGGER.debug(() -> String.format("Skipping invalid transaction %s during block generation", Base58.encode(transactionData.getSignature())));
|
||||
newBlock.deleteTransaction(transactionData);
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class GenesisBlock extends Block {
|
||||
}
|
||||
|
||||
// Properties
|
||||
private static BlockData blockData;
|
||||
private static BlockData genesisBlockData;
|
||||
private static List<TransactionData> transactionsData;
|
||||
private static List<AssetData> initialAssets;
|
||||
|
||||
@ -65,7 +65,7 @@ public class GenesisBlock extends Block {
|
||||
}
|
||||
|
||||
public static GenesisBlock getInstance(Repository repository) throws DataException {
|
||||
return new GenesisBlock(repository, blockData, transactionsData);
|
||||
return new GenesisBlock(repository, genesisBlockData, transactionsData);
|
||||
}
|
||||
|
||||
// Construction from JSON
|
||||
@ -73,7 +73,7 @@ public class GenesisBlock extends Block {
|
||||
/** Construct block data from blockchain config */
|
||||
public static void newInstance(GenesisInfo info) {
|
||||
// Should be safe to make this call as BlockChain's instance is set
|
||||
// so we won't be blocked trying to re-enter synchronzied Settings.getInstance()
|
||||
// so we won't be blocked trying to re-enter synchronized Settings.getInstance()
|
||||
BlockChain blockchain = BlockChain.getInstance();
|
||||
|
||||
// Timestamp of zero means "now" but only valid for test nets!
|
||||
@ -87,7 +87,7 @@ public class GenesisBlock extends Block {
|
||||
info.timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
transactionsData = new ArrayList<TransactionData>(Arrays.asList(info.transactions));
|
||||
transactionsData = new ArrayList<>(Arrays.asList(info.transactions));
|
||||
|
||||
// Add default values to transactions
|
||||
transactionsData.stream().forEach(transactionData -> {
|
||||
@ -133,7 +133,7 @@ public class GenesisBlock extends Block {
|
||||
int atCount = 0;
|
||||
BigDecimal atFees = BigDecimal.ZERO.setScale(8);
|
||||
|
||||
blockData = new BlockData(info.version, reference, transactionCount, totalFees, transactionsSignature, height, info.timestamp,
|
||||
genesisBlockData = new BlockData(info.version, reference, transactionCount, totalFees, transactionsSignature, height, info.timestamp,
|
||||
generatorPublicKey, generatorSignature, atCount, atFees);
|
||||
}
|
||||
|
||||
@ -246,14 +246,14 @@ public class GenesisBlock extends Block {
|
||||
|
||||
@Override
|
||||
public boolean isSignatureValid() {
|
||||
byte[] signature = calcSignature(this.getBlockData());
|
||||
byte[] signature = calcSignature(this.blockData);
|
||||
|
||||
// Validate block signature
|
||||
if (!Arrays.equals(signature, this.getBlockData().getGeneratorSignature()))
|
||||
if (!Arrays.equals(signature, this.blockData.getGeneratorSignature()))
|
||||
return false;
|
||||
|
||||
// Validate transactions signature
|
||||
if (!Arrays.equals(signature, this.getBlockData().getTransactionsSignature()))
|
||||
if (!Arrays.equals(signature, this.blockData.getTransactionsSignature()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -275,10 +275,10 @@ public class GenesisBlock extends Block {
|
||||
|
||||
@Override
|
||||
public void process() throws DataException {
|
||||
LOGGER.info(String.format("Using genesis block timestamp of %d", blockData.getTimestamp()));
|
||||
LOGGER.info(String.format("Using genesis block timestamp of %d", this.blockData.getTimestamp()));
|
||||
|
||||
// If we're a version 1 genesis block, create assets now
|
||||
if (blockData.getVersion() == 1)
|
||||
if (this.blockData.getVersion() == 1)
|
||||
for (AssetData assetData : initialAssets)
|
||||
repository.getAssetRepository().save(assetData);
|
||||
|
||||
|
@ -6,7 +6,7 @@ import com.google.common.hash.HashCode;
|
||||
@SuppressWarnings("deprecation")
|
||||
public class brokenmd160 {
|
||||
|
||||
public static void main(String args[]) {
|
||||
public static void main(String[] args) {
|
||||
if (args.length == 0) {
|
||||
System.err.println("usage: broken-md160 <hex>\noutputs: hex");
|
||||
System.exit(1);
|
||||
|
@ -64,7 +64,7 @@ public class ArbitraryDataManager extends Thread {
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
// Fall-through to exit thread...
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ public class ArbitraryDataManager extends Thread {
|
||||
private boolean hasLocalData(final Repository repository, final byte[] signature) {
|
||||
try {
|
||||
TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature);
|
||||
if (transactionData == null || !(transactionData instanceof ArbitraryTransactionData))
|
||||
if (!(transactionData instanceof ArbitraryTransactionData))
|
||||
return true;
|
||||
|
||||
ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, transactionData);
|
||||
|
@ -39,7 +39,7 @@ public class AutoUpdate extends Thread {
|
||||
public static final String NEW_JAR_FILENAME = "new-" + JAR_FILENAME;
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(AutoUpdate.class);
|
||||
private static final long CHECK_INTERVAL = 5 * 60 * 1000; // ms
|
||||
private static final long CHECK_INTERVAL = 5 * 60 * 1000L; // ms
|
||||
|
||||
private static final int DEV_GROUP_ID = 1;
|
||||
private static final int UPDATE_SERVICE = 1;
|
||||
@ -65,6 +65,7 @@ public class AutoUpdate extends Thread {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Thread.currentThread().setName("Auto-update");
|
||||
|
||||
@ -94,7 +95,7 @@ public class AutoUpdate extends Thread {
|
||||
continue;
|
||||
|
||||
TransactionData transactionData = repository.getTransactionRepository().fromSignature(signatures.get(0));
|
||||
if (transactionData == null || !(transactionData instanceof ArbitraryTransactionData))
|
||||
if (!(transactionData instanceof ArbitraryTransactionData))
|
||||
continue;
|
||||
|
||||
// Transaction needs to be newer than this build
|
||||
|
@ -97,21 +97,21 @@ public class Controller extends Thread {
|
||||
public static final String VERSION_PREFIX = "qora-core-";
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(Controller.class);
|
||||
private static final long MISBEHAVIOUR_COOLOFF = 10 * 60 * 1000; // ms
|
||||
private static final long MISBEHAVIOUR_COOLOFF = 10 * 60 * 1000L; // ms
|
||||
private static final int MAX_BLOCKCHAIN_TIP_AGE = 5; // blocks
|
||||
private static final Object shutdownLock = new Object();
|
||||
private static final String repositoryUrlTemplate = "jdbc:hsqldb:file:%s/blockchain;create=true;hsqldb.full_log_replay=true";
|
||||
private static final long ARBITRARY_REQUEST_TIMEOUT = 5 * 1000; // ms
|
||||
private static final long REPOSITORY_BACKUP_PERIOD = 123 * 60 * 1000; // ms
|
||||
private static final long NTP_PRE_SYNC_CHECK_PERIOD = 5 * 1000; // ms
|
||||
private static final long NTP_POST_SYNC_CHECK_PERIOD = 5 * 60 * 1000; // ms
|
||||
private static final long DELETE_EXPIRED_INTERVAL = 5 * 60 * 1000; // ms
|
||||
private static final long ARBITRARY_REQUEST_TIMEOUT = 5 * 1000L; // ms
|
||||
private static final long REPOSITORY_BACKUP_PERIOD = 123 * 60 * 1000L; // ms
|
||||
private static final long NTP_PRE_SYNC_CHECK_PERIOD = 5 * 1000L; // ms
|
||||
private static final long NTP_POST_SYNC_CHECK_PERIOD = 5 * 60 * 1000L; // ms
|
||||
private static final long DELETE_EXPIRED_INTERVAL = 5 * 60 * 1000L; // ms
|
||||
|
||||
// To do with online accounts list
|
||||
private static final long ONLINE_ACCOUNTS_TASKS_INTERVAL = 10 * 1000; // ms
|
||||
private static final long ONLINE_ACCOUNTS_BROADCAST_INTERVAL = 1 * 60 * 1000; // ms
|
||||
private static final long ONLINE_TIMESTAMP_MODULUS = 5 * 60 * 1000;
|
||||
private static final long LAST_SEEN_EXPIRY_PERIOD = (ONLINE_TIMESTAMP_MODULUS * 2) + (1 * 60 * 1000);
|
||||
private static final long ONLINE_ACCOUNTS_TASKS_INTERVAL = 10 * 1000L; // ms
|
||||
private static final long ONLINE_ACCOUNTS_BROADCAST_INTERVAL = 1 * 60 * 1000L; // ms
|
||||
private static final long ONLINE_TIMESTAMP_MODULUS = 5 * 60 * 1000L;
|
||||
private static final long LAST_SEEN_EXPIRY_PERIOD = (ONLINE_TIMESTAMP_MODULUS * 2) + (1 * 60 * 1000L);
|
||||
|
||||
private static volatile boolean isStopping = false;
|
||||
private static BlockGenerator blockGenerator = null;
|
||||
@ -170,18 +170,18 @@ public class Controller extends Thread {
|
||||
throw new RuntimeException("Can't read build.properties resource", e);
|
||||
}
|
||||
|
||||
String buildTimestamp = properties.getProperty("build.timestamp");
|
||||
if (buildTimestamp == null)
|
||||
String buildTimestampProperty = properties.getProperty("build.timestamp");
|
||||
if (buildTimestampProperty == null)
|
||||
throw new RuntimeException("Can't read build.timestamp from build.properties resource");
|
||||
|
||||
this.buildTimestamp = LocalDateTime.parse(buildTimestamp, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssX")).toEpochSecond(ZoneOffset.UTC);
|
||||
LOGGER.info(String.format("Build timestamp: %s", buildTimestamp));
|
||||
this.buildTimestamp = LocalDateTime.parse(buildTimestampProperty, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssX")).toEpochSecond(ZoneOffset.UTC);
|
||||
LOGGER.info(String.format("Build timestamp: %s", buildTimestampProperty));
|
||||
|
||||
String buildVersion = properties.getProperty("build.version");
|
||||
if (buildVersion == null)
|
||||
String buildVersionProperty = properties.getProperty("build.version");
|
||||
if (buildVersionProperty == null)
|
||||
throw new RuntimeException("Can't read build.version from build.properties resource");
|
||||
|
||||
this.buildVersion = VERSION_PREFIX + buildVersion;
|
||||
this.buildVersion = VERSION_PREFIX + buildVersionProperty;
|
||||
LOGGER.info(String.format("Build version: %s", this.buildVersion));
|
||||
}
|
||||
|
||||
@ -231,7 +231,7 @@ public class Controller extends Thread {
|
||||
|
||||
// Entry point
|
||||
|
||||
public static void main(String args[]) {
|
||||
public static void main(String[] args) {
|
||||
LOGGER.info("Starting up...");
|
||||
|
||||
// Potential GUI startup with splash screen, etc.
|
||||
@ -282,7 +282,7 @@ public class Controller extends Thread {
|
||||
LOGGER.info("Starting controller");
|
||||
Controller.getInstance().start();
|
||||
|
||||
LOGGER.info("Starting networking on port " + Settings.getInstance().getListenPort());
|
||||
LOGGER.info(String.format("Starting networking on port %d", Settings.getInstance().getListenPort()));
|
||||
try {
|
||||
Network network = Network.getInstance();
|
||||
network.start();
|
||||
@ -312,7 +312,7 @@ public class Controller extends Thread {
|
||||
LOGGER.info("Starting auto-update");
|
||||
AutoUpdate.getInstance().start();
|
||||
|
||||
LOGGER.info("Starting API on port " + Settings.getInstance().getApiPort());
|
||||
LOGGER.info(String.format("Starting API on port %d", Settings.getInstance().getApiPort()));
|
||||
try {
|
||||
ApiService apiService = ApiService.getInstance();
|
||||
apiService.start();
|
||||
@ -321,7 +321,7 @@ public class Controller extends Thread {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
LOGGER.info("Starting node management UI on port " + Settings.getInstance().getUiPort());
|
||||
LOGGER.info(String.format("Starting node management UI on port %d", Settings.getInstance().getUiPort()));
|
||||
try {
|
||||
UiService uiService = UiService.getInstance();
|
||||
uiService.start();
|
||||
@ -335,7 +335,7 @@ public class Controller extends Thread {
|
||||
}
|
||||
|
||||
/** Called by AdvancedInstaller's launch EXE in single-instance mode, when an instance is already running. */
|
||||
public static void secondaryMain(String args[]) {
|
||||
public static void secondaryMain(String[] args) {
|
||||
// Return as we don't want to run more than one instance
|
||||
}
|
||||
|
||||
@ -670,7 +670,7 @@ public class Controller extends Thread {
|
||||
network.broadcast(peer -> network.buildHeightMessage(peer, latestBlockData));
|
||||
|
||||
// Send (if outbound) / Request unconfirmed transaction signatures
|
||||
network.broadcast(peer -> network.buildGetUnconfirmedTransactionsMessage(peer));
|
||||
network.broadcast(network::buildGetUnconfirmedTransactionsMessage);
|
||||
}
|
||||
|
||||
public void onGenerationPossibleChange(boolean isGenerationPossible) {
|
||||
@ -1002,7 +1002,7 @@ public class Controller extends Thread {
|
||||
// Fetch actual transaction data from peer
|
||||
Message getTransactionMessage = new GetTransactionMessage(signature);
|
||||
Message responseMessage = peer.getResponse(getTransactionMessage);
|
||||
if (responseMessage == null || !(responseMessage instanceof TransactionMessage)) {
|
||||
if (!(responseMessage instanceof TransactionMessage)) {
|
||||
// Maybe peer no longer has this transaction
|
||||
LOGGER.trace(() -> String.format("Peer %s didn't send transaction %s", peer, Base58.encode(signature)));
|
||||
continue;
|
||||
@ -1158,7 +1158,7 @@ public class Controller extends Thread {
|
||||
// Check transaction exists and payload hash is correct
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature);
|
||||
if (transactionData == null || !(transactionData instanceof ArbitraryTransactionData))
|
||||
if (!(transactionData instanceof ArbitraryTransactionData))
|
||||
break;
|
||||
|
||||
ArbitraryTransactionData arbitraryTransactionData = (ArbitraryTransactionData) transactionData;
|
||||
@ -1231,10 +1231,10 @@ public class Controller extends Thread {
|
||||
case ONLINE_ACCOUNTS: {
|
||||
OnlineAccountsMessage onlineAccountsMessage = (OnlineAccountsMessage) message;
|
||||
|
||||
List<OnlineAccountData> onlineAccounts = onlineAccountsMessage.getOnlineAccounts();
|
||||
LOGGER.trace(() -> String.format("Received %d online accounts from %s", onlineAccounts.size(), peer));
|
||||
List<OnlineAccountData> peersOnlineAccounts = onlineAccountsMessage.getOnlineAccounts();
|
||||
LOGGER.trace(() -> String.format("Received %d online accounts from %s", peersOnlineAccounts.size(), peer));
|
||||
|
||||
for (OnlineAccountData onlineAccountData : onlineAccounts)
|
||||
for (OnlineAccountData onlineAccountData : peersOnlineAccounts)
|
||||
this.verifyAndAddAccount(onlineAccountData);
|
||||
|
||||
break;
|
||||
@ -1309,7 +1309,7 @@ public class Controller extends Thread {
|
||||
synchronized (this.onlineAccounts) {
|
||||
message = new GetOnlineAccountsMessage(this.onlineAccounts);
|
||||
}
|
||||
Network.getInstance().broadcast((peer) -> message);
|
||||
Network.getInstance().broadcast(peer -> message);
|
||||
}
|
||||
|
||||
// Refresh our online accounts signatures?
|
||||
@ -1341,7 +1341,7 @@ public class Controller extends Thread {
|
||||
iterator.remove();
|
||||
}
|
||||
} catch (DataException e) {
|
||||
LOGGER.warn("Repository issue trying to fetch forging accounts: " + e.getMessage());
|
||||
LOGGER.warn(String.format("Repository issue trying to fetch forging accounts: %s", e.getMessage()));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1389,7 +1389,7 @@ public class Controller extends Thread {
|
||||
return;
|
||||
|
||||
Message message = new OnlineAccountsMessage(ourOnlineAccounts);
|
||||
Network.getInstance().broadcast((peer) -> message);
|
||||
Network.getInstance().broadcast(peer -> message);
|
||||
|
||||
LOGGER.trace(()-> String.format("Broadcasted %d online account%s with timestamp %d", ourOnlineAccounts.size(), (ourOnlineAccounts.size() != 1 ? "s" : ""), onlineAccountsTimestamp));
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ public class Synchronizer {
|
||||
--ourHeight;
|
||||
}
|
||||
|
||||
LOGGER.debug(String.format("Orphaned blocks back to height %d, sig %.8s - fetching blocks from peer", commonBlockHeight, commonBlockSig58, peer));
|
||||
LOGGER.debug(String.format("Orphaned blocks back to height %d, sig %.8s - fetching blocks from peer %s", commonBlockHeight, commonBlockSig58, peer));
|
||||
} else {
|
||||
LOGGER.debug(String.format("Fetching new blocks from peer %s", peer));
|
||||
}
|
||||
@ -224,7 +224,7 @@ public class Synchronizer {
|
||||
int maxBatchHeight = commonBlockHeight + SYNC_BATCH_SIZE;
|
||||
|
||||
// Convert any block summaries from above into signatures to request from peer
|
||||
List<byte[]> peerBlockSignatures = peerBlockSummaries.stream().map(blockSummaryData -> blockSummaryData.getSignature()).collect(Collectors.toList());
|
||||
List<byte[]> peerBlockSignatures = peerBlockSummaries.stream().map(BlockSummaryData::getSignature).collect(Collectors.toList());
|
||||
|
||||
while (ourHeight < peerHeight && ourHeight < maxBatchHeight) {
|
||||
// Do we need more signatures?
|
||||
|
@ -196,12 +196,9 @@ public class BTC {
|
||||
peerGroup.start();
|
||||
}
|
||||
|
||||
public static BTC getInstance() {
|
||||
if (instance == null)
|
||||
synchronized (instanceLock) {
|
||||
public static synchronized BTC getInstance() {
|
||||
if (instance == null)
|
||||
instance = new BTC();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ package org.qora.crypto;
|
||||
* <b>DO NOT USE in future code</b> as this implementation is BROKEN and returns incorrect digests for some inputs.
|
||||
* <p>
|
||||
* It is only "grand-fathered" here to produce correct QORA addresses.
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
@Deprecated
|
||||
public class BrokenMD160 {
|
||||
|
||||
|
@ -2,8 +2,6 @@ package org.qora.data.voting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.qora.data.voting.PollOptionData;
|
||||
|
||||
public class PollData {
|
||||
|
||||
// Properties
|
||||
|
@ -33,13 +33,13 @@ public enum BIP39WordList {
|
||||
|
||||
try (InputStream inputStream = loader.getResourceAsStream("BIP39/wordlist_" + lang + ".txt")) {
|
||||
if (inputStream == null) {
|
||||
LOGGER.warn("Can't locate '" + lang + "' BIP39 wordlist");
|
||||
LOGGER.warn(String.format("Can't locate '%s' BIP39 wordlist", lang));
|
||||
return null;
|
||||
}
|
||||
|
||||
wordList = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.toList());
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("Error reading '" + lang + "' BIP39 wordlist", e);
|
||||
LOGGER.warn(String.format("Error reading '%s' BIP39 wordlist", lang), e);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ public class Group {
|
||||
public final int value;
|
||||
public final boolean isPercentage;
|
||||
|
||||
private final static Map<Integer, ApprovalThreshold> map = stream(ApprovalThreshold.values())
|
||||
private static final Map<Integer, ApprovalThreshold> map = stream(ApprovalThreshold.values())
|
||||
.collect(toMap(threshold -> threshold.value, threshold -> threshold));
|
||||
|
||||
ApprovalThreshold(int value, boolean isPercentage) {
|
||||
|
@ -41,7 +41,7 @@ public class SplashFrame {
|
||||
private SplashFrame() {
|
||||
this.splashDialog = new JDialog();
|
||||
|
||||
List<Image> icons = new ArrayList<Image>();
|
||||
List<Image> icons = new ArrayList<>();
|
||||
icons.add(Gui.loadImage("icons/icon16.png"));
|
||||
icons.add(Gui.loadImage("icons/icon32.png"));
|
||||
icons.add(Gui.loadImage("icons/icon64.png"));
|
||||
|
@ -4,8 +4,6 @@ import java.awt.AWTError;
|
||||
import java.awt.AWTException;
|
||||
import java.awt.SystemTray;
|
||||
import java.awt.TrayIcon;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowEvent;
|
||||
@ -37,7 +35,7 @@ import org.qora.utils.URLViewer;
|
||||
|
||||
public class SysTray {
|
||||
|
||||
protected static final Logger LOGGER = LogManager.getLogger(SplashFrame.class);
|
||||
protected static final Logger LOGGER = LogManager.getLogger(SysTray.class);
|
||||
private static final String NTP_SCRIPT = "ntpcfg.bat";
|
||||
|
||||
private static SysTray instance;
|
||||
@ -147,57 +145,45 @@ public class SysTray {
|
||||
});
|
||||
|
||||
JMenuItem openUi = new JMenuItem(Translator.INSTANCE.translate("SysTray", "OPEN_NODE_UI"));
|
||||
openUi.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
openUi.addActionListener(actionEvent -> {
|
||||
destroyHiddenDialog();
|
||||
|
||||
try {
|
||||
URLViewer.openWebpage(new URL("http://localhost:" + Settings.getInstance().getUiPort()));
|
||||
} catch (Exception e1) {
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Unable to open node UI in browser");
|
||||
}
|
||||
}
|
||||
});
|
||||
menu.add(openUi);
|
||||
|
||||
JMenuItem openTimeCheck = new JMenuItem(Translator.INSTANCE.translate("SysTray", "CHECK_TIME_ACCURACY"));
|
||||
openTimeCheck.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
openTimeCheck.addActionListener(actionEvent -> {
|
||||
destroyHiddenDialog();
|
||||
|
||||
try {
|
||||
URLViewer.openWebpage(new URL("https://time.is"));
|
||||
} catch (Exception e1) {
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Unable to open time-check website in browser");
|
||||
}
|
||||
}
|
||||
});
|
||||
menu.add(openTimeCheck);
|
||||
|
||||
// Only for Windows users
|
||||
if (System.getProperty("os.name").toLowerCase().contains("win")) {
|
||||
JMenuItem syncTime = new JMenuItem(Translator.INSTANCE.translate("SysTray", "SYNCHRONIZE_CLOCK"));
|
||||
syncTime.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
syncTime.addActionListener(actionEvent -> {
|
||||
destroyHiddenDialog();
|
||||
|
||||
new SynchronizeWorker().execute();
|
||||
}
|
||||
});
|
||||
menu.add(syncTime);
|
||||
}
|
||||
|
||||
JMenuItem exit = new JMenuItem(Translator.INSTANCE.translate("SysTray", "EXIT"));
|
||||
exit.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
exit.addActionListener(actionEvent -> {
|
||||
destroyHiddenDialog();
|
||||
|
||||
new ClosingWorker().execute();
|
||||
}
|
||||
});
|
||||
menu.add(exit);
|
||||
|
||||
|
@ -44,7 +44,7 @@ public class mintsim {
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
public static void main(String[] args) {
|
||||
if (args.length < 2 || (args.length % 2) != 0) {
|
||||
System.err.println("usage: mintsim <tier1-min-blocks> <number-tier1-accounts> [<tier2-min-blocks> <max-tier2-per-tier1> [...]]");
|
||||
System.exit(1);
|
||||
@ -53,8 +53,8 @@ public class mintsim {
|
||||
try {
|
||||
int argIndex = 0;
|
||||
do {
|
||||
int minBlocks = Integer.valueOf(args[argIndex++]);
|
||||
int maxAccounts = Integer.valueOf(args[argIndex++]);
|
||||
int minBlocks = Integer.parseInt(args[argIndex++]);
|
||||
int maxAccounts = Integer.parseInt(args[argIndex++]);
|
||||
|
||||
tiers.add(new TierInfo(maxAccounts, minBlocks));
|
||||
} while (argIndex < args.length);
|
||||
|
@ -201,7 +201,7 @@ public enum Handshake {
|
||||
private static final Logger LOGGER = LogManager.getLogger(Handshake.class);
|
||||
|
||||
/** Maximum allowed difference between peer's reported timestamp and when they connected, in milliseconds. */
|
||||
private static final long MAX_TIMESTAMP_DELTA = 30 * 1000; // ms
|
||||
private static final long MAX_TIMESTAMP_DELTA = 30 * 1000L; // ms
|
||||
|
||||
public final MessageType expectedMessageType;
|
||||
|
||||
|
@ -59,22 +59,22 @@ import org.qora.utils.ExecuteProduceConsume;
|
||||
import org.qora.utils.NTP;
|
||||
|
||||
// For managing peers
|
||||
public class Network extends Thread {
|
||||
public class Network {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(Network.class);
|
||||
private static Network instance;
|
||||
|
||||
private static final int LISTEN_BACKLOG = 10;
|
||||
/** How long before retrying after a connection failure, in milliseconds. */
|
||||
private static final int CONNECT_FAILURE_BACKOFF = 5 * 60 * 1000; // ms
|
||||
private static final long CONNECT_FAILURE_BACKOFF = 5 * 60 * 1000L; // ms
|
||||
/** How long between informational broadcasts to all connected peers, in milliseconds. */
|
||||
private static final int BROADCAST_INTERVAL = 60 * 1000; // ms
|
||||
private static final long BROADCAST_INTERVAL = 60 * 1000L; // ms
|
||||
/** Maximum time since last successful connection for peer info to be propagated, in milliseconds. */
|
||||
private static final long RECENT_CONNECTION_THRESHOLD = 24 * 60 * 60 * 1000; // ms
|
||||
private static final long RECENT_CONNECTION_THRESHOLD = 24 * 60 * 60 * 1000L; // ms
|
||||
/** Maximum time since last connection attempt before a peer is potentially considered "old", in milliseconds. */
|
||||
private static final long OLD_PEER_ATTEMPTED_PERIOD = 24 * 60 * 60 * 1000; // ms
|
||||
private static final long OLD_PEER_ATTEMPTED_PERIOD = 24 * 60 * 60 * 1000L; // ms
|
||||
/** Maximum time since last successful connection before a peer is potentially considered "old", in milliseconds. */
|
||||
private static final long OLD_PEER_CONNECTION_PERIOD = 7 * 24 * 60 * 60 * 1000; // ms
|
||||
private static final long OLD_PEER_CONNECTION_PERIOD = 7 * 24 * 60 * 60 * 1000L; // ms
|
||||
/** Maximum time allowed for handshake to complete, in milliseconds. */
|
||||
private static final long HANDSHAKE_TIMEOUT = 60 * 1000; // ms
|
||||
|
||||
@ -135,7 +135,7 @@ public class Network extends Thread {
|
||||
serverChannel.bind(endpoint, LISTEN_BACKLOG);
|
||||
serverChannel.register(channelSelector, SelectionKey.OP_ACCEPT);
|
||||
} catch (UnknownHostException e) {
|
||||
LOGGER.error("Can't bind listen socket to address " + Settings.getInstance().getBindAddress());
|
||||
LOGGER.error(String.format("Can't bind listen socket to address %s", Settings.getInstance().getBindAddress()));
|
||||
throw new RuntimeException("Can't bind listen socket to address");
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Can't create listen socket");
|
||||
@ -167,7 +167,9 @@ public class Network extends Thread {
|
||||
10L, TimeUnit.SECONDS,
|
||||
new SynchronousQueue<Runnable>());
|
||||
networkEPC = new NetworkProcessor(networkExecutor);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
// Start up first networking thread
|
||||
networkEPC.start();
|
||||
}
|
||||
@ -244,14 +246,9 @@ public class Network extends Thread {
|
||||
|
||||
/** Returns list of peers we connected to that have completed handshaking. */
|
||||
public List<Peer> getOutboundHandshakedPeers() {
|
||||
List<Peer> peers = new ArrayList<>();
|
||||
|
||||
synchronized (this.connectedPeers) {
|
||||
peers = this.connectedPeers.stream().filter(peer -> peer.isOutbound() && peer.getHandshakeStatus() == Handshake.COMPLETED)
|
||||
.collect(Collectors.toList());
|
||||
return this.connectedPeers.stream().filter(peer -> peer.isOutbound() && peer.getHandshakeStatus() == Handshake.COMPLETED).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return peers;
|
||||
}
|
||||
|
||||
/** Returns Peer with inbound connection and matching ID, or null if none found. */
|
||||
@ -359,9 +356,7 @@ public class Network extends Thread {
|
||||
|
||||
LOGGER.trace(() -> String.format("Network thread %s encountered I/O error: %s", Thread.currentThread().getId(), e.getMessage()), e);
|
||||
peer.disconnect("I/O error");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -664,7 +659,7 @@ public class Network extends Thread {
|
||||
if (socketChannel == null)
|
||||
return;
|
||||
|
||||
if (this.isInterrupted())
|
||||
if (Thread.currentThread().isInterrupted())
|
||||
return;
|
||||
|
||||
synchronized (this.connectedPeers) {
|
||||
@ -839,7 +834,7 @@ public class Network extends Thread {
|
||||
// If inbound peer, use listen port and socket address to recreate first entry
|
||||
if (!peer.isOutbound()) {
|
||||
PeerAddress sendingPeerAddress = PeerAddress.fromString(peer.getPeerData().getAddress().getHost() + ":" + peerPort);
|
||||
LOGGER.trace("PEERS_V2 sending peer's listen address: " + sendingPeerAddress.toString());
|
||||
LOGGER.trace(() -> String.format("PEERS_V2 sending peer's listen address: %s", sendingPeerAddress.toString()));
|
||||
peerV2Addresses.add(0, sendingPeerAddress);
|
||||
}
|
||||
|
||||
@ -1100,10 +1095,7 @@ public class Network extends Thread {
|
||||
List<PeerData> knownPeers = repository.getNetworkRepository().getAllPeers();
|
||||
|
||||
// Filter out duplicates
|
||||
Predicate<PeerAddress> isKnownAddress = peerAddress -> {
|
||||
return knownPeers.stream().anyMatch(knownPeerData -> knownPeerData.getAddress().equals(peerAddress));
|
||||
};
|
||||
|
||||
Predicate<PeerAddress> isKnownAddress = peerAddress -> knownPeers.stream().anyMatch(knownPeerData -> knownPeerData.getAddress().equals(peerAddress));
|
||||
peerAddresses.removeIf(isKnownAddress);
|
||||
|
||||
repository.discardChanges();
|
||||
@ -1126,6 +1118,8 @@ public class Network extends Thread {
|
||||
|
||||
public void broadcast(Function<Peer, Message> peerMessageBuilder) {
|
||||
class Broadcaster implements Runnable {
|
||||
private final Random random = new Random();
|
||||
|
||||
private List<Peer> targetPeers;
|
||||
private Function<Peer, Message> peerMessageBuilder;
|
||||
|
||||
@ -1138,12 +1132,10 @@ public class Network extends Thread {
|
||||
public void run() {
|
||||
Thread.currentThread().setName("Network Broadcast");
|
||||
|
||||
Random random = new Random();
|
||||
|
||||
for (Peer peer : targetPeers) {
|
||||
// Very short sleep to reduce strain, improve multi-threading and catch interrupts
|
||||
try {
|
||||
Thread.sleep(random.nextInt(20) + 20);
|
||||
Thread.sleep(random.nextInt(20) + 20L);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ public class Peer {
|
||||
this.socketChannel.configureBlocking(false);
|
||||
this.byteBuffer = ByteBuffer.allocate(Network.getInstance().getMaxMessageSize());
|
||||
this.replyQueues = Collections.synchronizedMap(new HashMap<Integer, BlockingQueue<Message>>());
|
||||
this.pendingMessages = new LinkedBlockingQueue<Message>();
|
||||
this.pendingMessages = new LinkedBlockingQueue<>();
|
||||
}
|
||||
|
||||
public SocketChannel connect() {
|
||||
@ -394,7 +394,7 @@ public class Peer {
|
||||
if (bytesWritten == 0)
|
||||
// Underlying socket's internal buffer probably full,
|
||||
// so wait a short while for bytes to actually be transmitted over the wire
|
||||
Thread.sleep(1L);
|
||||
this.socketChannel.wait(1L);
|
||||
}
|
||||
}
|
||||
} catch (MessageException e) {
|
||||
@ -424,7 +424,7 @@ public class Peer {
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Message getResponse(Message message) throws InterruptedException {
|
||||
BlockingQueue<Message> blockingQueue = new ArrayBlockingQueue<Message>(1);
|
||||
BlockingQueue<Message> blockingQueue = new ArrayBlockingQueue<>(1);
|
||||
|
||||
// Assign random ID to this message
|
||||
int id;
|
||||
@ -443,8 +443,7 @@ public class Peer {
|
||||
}
|
||||
|
||||
try {
|
||||
Message response = blockingQueue.poll(RESPONSE_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
return response;
|
||||
return blockingQueue.poll(RESPONSE_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
} finally {
|
||||
this.replyQueues.remove(id);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public abstract class Message {
|
||||
ONLINE_ACCOUNTS(26);
|
||||
|
||||
public final int value;
|
||||
public final Method fromByteBuffer;
|
||||
public final Method fromByteBufferMethod;
|
||||
|
||||
private static final Map<Integer, MessageType> map = stream(MessageType.values())
|
||||
.collect(toMap(messageType -> messageType.value, messageType -> messageType));
|
||||
@ -88,16 +88,16 @@ public abstract class Message {
|
||||
|
||||
String className = String.join("", classNameParts);
|
||||
|
||||
Method fromByteBuffer;
|
||||
Method method;
|
||||
try {
|
||||
Class<?> subclass = Class.forName(String.join("", Message.class.getPackage().getName(), ".", className, "Message"));
|
||||
|
||||
fromByteBuffer = subclass.getDeclaredMethod("fromByteBuffer", int.class, ByteBuffer.class);
|
||||
method = subclass.getDeclaredMethod("fromByteBuffer", int.class, ByteBuffer.class);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
|
||||
fromByteBuffer = null;
|
||||
method = null;
|
||||
}
|
||||
|
||||
this.fromByteBuffer = fromByteBuffer;
|
||||
this.fromByteBufferMethod = method;
|
||||
}
|
||||
|
||||
public static MessageType valueOf(int value) {
|
||||
@ -105,11 +105,11 @@ public abstract class Message {
|
||||
}
|
||||
|
||||
public Message fromByteBuffer(int id, ByteBuffer byteBuffer) throws MessageException {
|
||||
if (this.fromByteBuffer == null)
|
||||
if (this.fromByteBufferMethod == null)
|
||||
throw new MessageException("Unsupported message type [" + value + "] during conversion from bytes");
|
||||
|
||||
try {
|
||||
return (Message) this.fromByteBuffer.invoke(null, id, byteBuffer);
|
||||
return (Message) this.fromByteBufferMethod.invoke(null, id, byteBuffer);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
if (e.getCause() instanceof BufferUnderflowException)
|
||||
throw new MessageException("Byte data too short for " + name() + " message");
|
||||
|
@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -42,7 +43,7 @@ public class PeersV2Message extends Message {
|
||||
|
||||
byte[] addressBytes = new byte[addressSize & 0xff];
|
||||
byteBuffer.get(addressBytes);
|
||||
String addressString = new String(addressBytes, "UTF-8");
|
||||
String addressString = new String(addressBytes, StandardCharsets.UTF_8);
|
||||
|
||||
try {
|
||||
PeerAddress peerAddress = PeerAddress.fromString(addressString);
|
||||
@ -63,10 +64,10 @@ public class PeersV2Message extends Message {
|
||||
List<byte[]> addresses = new ArrayList<>();
|
||||
|
||||
// First entry represents sending node but contains only port number with empty address.
|
||||
addresses.add(new String("0.0.0.0:" + Settings.getInstance().getListenPort()).getBytes("UTF-8"));
|
||||
addresses.add(("0.0.0.0:" + Settings.getInstance().getListenPort()).getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
for (PeerAddress peerAddress : this.peerAddresses)
|
||||
addresses.add(peerAddress.toString().getBytes("UTF-8"));
|
||||
addresses.add(peerAddress.toString().getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
// We can't send addresses that are longer than 255 bytes as length itself is encoded in one byte.
|
||||
addresses.removeIf(addressString -> addressString.length > 255);
|
||||
|
@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.qora.utils.Serialization;
|
||||
|
||||
@ -44,7 +45,7 @@ public class VersionMessage extends Message {
|
||||
byte[] versionBytes = new byte[versionStringLength];
|
||||
bytes.get(versionBytes);
|
||||
|
||||
String versionString = new String(versionBytes, "UTF-8");
|
||||
String versionString = new String(versionBytes, StandardCharsets.UTF_8);
|
||||
|
||||
return new VersionMessage(id, buildTimestamp, versionString);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public class Payment {
|
||||
return ValidationResult.NEGATIVE_FEE;
|
||||
|
||||
// Total up payment amounts by assetId
|
||||
Map<Long, BigDecimal> amountsByAssetId = new HashMap<Long, BigDecimal>();
|
||||
Map<Long, BigDecimal> amountsByAssetId = new HashMap<>();
|
||||
// Add transaction fee to start with
|
||||
amountsByAssetId.put(Asset.QORT, fee);
|
||||
|
||||
|
@ -188,7 +188,7 @@ public class HSQLDBATRepository implements ATRepository {
|
||||
|
||||
@Override
|
||||
public List<ATStateData> getBlockATStatesAtHeight(int height) throws DataException {
|
||||
List<ATStateData> atStates = new ArrayList<ATStateData>();
|
||||
List<ATStateData> atStates = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT AT_address, state_hash, fees FROM ATStates WHERE height = ? ORDER BY creation ASC",
|
||||
height)) {
|
||||
|
@ -321,7 +321,7 @@ public class HSQLDBAccountRepository implements AccountRepository {
|
||||
}
|
||||
|
||||
// For no-address queries, or unless specifically requested, only return accounts with non-zero balance
|
||||
if (addresses.isEmpty() || (excludeZero != null && excludeZero == true)) {
|
||||
if (addresses.isEmpty() || (excludeZero != null && excludeZero)) {
|
||||
sql.append(assetIds.isEmpty() ? " WHERE " : " AND ");
|
||||
sql.append("balance != 0 ");
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
||||
|
||||
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
|
||||
|
||||
List<AssetData> assets = new ArrayList<AssetData>();
|
||||
List<AssetData> assets = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
|
||||
if (resultSet == null)
|
||||
@ -228,7 +228,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
||||
@Override
|
||||
public List<OrderData> getOpenOrders(long haveAssetId, long wantAssetId, Integer limit, Integer offset,
|
||||
Boolean reverse) throws DataException {
|
||||
List<OrderData> orders = new ArrayList<OrderData>();
|
||||
List<OrderData> orders = new ArrayList<>();
|
||||
|
||||
// Cache have & want asset names for later use, which also saves a table join
|
||||
AssetData haveAssetData = this.fromAssetId(haveAssetId);
|
||||
@ -305,7 +305,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
||||
|
||||
sql.append(", ordered");
|
||||
|
||||
List<OrderData> orders = new ArrayList<OrderData>();
|
||||
List<OrderData> orders = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) {
|
||||
if (resultSet == null)
|
||||
@ -336,7 +336,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
||||
@Override
|
||||
public List<OrderData> getAggregatedOpenOrders(long haveAssetId, long wantAssetId, Integer limit, Integer offset,
|
||||
Boolean reverse) throws DataException {
|
||||
List<OrderData> orders = new ArrayList<OrderData>();
|
||||
List<OrderData> orders = new ArrayList<>();
|
||||
|
||||
// Cache have & want asset names for later use, which also saves a table join
|
||||
AssetData haveAssetData = this.fromAssetId(haveAssetId);
|
||||
@ -404,7 +404,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
||||
|
||||
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
|
||||
|
||||
List<OrderData> orders = new ArrayList<OrderData>();
|
||||
List<OrderData> orders = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), publicKey)) {
|
||||
if (resultSet == null)
|
||||
@ -437,7 +437,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
||||
@Override
|
||||
public List<OrderData> getAccountsOrders(byte[] publicKey, long haveAssetId, long wantAssetId, Boolean optIsClosed,
|
||||
Boolean optIsFulfilled, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
List<OrderData> orders = new ArrayList<OrderData>();
|
||||
List<OrderData> orders = new ArrayList<>();
|
||||
|
||||
// Cache have & want asset names for later use, which also saves a table join
|
||||
AssetData haveAssetData = this.fromAssetId(haveAssetId);
|
||||
@ -524,7 +524,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
||||
@Override
|
||||
public List<TradeData> getTrades(long haveAssetId, long wantAssetId, Integer limit, Integer offset, Boolean reverse)
|
||||
throws DataException {
|
||||
List<TradeData> trades = new ArrayList<TradeData>();
|
||||
List<TradeData> trades = new ArrayList<>();
|
||||
|
||||
// Cache have & want asset names for later use, which also saves a table join
|
||||
AssetData haveAssetData = this.fromAssetId(haveAssetId);
|
||||
@ -677,7 +677,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
||||
|
||||
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
|
||||
|
||||
List<TradeData> trades = new ArrayList<TradeData>();
|
||||
List<TradeData> trades = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), orderId)) {
|
||||
if (resultSet == null)
|
||||
|
@ -153,7 +153,7 @@ public class HSQLDBBlockRepository implements BlockRepository {
|
||||
|
||||
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
|
||||
|
||||
List<TransactionData> transactions = new ArrayList<TransactionData>();
|
||||
List<TransactionData> transactions = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), signature)) {
|
||||
if (resultSet == null)
|
||||
|
@ -29,9 +29,11 @@ public class HSQLDBDatabaseUpdates {
|
||||
* @throws SQLException
|
||||
*/
|
||||
private static void incrementDatabaseVersion(Connection connection) throws SQLException {
|
||||
connection.createStatement().execute("UPDATE DatabaseInfo SET version = version + 1");
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
stmt.execute("UPDATE DatabaseInfo SET version = version + 1");
|
||||
connection.commit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch current version of database schema.
|
||||
|
@ -308,9 +308,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
String owner = resultSet.getString(1);
|
||||
|
||||
return owner;
|
||||
return resultSet.getString(1);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch group owner from repository", e);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public class HSQLDBRepository implements Repository {
|
||||
|
||||
this.slowQueryThreshold = Settings.getInstance().getSlowQueryThreshold();
|
||||
if (this.slowQueryThreshold != null)
|
||||
this.sqlStatements = new ArrayList<String>();
|
||||
this.sqlStatements = new ArrayList<>();
|
||||
|
||||
// Find out our session ID
|
||||
try (Statement stmt = this.connection.createStatement()) {
|
||||
@ -237,10 +237,10 @@ public class HSQLDBRepository implements Repository {
|
||||
|
||||
@Override
|
||||
public void backup(boolean quick) throws DataException {
|
||||
// First perform a CHECKPOINT
|
||||
try {
|
||||
if (!quick)
|
||||
this.connection.createStatement().execute("CHECKPOINT DEFRAG");
|
||||
// First perform a CHECKPOINT
|
||||
try (Statement stmt = this.connection.createStatement()) {
|
||||
stmt.execute("CHECKPOINT DEFRAG");
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to prepare repository for backup");
|
||||
}
|
||||
@ -272,8 +272,8 @@ public class HSQLDBRepository implements Repository {
|
||||
}
|
||||
|
||||
// Actually create backup
|
||||
try {
|
||||
this.connection.createStatement().execute("BACKUP DATABASE TO 'backup/' NOT BLOCKING AS FILES");
|
||||
try (Statement stmt = this.connection.createStatement()) {
|
||||
stmt.execute("BACKUP DATABASE TO 'backup/' NOT BLOCKING AS FILES");
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to backup repository");
|
||||
}
|
||||
@ -287,8 +287,7 @@ public class HSQLDBRepository implements Repository {
|
||||
if (!matcher.find())
|
||||
return null;
|
||||
|
||||
String pathname = matcher.group(1);
|
||||
return pathname;
|
||||
return matcher.group(1);
|
||||
}
|
||||
|
||||
private static String buildBackupUrl(String dbPathname) {
|
||||
@ -298,8 +297,7 @@ public class HSQLDBRepository implements Repository {
|
||||
|
||||
// Try to open backup. We need to remove "create=true" and insert "backup" dir before final filename.
|
||||
String backupUrlTemplate = "jdbc:hsqldb:file:%s/backup/%s;create=false;hsqldb.full_log_replay=true";
|
||||
String backupUrl = String.format(backupUrlTemplate, oldRepoDirPath.toString(), oldRepoFilePath.toString());
|
||||
return backupUrl;
|
||||
return String.format(backupUrlTemplate, oldRepoDirPath.toString(), oldRepoFilePath.toString());
|
||||
}
|
||||
|
||||
/* package */ static void attemptRecovery(String connectionUrl) throws DataException {
|
||||
@ -321,11 +319,11 @@ public class HSQLDBRepository implements Repository {
|
||||
.filter(file -> file.getPath().startsWith(dbPathname))
|
||||
.forEach(File::delete);
|
||||
|
||||
try {
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
// Now "backup" the backup back to original repository location (the parent)
|
||||
// NOTE: trailing / is OK because HSQLDB checks for both / and O/S-specific separator
|
||||
// textdb.allow_full_path connection property is required to be able to use '..'
|
||||
connection.createStatement().execute("BACKUP DATABASE TO '../' BLOCKING AS FILES");
|
||||
stmt.execute("BACKUP DATABASE TO '../' BLOCKING AS FILES");
|
||||
} catch (SQLException e) {
|
||||
// We really failed
|
||||
throw new DataException("Failed to recover repository to original location");
|
||||
@ -357,9 +355,7 @@ public class HSQLDBRepository implements Repository {
|
||||
if (this.sqlStatements != null)
|
||||
this.sqlStatements.add(sql);
|
||||
|
||||
PreparedStatement preparedStatement = this.connection.prepareStatement(sql);
|
||||
|
||||
return preparedStatement;
|
||||
return this.connection.prepareStatement(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -594,7 +590,7 @@ public class HSQLDBRepository implements Repository {
|
||||
return e;
|
||||
|
||||
do {
|
||||
long sessionId = resultSet.getLong(1);
|
||||
long systemSessionId = resultSet.getLong(1);
|
||||
boolean inTransaction = resultSet.getBoolean(2);
|
||||
long transactionSize = resultSet.getLong(3);
|
||||
String waitingForThis = resultSet.getString(4);
|
||||
@ -602,7 +598,7 @@ public class HSQLDBRepository implements Repository {
|
||||
String currentStatement = resultSet.getString(6);
|
||||
|
||||
LOGGER.error(String.format("Session %d, %s transaction (size %d), waiting for this '%s', this waiting for '%s', current statement: %s",
|
||||
sessionId, (inTransaction ? "in" : "not in"), transactionSize, waitingForThis, thisWaitingFor, currentStatement));
|
||||
systemSessionId, (inTransaction ? "in" : "not in"), transactionSize, waitingForThis, thisWaitingFor, currentStatement));
|
||||
} while (resultSet.next());
|
||||
} catch (SQLException de) {
|
||||
// Throw original exception instead
|
||||
@ -619,8 +615,10 @@ public class HSQLDBRepository implements Repository {
|
||||
throw new DataException("Unable to check repository status after " + context);
|
||||
|
||||
try (ResultSet resultSet = stmt.getResultSet()) {
|
||||
if (resultSet == null || !resultSet.next())
|
||||
LOGGER.warn("Unable to check repository status after " + context);
|
||||
if (resultSet == null || !resultSet.next()) {
|
||||
LOGGER.warn(String.format("Unable to check repository status after %s", context));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean inTransaction = resultSet.getBoolean(1);
|
||||
int transactionCount = resultSet.getInt(2);
|
||||
|
@ -3,6 +3,7 @@ package org.qora.repository.hsqldb;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@ -31,9 +32,10 @@ public class HSQLDBRepositoryFactory implements RepositoryFactory {
|
||||
|
||||
// Check no-one else is accessing database
|
||||
try (Connection connection = DriverManager.getConnection(this.connectionUrl)) {
|
||||
// We only need to check we can obtain connection. It will be auto-closed.
|
||||
} catch (SQLException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause == null || !(cause instanceof HsqlException))
|
||||
if (!(cause instanceof HsqlException))
|
||||
throw new DataException("Unable to open repository: " + e.getMessage());
|
||||
|
||||
HsqlException he = (HsqlException) cause;
|
||||
@ -84,7 +86,7 @@ public class HSQLDBRepositoryFactory implements RepositoryFactory {
|
||||
|
||||
if (delay > SLOW_CONNECTION_THRESHOLD)
|
||||
// This could be an indication of excessive repository use, or insufficient pool size
|
||||
LOGGER.warn(String.format("Fetching repository connection from pool took %dms (threshold: %dms)"), delay, SLOW_CONNECTION_THRESHOLD);
|
||||
LOGGER.warn(() -> String.format("Fetching repository connection from pool took %dms (threshold: %dms)", delay, SLOW_CONNECTION_THRESHOLD));
|
||||
|
||||
setupConnection(connection);
|
||||
return connection;
|
||||
@ -112,8 +114,9 @@ public class HSQLDBRepositoryFactory implements RepositoryFactory {
|
||||
this.connectionPool.close(0);
|
||||
|
||||
// Now that all connections are closed, create a dedicated connection to shut down repository
|
||||
try (Connection connection = DriverManager.getConnection(this.connectionUrl)) {
|
||||
connection.createStatement().execute("SHUTDOWN");
|
||||
try (Connection connection = DriverManager.getConnection(this.connectionUrl);
|
||||
Statement stmt = connection.createStatement()) {
|
||||
stmt.execute("SHUTDOWN");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Error during repository shutdown", e);
|
||||
|
@ -22,8 +22,8 @@ public class HSQLDBSaver {
|
||||
|
||||
private String table;
|
||||
|
||||
private List<String> columns = new ArrayList<String>();
|
||||
private List<Object> objects = new ArrayList<Object>();
|
||||
private List<String> columns = new ArrayList<>();
|
||||
private List<Object> objects = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Construct a SaveHelper, using SQL Connection and table name.
|
||||
|
@ -41,7 +41,7 @@ public class HSQLDBVotingRepository implements VotingRepository {
|
||||
if (optionsResultSet == null)
|
||||
return null;
|
||||
|
||||
List<PollOptionData> pollOptions = new ArrayList<PollOptionData>();
|
||||
List<PollOptionData> pollOptions = new ArrayList<>();
|
||||
|
||||
// NOTE: do-while because checkedExecute() above has already called rs.next() for us
|
||||
do {
|
||||
@ -112,7 +112,7 @@ public class HSQLDBVotingRepository implements VotingRepository {
|
||||
@Override
|
||||
public List<VoteOnPollData> getVotes(String pollName) throws DataException {
|
||||
String sql = "SELECT voter, option_index FROM PollVotes WHERE poll_name = ?";
|
||||
List<VoteOnPollData> votes = new ArrayList<VoteOnPollData>();
|
||||
List<VoteOnPollData> votes = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, pollName)) {
|
||||
if (resultSet == null)
|
||||
|
@ -65,6 +65,7 @@ public class HSQLDBArbitraryTransactionRepository extends HSQLDBTransactionRepos
|
||||
this.savePayments(transactionData.getSignature(), arbitraryTransactionData.getPayments());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(TransactionData transactionData) throws DataException {
|
||||
ArbitraryTransactionData arbitraryTransactionData = (ArbitraryTransactionData) transactionData;
|
||||
|
||||
|
@ -36,7 +36,7 @@ public class HSQLDBCreatePollTransactionRepository extends HSQLDBTransactionRepo
|
||||
if (optionsResultSet == null)
|
||||
return null;
|
||||
|
||||
List<PollOptionData> pollOptions = new ArrayList<PollOptionData>();
|
||||
List<PollOptionData> pollOptions = new ArrayList<>();
|
||||
|
||||
// NOTE: do-while because checkedExecute() above has already called rs.next() for us
|
||||
do {
|
||||
|
@ -9,7 +9,7 @@ import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -105,16 +105,13 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
for (TransactionType txType : TransactionType.values()) {
|
||||
RepositorySubclassInfo subclassInfo = subclassInfos[txType.value];
|
||||
|
||||
if (subclassInfo == null)
|
||||
continue;
|
||||
|
||||
if (subclassInfo.constructor == null)
|
||||
if (subclassInfo == null || subclassInfo.constructor == null)
|
||||
continue;
|
||||
|
||||
try {
|
||||
this.repositoryByTxType[txType.value] = (HSQLDBTransactionRepository) subclassInfo.constructor.newInstance(repository);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) {
|
||||
continue;
|
||||
LOGGER.debug(String.format("HSQLDBTransactionRepository subclass constructor failed for transaction type \"%s\"", txType.name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,9 +149,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
approvalHeight = null;
|
||||
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, blockHeight, approvalHeight, signature);
|
||||
TransactionData transactionData = this.fromBase(type, baseTransactionData);
|
||||
|
||||
return transactionData;
|
||||
return this.fromBase(type, baseTransactionData);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch transaction from repository", e);
|
||||
}
|
||||
@ -187,9 +182,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
approvalHeight = null;
|
||||
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, blockHeight, approvalHeight, signature);
|
||||
TransactionData transactionData = this.fromBase(type, baseTransactionData);
|
||||
|
||||
return transactionData;
|
||||
return this.fromBase(type, baseTransactionData);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch transaction from repository", e);
|
||||
}
|
||||
@ -242,7 +235,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
protected List<PaymentData> getPaymentsFromSignature(byte[] signature) throws DataException {
|
||||
String sql = "SELECT recipient, amount, asset_id FROM SharedTransactionPayments WHERE signature = ?";
|
||||
|
||||
List<PaymentData> payments = new ArrayList<PaymentData>();
|
||||
List<PaymentData> payments = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, signature)) {
|
||||
if (resultSet == null)
|
||||
@ -314,7 +307,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
public List<byte[]> getSignaturesInvolvingAddress(String address) throws DataException {
|
||||
String sql = "SELECT signature FROM TransactionRecipients WHERE participant = ?";
|
||||
|
||||
List<byte[]> signatures = new ArrayList<byte[]>();
|
||||
List<byte[]> signatures = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, address)) {
|
||||
if (resultSet == null)
|
||||
@ -366,7 +359,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
+ "WHERE block_height BETWEEN ? AND ? "
|
||||
+ "GROUP BY type";
|
||||
|
||||
Map<TransactionType, Integer> transactionCounts = new HashMap<>();
|
||||
Map<TransactionType, Integer> transactionCounts = new EnumMap<>(TransactionType.class);
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, startHeight, endHeight)) {
|
||||
if (resultSet == null)
|
||||
@ -389,7 +382,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
public List<byte[]> getSignaturesMatchingCriteria(Integer startBlock, Integer blockLimit, Integer txGroupId,
|
||||
List<TransactionType> txTypes, Integer service, String address,
|
||||
ConfirmationStatus confirmationStatus, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
List<byte[]> signatures = new ArrayList<byte[]>();
|
||||
List<byte[]> signatures = new ArrayList<>();
|
||||
|
||||
boolean hasAddress = address != null && !address.isEmpty();
|
||||
boolean hasTxTypes = txTypes != null && !txTypes.isEmpty();
|
||||
@ -399,9 +392,9 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
startBlock = (reverse == null || !reverse) ? 1 : this.repository.getBlockRepository().getBlockchainHeight() - blockLimit;
|
||||
|
||||
String signatureColumn = "Transactions.signature";
|
||||
List<String> whereClauses = new ArrayList<String>();
|
||||
List<String> whereClauses = new ArrayList<>();
|
||||
String groupBy = null;
|
||||
List<Object> bindParams = new ArrayList<Object>();
|
||||
List<Object> bindParams = new ArrayList<>();
|
||||
|
||||
// Tables, starting with Transactions
|
||||
StringBuilder tables = new StringBuilder(256);
|
||||
@ -579,7 +572,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
|
||||
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
|
||||
|
||||
List<TransactionData> transactions = new ArrayList<TransactionData>();
|
||||
List<TransactionData> transactions = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
|
||||
if (resultSet == null)
|
||||
@ -693,7 +686,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
|
||||
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
|
||||
|
||||
List<TransactionData> transactions = new ArrayList<TransactionData>();
|
||||
List<TransactionData> transactions = new ArrayList<>();
|
||||
|
||||
// Find transactions with no corresponding row in BlockTransactions
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams)) {
|
||||
@ -729,7 +722,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
|
||||
sql.append(" AND Transactions.block_height < ? - Groups.min_block_delay");
|
||||
|
||||
List<TransactionData> transactions = new ArrayList<TransactionData>();
|
||||
List<TransactionData> transactions = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), blockHeight)) {
|
||||
if (resultSet == null)
|
||||
@ -764,7 +757,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
|
||||
sql.append(" AND Transactions.block_height < ? - Groups.max_block_delay");
|
||||
|
||||
List<TransactionData> transactions = new ArrayList<TransactionData>();
|
||||
List<TransactionData> transactions = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), blockHeight)) {
|
||||
if (resultSet == null)
|
||||
@ -925,7 +918,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
|
||||
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
|
||||
|
||||
List<TransactionData> transactions = new ArrayList<TransactionData>();
|
||||
List<TransactionData> transactions = new ArrayList<>();
|
||||
|
||||
// Find transactions with no corresponding row in BlockTransactions
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
|
||||
|
@ -94,8 +94,8 @@ public class Settings {
|
||||
|
||||
// Auto-update sources
|
||||
private String[] autoUpdateRepos = new String[] {
|
||||
"https://github.com/catbref/qora-core/raw/%s/qora-core.jar",
|
||||
"https://raw.githubusercontent.com@151.101.16.133/catbref/qora-core/%s/qora-core.jar"
|
||||
"https://github.com/QORT/qortal/raw/%s/qora-core.jar",
|
||||
"https://raw.githubusercontent.com@151.101.16.133/QORT/qortal/%s/qora-core.jar"
|
||||
};
|
||||
|
||||
/** Array of NTP server hostnames. */
|
||||
@ -171,7 +171,7 @@ public class Settings {
|
||||
String path = "";
|
||||
|
||||
do {
|
||||
LOGGER.info("Using settings file: " + path + filename);
|
||||
LOGGER.info(String.format("Using settings file: %s%s", path, filename));
|
||||
|
||||
// Create the StreamSource by creating Reader to the JSON input
|
||||
try (Reader settingsReader = new FileReader(path + filename)) {
|
||||
|
@ -35,7 +35,7 @@ public class ArbitraryTransaction extends Transaction {
|
||||
|
||||
@Override
|
||||
public List<Account> getRecipientAccounts() throws DataException {
|
||||
List<Account> recipients = new ArrayList<Account>();
|
||||
List<Account> recipients = new ArrayList<>();
|
||||
|
||||
if (arbitraryTransactionData.getVersion() != 1)
|
||||
for (PaymentData paymentData : arbitraryTransactionData.getPayments())
|
||||
@ -92,7 +92,7 @@ public class ArbitraryTransaction extends Transaction {
|
||||
@Override
|
||||
public ValidationResult isValid() throws DataException {
|
||||
// Are arbitrary transactions even allowed at this point?
|
||||
if (arbitraryTransactionData.getVersion() != ArbitraryTransaction.getVersionByTimestamp(arbitraryTransactionData.getTimestamp()))
|
||||
if (arbitraryTransactionData.getVersion() != Transaction.getVersionByTimestamp(arbitraryTransactionData.getTimestamp()))
|
||||
return ValidationResult.NOT_YET_RELEASED;
|
||||
|
||||
if (this.arbitraryTransactionData.getTimestamp() < BlockChain.getInstance().getArbitraryReleaseTimestamp())
|
||||
|
@ -57,7 +57,7 @@ public class AtTransaction extends Transaction {
|
||||
/** For AT-Transactions, the use the AT address instead of transaction creator (which is genesis account) */
|
||||
@Override
|
||||
public List<Account> getInvolvedAccounts() throws DataException {
|
||||
List<Account> participants = new ArrayList<Account>(getRecipientAccounts());
|
||||
List<Account> participants = new ArrayList<>(getRecipientAccounts());
|
||||
participants.add(getATAccount());
|
||||
return participants;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class CancelAssetOrderTransaction extends Transaction {
|
||||
|
||||
@Override
|
||||
public List<Account> getRecipientAccounts() {
|
||||
return new ArrayList<Account>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -33,7 +33,7 @@ public class CancelSellNameTransaction extends Transaction {
|
||||
|
||||
@Override
|
||||
public List<Account> getRecipientAccounts() {
|
||||
return new ArrayList<Account>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,7 +35,7 @@ public class CreateAssetOrderTransaction extends Transaction {
|
||||
|
||||
@Override
|
||||
public List<Account> getRecipientAccounts() {
|
||||
return new ArrayList<Account>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,9 +1,9 @@
|
||||
package org.qora.transaction;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -46,7 +46,7 @@ public class DeployAtTransaction extends Transaction {
|
||||
|
||||
@Override
|
||||
public List<Account> getRecipientAccounts() throws DataException {
|
||||
return new ArrayList<Account>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -79,8 +79,7 @@ public class DeployAtTransaction extends Transaction {
|
||||
/** Returns AT version from the header bytes */
|
||||
private short getVersion() {
|
||||
byte[] creationBytes = deployATTransactionData.getCreationBytes();
|
||||
short version = (short) (creationBytes[0] | (creationBytes[1] << 8)); // Little-endian
|
||||
return version;
|
||||
return (short) ((creationBytes[0] & 0xff) | (creationBytes[1] << 8)); // Little-endian
|
||||
}
|
||||
|
||||
/** Make sure deployATTransactionData has an ATAddress */
|
||||
@ -92,9 +91,8 @@ public class DeployAtTransaction extends Transaction {
|
||||
if (blockHeight == 0)
|
||||
blockHeight = this.repository.getBlockRepository().getBlockchainHeight() + 1;
|
||||
|
||||
try {
|
||||
byte[] name = this.deployATTransactionData.getName().getBytes("UTF-8");
|
||||
byte[] description = this.deployATTransactionData.getDescription().replaceAll("\\s", "").getBytes("UTF-8");
|
||||
byte[] name = this.deployATTransactionData.getName().getBytes(StandardCharsets.UTF_8);
|
||||
byte[] description = this.deployATTransactionData.getDescription().replaceAll("\\s", "").getBytes(StandardCharsets.UTF_8);
|
||||
byte[] creatorPublicKey = this.deployATTransactionData.getCreatorPublicKey();
|
||||
byte[] creationBytes = this.deployATTransactionData.getCreationBytes();
|
||||
|
||||
@ -112,9 +110,6 @@ public class DeployAtTransaction extends Transaction {
|
||||
String atAddress = Crypto.toATAddress(byteBuffer.array());
|
||||
|
||||
this.deployATTransactionData.setAtAddress(atAddress);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new DataException("Unable to generate AT account from Deploy AT transaction data", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation
|
||||
|
@ -90,7 +90,7 @@ public class MessageTransaction extends Transaction {
|
||||
@Override
|
||||
public ValidationResult isValid() throws DataException {
|
||||
// Are message transactions even allowed at this point?
|
||||
if (messageTransactionData.getVersion() != MessageTransaction.getVersionByTimestamp(messageTransactionData.getTimestamp()))
|
||||
if (messageTransactionData.getVersion() != Transaction.getVersionByTimestamp(messageTransactionData.getTimestamp()))
|
||||
return ValidationResult.NOT_YET_RELEASED;
|
||||
|
||||
if (this.repository.getBlockRepository().getBlockchainHeight() < BlockChain.getInstance().getMessageReleaseHeight())
|
||||
|
@ -35,7 +35,7 @@ public class MultiPaymentTransaction extends Transaction {
|
||||
|
||||
@Override
|
||||
public List<Account> getRecipientAccounts() throws DataException {
|
||||
List<Account> recipients = new ArrayList<Account>();
|
||||
List<Account> recipients = new ArrayList<>();
|
||||
|
||||
for (PaymentData paymentData : multiPaymentTransactionData.getPayments())
|
||||
recipients.add(new Account(this.repository, paymentData.getRecipient()));
|
||||
@ -95,7 +95,7 @@ public class MultiPaymentTransaction extends Transaction {
|
||||
return ValidationResult.NOT_YET_RELEASED;
|
||||
|
||||
// Check number of payments
|
||||
if (payments.size() < 1 || payments.size() > MAX_PAYMENTS_COUNT)
|
||||
if (payments.isEmpty() || payments.size() > MAX_PAYMENTS_COUNT)
|
||||
return ValidationResult.INVALID_PAYMENTS_COUNT;
|
||||
|
||||
// Check reference is correct
|
||||
|
@ -36,7 +36,7 @@ public class SellNameTransaction extends Transaction {
|
||||
|
||||
@Override
|
||||
public List<Account> getRecipientAccounts() {
|
||||
return new ArrayList<Account>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,6 +7,7 @@ import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@ -91,7 +92,7 @@ public abstract class Transaction {
|
||||
public final Class<?> clazz;
|
||||
public final Constructor<?> constructor;
|
||||
|
||||
private final static Map<Integer, TransactionType> map = stream(TransactionType.values()).collect(toMap(type -> type.value, type -> type));
|
||||
private static final Map<Integer, TransactionType> map = stream(TransactionType.values()).collect(toMap(type -> type.value, type -> type));
|
||||
|
||||
TransactionType(int value, boolean needsApproval) {
|
||||
this.value = value;
|
||||
@ -105,14 +106,14 @@ public abstract class Transaction {
|
||||
|
||||
this.className = String.join("", classNameParts);
|
||||
|
||||
Class<?> clazz = null;
|
||||
Constructor<?> constructor = null;
|
||||
Class<?> subClazz = null;
|
||||
Constructor<?> subConstructor = null;
|
||||
|
||||
try {
|
||||
clazz = Class.forName(String.join("", Transaction.class.getPackage().getName(), ".", this.className, "Transaction"));
|
||||
subClazz = Class.forName(String.join("", Transaction.class.getPackage().getName(), ".", this.className, "Transaction"));
|
||||
|
||||
try {
|
||||
constructor = clazz.getConstructor(Repository.class, TransactionData.class);
|
||||
subConstructor = subClazz.getConstructor(Repository.class, TransactionData.class);
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
LOGGER.debug(String.format("Transaction subclass constructor not found for transaction type \"%s\"", this.name()));
|
||||
}
|
||||
@ -120,8 +121,8 @@ public abstract class Transaction {
|
||||
LOGGER.debug(String.format("Transaction subclass not found for transaction type \"%s\"", this.name()));
|
||||
}
|
||||
|
||||
this.clazz = clazz;
|
||||
this.constructor = constructor;
|
||||
this.clazz = subClazz;
|
||||
this.constructor = subConstructor;
|
||||
}
|
||||
|
||||
public static TransactionType valueOf(int value) {
|
||||
@ -140,7 +141,7 @@ public abstract class Transaction {
|
||||
|
||||
public final int value;
|
||||
|
||||
private final static Map<Integer, ApprovalStatus> map = stream(ApprovalStatus.values()).collect(toMap(result -> result.value, result -> result));
|
||||
private static final Map<Integer, ApprovalStatus> map = stream(ApprovalStatus.values()).collect(toMap(result -> result.value, result -> result));
|
||||
|
||||
ApprovalStatus(int value) {
|
||||
this.value = value;
|
||||
@ -244,7 +245,7 @@ public abstract class Transaction {
|
||||
|
||||
public final int value;
|
||||
|
||||
private final static Map<Integer, ValidationResult> map = stream(ValidationResult.values()).collect(toMap(result -> result.value, result -> result));
|
||||
private static final Map<Integer, ValidationResult> map = stream(ValidationResult.values()).collect(toMap(result -> result.value, result -> result));
|
||||
|
||||
ValidationResult(int value) {
|
||||
this.value = value;
|
||||
@ -417,7 +418,7 @@ public abstract class Transaction {
|
||||
*/
|
||||
public List<Account> getInvolvedAccounts() throws DataException {
|
||||
// Typically this is all the recipients plus the transaction creator/sender
|
||||
List<Account> participants = new ArrayList<Account>(getRecipientAccounts());
|
||||
List<Account> participants = new ArrayList<>(getRecipientAccounts());
|
||||
participants.add(getCreator());
|
||||
return participants;
|
||||
}
|
||||
@ -622,8 +623,8 @@ public abstract class Transaction {
|
||||
List<TransactionData> unconfirmedTransactions = repository.getTransactionRepository().getUnconfirmedTransactions();
|
||||
|
||||
int count = 0;
|
||||
for (TransactionData transactionData : unconfirmedTransactions) {
|
||||
Transaction transaction = Transaction.fromData(repository, transactionData);
|
||||
for (TransactionData unconfirmedTransactionData : unconfirmedTransactions) {
|
||||
Transaction transaction = Transaction.fromData(repository, unconfirmedTransactionData);
|
||||
PublicKeyAccount otherCreator = transaction.getCreator();
|
||||
|
||||
if (Arrays.equals(creator.getPublicKey(), otherCreator.getPublicKey()))
|
||||
@ -662,14 +663,14 @@ public abstract class Transaction {
|
||||
repository.discardChanges();
|
||||
|
||||
try {
|
||||
for (int i = 0; i < unconfirmedTransactions.size(); ++i) {
|
||||
TransactionData transactionData = unconfirmedTransactions.get(i);
|
||||
Iterator<TransactionData> unconfirmedTransactionsIterator = unconfirmedTransactions.iterator();
|
||||
while (unconfirmedTransactionsIterator.hasNext()) {
|
||||
TransactionData transactionData = unconfirmedTransactionsIterator.next();
|
||||
|
||||
if (!isStillValidUnconfirmed(repository, transactionData, latestBlockData.getTimestamp())) {
|
||||
unconfirmedTransactions.remove(i);
|
||||
--i;
|
||||
if (isStillValidUnconfirmed(repository, transactionData, latestBlockData.getTimestamp()))
|
||||
continue;
|
||||
}
|
||||
|
||||
unconfirmedTransactionsIterator.remove();
|
||||
}
|
||||
} finally {
|
||||
// Throw away temporary updates to account lastReference
|
||||
@ -713,16 +714,15 @@ public abstract class Transaction {
|
||||
repository.discardChanges();
|
||||
|
||||
try {
|
||||
for (int i = 0; i < unconfirmedTransactions.size(); ++i) {
|
||||
TransactionData transactionData = unconfirmedTransactions.get(i);
|
||||
Iterator<TransactionData> unconfirmedTransactionsIterator = unconfirmedTransactions.iterator();
|
||||
while (unconfirmedTransactionsIterator.hasNext()) {
|
||||
TransactionData transactionData = unconfirmedTransactionsIterator.next();
|
||||
|
||||
if (!isStillValidUnconfirmed(repository, transactionData, latestBlockData.getTimestamp())) {
|
||||
invalidTransactions.add(transactionData);
|
||||
|
||||
unconfirmedTransactions.remove(i);
|
||||
--i;
|
||||
if (isStillValidUnconfirmed(repository, transactionData, latestBlockData.getTimestamp()))
|
||||
continue;
|
||||
}
|
||||
|
||||
invalidTransactions.add(transactionData);
|
||||
unconfirmedTransactionsIterator.remove();
|
||||
}
|
||||
} finally {
|
||||
// Throw away temporary updates to account lastReference
|
||||
@ -927,7 +927,7 @@ public abstract class Transaction {
|
||||
*/
|
||||
public ValidationResult isProcessable() throws DataException {
|
||||
return ValidationResult.OK;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually process a transaction, updating the blockchain.
|
||||
|
@ -41,7 +41,7 @@ public class VoteOnPollTransaction extends Transaction {
|
||||
|
||||
@Override
|
||||
public List<Account> getRecipientAccounts() {
|
||||
return new ArrayList<Account>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -151,15 +151,13 @@ public class VoteOnPollTransaction extends Transaction {
|
||||
Integer previousOptionIndex = voteOnPollTransactionData.getPreviousOptionIndex();
|
||||
if (previousOptionIndex != null) {
|
||||
// Reinstate previous vote
|
||||
LOGGER.trace("Reinstating previous vote by " + voter.getAddress() + " on poll \"" + voteOnPollTransactionData.getPollName()
|
||||
+ "\" with option index " + previousOptionIndex);
|
||||
LOGGER.trace(() -> String.format("Reinstating previous vote by %s on poll \"%s\" with option index %d", voter.getAddress(), voteOnPollTransactionData.getPollName(), previousOptionIndex));
|
||||
VoteOnPollData previousVoteOnPollData = new VoteOnPollData(voteOnPollTransactionData.getPollName(), voteOnPollTransactionData.getVoterPublicKey(),
|
||||
previousOptionIndex);
|
||||
votingRepository.save(previousVoteOnPollData);
|
||||
} else {
|
||||
// Delete vote
|
||||
LOGGER.trace("Deleting vote by " + voter.getAddress() + " on poll \"" + voteOnPollTransactionData.getPollName() + "\" with option index "
|
||||
+ voteOnPollTransactionData.getOptionIndex());
|
||||
LOGGER.trace(() -> String.format("Deleting vote by %s on poll \"%s\" with option index %d", voter.getAddress(), voteOnPollTransactionData.getPollName(), voteOnPollTransactionData.getOptionIndex()));
|
||||
votingRepository.delete(voteOnPollTransactionData.getPollName(), voteOnPollTransactionData.getVoterPublicKey());
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ import java.nio.ByteBuffer;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
import org.qora.data.PaymentData;
|
||||
import org.qora.transform.TransformationException;
|
||||
import org.qora.utils.Serialization;
|
||||
|
||||
import com.google.common.primitives.Longs;
|
||||
|
@ -109,7 +109,7 @@ public class BlockTransformer extends Transformer {
|
||||
|
||||
int atCount = 0;
|
||||
BigDecimal atFees = BigDecimal.ZERO.setScale(8);
|
||||
List<ATStateData> atStates = new ArrayList<ATStateData>();
|
||||
List<ATStateData> atStates = new ArrayList<>();
|
||||
|
||||
if (version >= 2) {
|
||||
int atBytesLength = byteBuffer.getInt();
|
||||
@ -172,7 +172,7 @@ public class BlockTransformer extends Transformer {
|
||||
int transactionCount = byteBuffer.getInt();
|
||||
|
||||
// Parse transactions now, compared to deferred parsing in Gen1, so we can throw ParseException if need be.
|
||||
List<TransactionData> transactions = new ArrayList<TransactionData>();
|
||||
List<TransactionData> transactions = new ArrayList<>();
|
||||
|
||||
for (int t = 0; t < transactionCount; ++t) {
|
||||
if (byteBuffer.remaining() < TRANSACTION_SIZE_LENGTH)
|
||||
@ -244,7 +244,7 @@ public class BlockTransformer extends Transformer {
|
||||
BlockData blockData = new BlockData(version, reference, transactionCount, totalFees, transactionsSignature, height, timestamp,
|
||||
generatorPublicKey, generatorSignature, atCount, atFees, encodedOnlineAccounts, onlineAccountsCount, onlineAccountsTimestamp, onlineAccountsSignatures);
|
||||
|
||||
return new Triple<BlockData, List<TransactionData>, List<ATStateData>>(blockData, transactions, atStates);
|
||||
return new Triple<>(blockData, transactions, atStates);
|
||||
}
|
||||
|
||||
public static int getDataLength(Block block) throws TransformationException {
|
||||
|
@ -16,6 +16,7 @@ import org.qora.data.transaction.BaseTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.data.transaction.ArbitraryTransactionData.DataType;
|
||||
import org.qora.transaction.ArbitraryTransaction;
|
||||
import org.qora.transaction.Transaction;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
import org.qora.transform.PaymentTransformer;
|
||||
import org.qora.transform.TransformationException;
|
||||
@ -59,7 +60,7 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer {
|
||||
public static TransactionData fromByteBuffer(ByteBuffer byteBuffer) throws TransformationException {
|
||||
long timestamp = byteBuffer.getLong();
|
||||
|
||||
int version = ArbitraryTransaction.getVersionByTimestamp(timestamp);
|
||||
int version = Transaction.getVersionByTimestamp(timestamp);
|
||||
|
||||
int txGroupId = 0;
|
||||
if (timestamp >= BlockChain.getInstance().getQoraV2Timestamp())
|
||||
@ -71,7 +72,7 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer {
|
||||
byte[] senderPublicKey = Serialization.deserializePublicKey(byteBuffer);
|
||||
|
||||
// V3+ allows payments but always return a list of payments, even if empty
|
||||
List<PaymentData> payments = new ArrayList<PaymentData>();
|
||||
List<PaymentData> payments = new ArrayList<>();
|
||||
if (version != 1) {
|
||||
int paymentsCount = byteBuffer.getInt();
|
||||
|
||||
@ -182,7 +183,7 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
// In v1, a coding error means that all bytes prior to final payment entry are lost!
|
||||
// If there are no payments then we can skip mangling
|
||||
if (arbitraryTransactionData.getPayments().size() == 0)
|
||||
if (arbitraryTransactionData.getPayments().isEmpty())
|
||||
return bytes;
|
||||
|
||||
// So we're left with: final payment entry, service, data size, data, fee
|
||||
|
@ -72,7 +72,7 @@ public class CreatePollTransactionTransformer extends TransactionTransformer {
|
||||
if (optionsCount < 1 || optionsCount > Poll.MAX_OPTIONS)
|
||||
throw new TransformationException("Invalid number of options for CreatePollTransaction");
|
||||
|
||||
List<PollOptionData> pollOptions = new ArrayList<PollOptionData>();
|
||||
List<PollOptionData> pollOptions = new ArrayList<>();
|
||||
for (int optionIndex = 0; optionIndex < optionsCount; ++optionIndex) {
|
||||
String optionName = Serialization.deserializeSizedString(byteBuffer, Poll.MAX_NAME_SIZE);
|
||||
|
||||
|
@ -11,6 +11,7 @@ import org.qora.data.transaction.BaseTransactionData;
|
||||
import org.qora.data.transaction.DeployAtTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.transaction.DeployAtTransaction;
|
||||
import org.qora.transaction.Transaction;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
import org.qora.transform.TransformationException;
|
||||
import org.qora.utils.Serialization;
|
||||
@ -59,7 +60,7 @@ public class DeployAtTransactionTransformer extends TransactionTransformer {
|
||||
public static TransactionData fromByteBuffer(ByteBuffer byteBuffer) throws TransformationException {
|
||||
long timestamp = byteBuffer.getLong();
|
||||
|
||||
int version = DeployAtTransaction.getVersionByTimestamp(timestamp);
|
||||
int version = Transaction.getVersionByTimestamp(timestamp);
|
||||
|
||||
int txGroupId = 0;
|
||||
if (timestamp >= BlockChain.getInstance().getQoraV2Timestamp())
|
||||
@ -106,7 +107,7 @@ public class DeployAtTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
int dataLength = getBaseLength(transactionData) + EXTRAS_LENGTH;
|
||||
|
||||
int version = DeployAtTransaction.getVersionByTimestamp(transactionData.getTimestamp());
|
||||
int version = Transaction.getVersionByTimestamp(transactionData.getTimestamp());
|
||||
|
||||
// V4+ have assetId too
|
||||
if (version >= 4)
|
||||
@ -123,7 +124,7 @@ public class DeployAtTransactionTransformer extends TransactionTransformer {
|
||||
try {
|
||||
DeployAtTransactionData deployATTransactionData = (DeployAtTransactionData) transactionData;
|
||||
|
||||
int version = DeployAtTransaction.getVersionByTimestamp(transactionData.getTimestamp());
|
||||
int version = Transaction.getVersionByTimestamp(transactionData.getTimestamp());
|
||||
|
||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||
|
||||
|
@ -11,6 +11,7 @@ import org.qora.data.transaction.BaseTransactionData;
|
||||
import org.qora.data.transaction.MessageTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.transaction.MessageTransaction;
|
||||
import org.qora.transaction.Transaction;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
import org.qora.transform.TransformationException;
|
||||
import org.qora.utils.Serialization;
|
||||
@ -53,7 +54,7 @@ public class MessageTransactionTransformer extends TransactionTransformer {
|
||||
public static TransactionData fromByteBuffer(ByteBuffer byteBuffer) throws TransformationException {
|
||||
long timestamp = byteBuffer.getLong();
|
||||
|
||||
int version = MessageTransaction.getVersionByTimestamp(timestamp);
|
||||
int version = Transaction.getVersionByTimestamp(timestamp);
|
||||
|
||||
int txGroupId = 0;
|
||||
if (timestamp >= BlockChain.getInstance().getQoraV2Timestamp())
|
||||
|
@ -58,7 +58,7 @@ public class MultiPaymentTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
int paymentsCount = byteBuffer.getInt();
|
||||
|
||||
List<PaymentData> payments = new ArrayList<PaymentData>();
|
||||
List<PaymentData> payments = new ArrayList<>();
|
||||
for (int i = 0; i < paymentsCount; ++i)
|
||||
payments.add(PaymentTransformer.fromByteBuffer(byteBuffer));
|
||||
|
||||
|
@ -80,11 +80,9 @@ public class UpdateAssetTransactionTransformer extends TransactionTransformer {
|
||||
public static int getDataLength(TransactionData transactionData) throws TransformationException {
|
||||
UpdateAssetTransactionData updateAssetTransactionData = (UpdateAssetTransactionData) transactionData;
|
||||
|
||||
int dataLength = getBaseLength(transactionData) + EXTRAS_LENGTH
|
||||
return getBaseLength(transactionData) + EXTRAS_LENGTH
|
||||
+ Utf8.encodedLength(updateAssetTransactionData.getNewDescription())
|
||||
+ Utf8.encodedLength(updateAssetTransactionData.getNewData());
|
||||
|
||||
return dataLength;
|
||||
}
|
||||
|
||||
public static byte[] toBytes(TransactionData transactionData) throws TransformationException {
|
||||
|
@ -40,7 +40,7 @@ public class BIP39 {
|
||||
bitShift = 0 - bitShift;
|
||||
entropy[byteIndex++] |= (byte) (wordListIndex >> bitShift);
|
||||
|
||||
entropy[byteIndex] |= (byte) ((wordListIndex << (8 - bitShift)));
|
||||
entropy[byteIndex] |= (byte) (wordListIndex << (8 - bitShift));
|
||||
bitShift = bitShift + BITS_PER_WORD - 8;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class ByteArray implements Comparable<ByteArray> {
|
||||
public int hashCode() {
|
||||
int h = hash;
|
||||
if (h == 0 && value.length > 0) {
|
||||
byte val[] = value;
|
||||
byte[] val = value;
|
||||
|
||||
for (int i = 0; i < val.length; ++i)
|
||||
h = 31 * h + val[i];
|
||||
@ -56,7 +56,7 @@ public class ByteArray implements Comparable<ByteArray> {
|
||||
int b = otherValue[i] & 0xFF;
|
||||
if (a < b)
|
||||
return -1;
|
||||
if (b > a)
|
||||
if (a > b)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ public class NTP implements Runnable {
|
||||
this.remote = remote;
|
||||
}
|
||||
|
||||
public boolean poll(NTPUDPClient client) {
|
||||
public boolean doPoll(NTPUDPClient client) {
|
||||
Thread.currentThread().setName(String.format("NTP: %s", this.remote));
|
||||
|
||||
try {
|
||||
@ -161,9 +161,9 @@ public class NTP implements Runnable {
|
||||
while (!isStopping) {
|
||||
Thread.sleep(1000);
|
||||
|
||||
CompletionService<Boolean> ecs = new ExecutorCompletionService<Boolean>(serverExecutor);
|
||||
CompletionService<Boolean> ecs = new ExecutorCompletionService<>(serverExecutor);
|
||||
for (NTPServer server : ntpServers)
|
||||
ecs.submit(() -> server.poll(client));
|
||||
ecs.submit(() -> server.doPoll(client));
|
||||
|
||||
boolean hasUpdate = false;
|
||||
for (int i = 0; i < ntpServers.size(); ++i) {
|
||||
|
@ -6,6 +6,7 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.qora.transform.TransformationException;
|
||||
import org.qora.transform.Transformer;
|
||||
@ -92,7 +93,7 @@ public class Serialization {
|
||||
}
|
||||
|
||||
public static void serializeSizedString(ByteArrayOutputStream bytes, String string) throws UnsupportedEncodingException, IOException {
|
||||
byte[] stringBytes = string.getBytes("UTF-8");
|
||||
byte[] stringBytes = string.getBytes(StandardCharsets.UTF_8);
|
||||
bytes.write(Ints.toByteArray(stringBytes.length));
|
||||
bytes.write(stringBytes);
|
||||
}
|
||||
@ -108,11 +109,7 @@ public class Serialization {
|
||||
byte[] bytes = new byte[size];
|
||||
byteBuffer.get(bytes);
|
||||
|
||||
try {
|
||||
return new String(bytes, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new TransformationException("UTF-8 charset unsupported during string deserialization");
|
||||
}
|
||||
return new String(bytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class StringLongMapXmlAdapter extends XmlAdapter<StringLongMapXmlAdapter.
|
||||
|
||||
public static class StringLongMap {
|
||||
@XmlVariableNode("key")
|
||||
List<MapEntry> entries = new ArrayList<MapEntry>();
|
||||
List<MapEntry> entries = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static class MapEntry {
|
||||
|
@ -120,4 +120,14 @@ public class ByteArrayTests {
|
||||
System.out.println(String.format("Primitive hashCode: 0x%08x", copiedValue.hashCode()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareTo() {
|
||||
ByteArray testValue0 = new ByteArray(new byte[] { 0x00 });
|
||||
ByteArray testValue1 = new ByteArray(new byte[] { 0x01 });
|
||||
|
||||
assertEquals("0 should be the same as 0", 0, testValue0.compareTo(testValue0));
|
||||
assertEquals("0 should be before 1", -1, testValue0.compareTo(testValue1));
|
||||
assertEquals("1 should be after 0", 1, testValue1.compareTo(testValue0));
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user