diff --git a/src/main/java/org/qora/block/Block.java b/src/main/java/org/qora/block/Block.java index d050c969..2be25a1a 100644 --- a/src/main/java/org/qora/block/Block.java +++ b/src/main/java/org/qora/block/Block.java @@ -145,10 +145,6 @@ public class Block { // Other useful constants - /** Maximum size of block in bytes */ - // TODO push this out to blockchain config file - public static final int MAX_BLOCK_BYTES = 1048576; - private static final BigInteger MAX_DISTANCE; static { byte[] maxValue = new byte[Transformer.PUBLIC_KEY_LENGTH]; @@ -606,7 +602,7 @@ public class Block { // Check there is space in block try { - if (BlockTransformer.getDataLength(this) + TransactionTransformer.getDataLength(transactionData) > MAX_BLOCK_BYTES) + if (BlockTransformer.getDataLength(this) + TransactionTransformer.getDataLength(transactionData) > BlockChain.getInstance().getMaxBlockSize()) return false; } catch (TransformationException e) { return false; diff --git a/src/main/java/org/qora/block/BlockChain.java b/src/main/java/org/qora/block/BlockChain.java index 2e2daff7..792374f7 100644 --- a/src/main/java/org/qora/block/BlockChain.java +++ b/src/main/java/org/qora/block/BlockChain.java @@ -52,6 +52,8 @@ public class BlockChain { private boolean isTestChain = false; /** Maximum coin supply. */ private BigDecimal maxBalance; + /** Transaction expiry period, starting from transaction's timestamp, in milliseconds. */ + private long transactionExpiryPeriod; private BigDecimal unitFee; private BigDecimal maxBytesPerUnitFee; @@ -65,6 +67,8 @@ public class BlockChain { private long maxBlockTime; /** Maximum acceptable timestamp disagreement offset in milliseconds. */ private long blockTimestampMargin; + /** Maximum block size, in bytes. */ + private int maxBlockSize; /** Whether transactions with txGroupId of NO_GROUP are allowed */ private boolean requireGroupForApproval; @@ -241,6 +245,10 @@ public class BlockChain { return this.maxBalance; } + public long getTransactionExpiryPeriod() { + return this.transactionExpiryPeriod; + } + public int getBlockDifficultyInterval() { return this.blockDifficultyInterval; } @@ -257,6 +265,10 @@ public class BlockChain { return this.blockTimestampMargin; } + public int getMaxBlockSize() { + return this.maxBlockSize; + } + /** Returns true if approval-needing transaction types require a txGroupId other than NO_GROUP. */ public boolean getRequireGroupForApproval() { return this.requireGroupForApproval; diff --git a/src/main/java/org/qora/network/Network.java b/src/main/java/org/qora/network/Network.java index 032ea73f..52e8aabc 100644 --- a/src/main/java/org/qora/network/Network.java +++ b/src/main/java/org/qora/network/Network.java @@ -33,7 +33,7 @@ import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.qora.block.Block; +import org.qora.block.BlockChain; import org.qora.controller.Controller; import org.qora.data.block.BlockData; import org.qora.data.network.PeerData; @@ -78,9 +78,6 @@ public class Network extends Thread { /** Maximum time allowed for handshake to complete, in milliseconds. */ private static final long HANDSHAKE_TIMEOUT = 60 * 1000; // ms - /** Maximum message size (bytes). Needs to be at least maximum block size + MAGIC + message type, etc. */ - /* package */ static final int MAXIMUM_MESSAGE_SIZE = 4 + 1 + 4 + Block.MAX_BLOCK_BYTES; - private static final byte[] MAINNET_MESSAGE_MAGIC = new byte[] { 0x51, 0x4f, 0x52, 0x54 }; // QORT private static final byte[] TESTNET_MESSAGE_MAGIC = new byte[] { 0x71, 0x6f, 0x72, 0x54 }; // qorT @@ -100,6 +97,7 @@ public class Network extends Thread { public static final byte[] ZERO_PEER_ID = new byte[PEER_ID_LENGTH]; private final byte[] ourPeerId; + private final int maxMessageSize; private List connectedPeers; private List selfPeers; @@ -152,6 +150,8 @@ public class Network extends Thread { // Set bit to make sure our peer ID is not 0 ourPeerId[ourPeerId.length - 1] |= 0x01; + maxMessageSize = 4 + 1 + 4 + BlockChain.getInstance().getMaxBlockSize(); + minOutboundPeers = Settings.getInstance().getMinOutboundPeers(); maxPeers = Settings.getInstance().getMaxPeers(); @@ -189,6 +189,11 @@ public class Network extends Thread { return this.ourPeerId; } + /** Maximum message size (bytes). Needs to be at least maximum block size + MAGIC + message type, etc. */ + /* package */ int getMaxMessageSize() { + return this.maxMessageSize; + } + // Peer lists public List getConnectedPeers() { diff --git a/src/main/java/org/qora/network/Peer.java b/src/main/java/org/qora/network/Peer.java index b9678071..a7a2692b 100644 --- a/src/main/java/org/qora/network/Peer.java +++ b/src/main/java/org/qora/network/Peer.java @@ -293,7 +293,7 @@ public class Peer { this.connectionTimestamp = NTP.getTime(); this.socketChannel.setOption(StandardSocketOptions.TCP_NODELAY, true); this.socketChannel.configureBlocking(false); - this.byteBuffer = ByteBuffer.allocate(Network.MAXIMUM_MESSAGE_SIZE); + this.byteBuffer = ByteBuffer.allocate(Network.getInstance().getMaxMessageSize()); this.replyQueues = Collections.synchronizedMap(new HashMap>()); this.pendingMessages = new LinkedBlockingQueue(); } diff --git a/src/main/java/org/qora/transaction/Transaction.java b/src/main/java/org/qora/transaction/Transaction.java index 269014c3..2b990dfe 100644 --- a/src/main/java/org/qora/transaction/Transaction.java +++ b/src/main/java/org/qora/transaction/Transaction.java @@ -305,8 +305,8 @@ public abstract class Transaction { // More information public static long getDeadline(TransactionData transactionData) { - // 24 hour deadline to include transaction in a block - return transactionData.getTimestamp() + (24 * 60 * 60 * 1000); + // Calculate deadline to include transaction in a block + return transactionData.getTimestamp() + BlockChain.getInstance().getTransactionExpiryPeriod(); } public long getDeadline() { diff --git a/src/main/java/org/qora/transform/block/BlockTransformer.java b/src/main/java/org/qora/transform/block/BlockTransformer.java index 96327704..b7bf5078 100644 --- a/src/main/java/org/qora/transform/block/BlockTransformer.java +++ b/src/main/java/org/qora/transform/block/BlockTransformer.java @@ -10,6 +10,7 @@ import java.util.List; import org.qora.account.PublicKeyAccount; import org.qora.block.Block; +import org.qora.block.BlockChain; import org.qora.data.at.ATStateData; import org.qora.data.block.BlockData; import org.qora.data.transaction.TransactionData; @@ -89,7 +90,7 @@ public class BlockTransformer extends Transformer { if (version >= 2 && byteBuffer.remaining() < BASE_LENGTH + AT_BYTES_LENGTH - VERSION_LENGTH) throw new TransformationException("Byte data too short for V2+ Block"); - if (byteBuffer.remaining() > Block.MAX_BLOCK_BYTES) + if (byteBuffer.remaining() > BlockChain.getInstance().getMaxBlockSize()) throw new TransformationException("Byte data too long for Block"); long timestamp = byteBuffer.getLong(); @@ -116,7 +117,7 @@ public class BlockTransformer extends Transformer { if (version >= 2) { int atBytesLength = byteBuffer.getInt(); - if (atBytesLength > Block.MAX_BLOCK_BYTES) + if (atBytesLength > BlockChain.getInstance().getMaxBlockSize()) throw new TransformationException("Byte data too long for Block's AT info"); ByteBuffer atByteBuffer = byteBuffer.slice(); @@ -185,7 +186,7 @@ public class BlockTransformer extends Transformer { if (byteBuffer.remaining() < transactionLength) throw new TransformationException("Byte data too short for Block Transaction"); - if (transactionLength > Block.MAX_BLOCK_BYTES) + if (transactionLength > BlockChain.getInstance().getMaxBlockSize()) throw new TransformationException("Byte data too long for Block Transaction"); byte[] transactionBytes = new byte[transactionLength]; @@ -208,7 +209,7 @@ public class BlockTransformer extends Transformer { int conciseSetLength = byteBuffer.getInt(); - if (conciseSetLength > Block.MAX_BLOCK_BYTES) + if (conciseSetLength > BlockChain.getInstance().getMaxBlockSize()) throw new TransformationException("Byte data too long for online account info"); if ((conciseSetLength & 3) != 0) @@ -230,7 +231,7 @@ public class BlockTransformer extends Transformer { onlineAccountsTimestamp = byteBuffer.getLong(); final int signaturesByteLength = onlineAccountsSignaturesCount * Transformer.SIGNATURE_LENGTH; - if (signaturesByteLength > Block.MAX_BLOCK_BYTES) + if (signaturesByteLength > BlockChain.getInstance().getMaxBlockSize()) throw new TransformationException("Byte data too long for online accounts signatures"); onlineAccountsSignatures = new byte[signaturesByteLength];