Rollout conditional signature serialization to remaining transaction types.

Also added/corrected some JavaDoc.
This commit is contained in:
catbref 2018-06-28 08:36:12 +01:00
parent 05e0fd92b9
commit 9651192a2d
10 changed files with 69 additions and 34 deletions

View File

@ -5,7 +5,6 @@ import static java.util.stream.Collectors.toMap;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -463,10 +462,10 @@ public class Block {
* <p> * <p>
* Performs various tests like checking for parent block, correct block timestamp, version, generating balance, etc. * Performs various tests like checking for parent block, correct block timestamp, version, generating balance, etc.
* <p> * <p>
* Checks block's transactions using an HSQLDB "SAVEPOINT" and hence needs to be called within an ongoing SQL Transaction. * Checks block's transactions by testing their validity then processing them.<br>
* Hence <b>calls repository.discardChanges()</b> before returning.
* *
* @return true if block is valid, false otherwise. * @return ValidationResult.OK if block is valid, or some other ValidationResult otherwise.
* @throws SQLException
* @throws DataException * @throws DataException
*/ */
public ValidationResult isValid() throws DataException { public ValidationResult isValid() throws DataException {
@ -561,13 +560,13 @@ public class Block {
} catch (DataException e) { } catch (DataException e) {
return ValidationResult.TRANSACTION_TIMESTAMP_INVALID; return ValidationResult.TRANSACTION_TIMESTAMP_INVALID;
} finally { } finally {
// Revert back to savepoint // Discard changes to repository made by test-processing transactions above
try { try {
this.repository.discardChanges(); this.repository.discardChanges();
} catch (DataException e) { } catch (DataException e) {
/* /*
* Rollback failure most likely due to prior DataException, so catch rollback's DataException and discard. A "return false" in try-block will * Discard failure most likely due to prior DataException, so catch discardChanges' DataException and discard.
* still return false, prior DataException propagates to caller and successful completion of try-block continues on after rollback. * Prior DataException propagates to caller. Successful completion of try-block continues on after discard.
*/ */
} }
} }

View File

@ -17,29 +17,17 @@ import repository.RepositoryManager;
*/ */
public class BlockChain { public class BlockChain {
/** /** Minimum Qora balance for use in calculations. */
* Minimum Qora balance.
*/
public static final BigDecimal MIN_BALANCE = BigDecimal.valueOf(1L).setScale(8); public static final BigDecimal MIN_BALANCE = BigDecimal.valueOf(1L).setScale(8);
/** /** Maximum Qora balance. */
* Maximum Qora balance.
*/
public static final BigDecimal MAX_BALANCE = BigDecimal.valueOf(10_000_000_000L).setScale(8); public static final BigDecimal MAX_BALANCE = BigDecimal.valueOf(10_000_000_000L).setScale(8);
/** /** Number of blocks between recalculating block's generating balance. */
* Number of blocks between recalculating block's generating balance.
*/
public static final int BLOCK_RETARGET_INTERVAL = 10; public static final int BLOCK_RETARGET_INTERVAL = 10;
/** /** Minimum target time between blocks, in seconds. */
* Minimum target time between blocks, in seconds.
*/
public static final long MIN_BLOCK_TIME = 60; public static final long MIN_BLOCK_TIME = 60;
/** /** Maximum target time between blocks, in seconds. */
* Maximum target time between blocks, in seconds.
*/
public static final long MAX_BLOCK_TIME = 300; public static final long MAX_BLOCK_TIME = 300;
/** /** Maximum acceptable timestamp disagreement offset in milliseconds. */
* Maximum acceptable timestamp disagreement offset in milliseconds.
*/
public static final long BLOCK_TIMESTAMP_MARGIN = 500L; public static final long BLOCK_TIMESTAMP_MARGIN = 500L;
// Various release timestamps / block heights // Various release timestamps / block heights

View File

@ -62,7 +62,7 @@ public abstract class Transaction {
} }
} }
// Minimum fee /** Minimum fee for a transaction */
public static final BigDecimal MINIMUM_FEE = BigDecimal.ONE; public static final BigDecimal MINIMUM_FEE = BigDecimal.ONE;
// Cached info to make transaction processing faster // Cached info to make transaction processing faster
@ -75,11 +75,26 @@ public abstract class Transaction {
// Constructors // Constructors
/**
* Basic constructor for use by subclasses.
*
* @param repository
* @param transactionData
*/
protected Transaction(Repository repository, TransactionData transactionData) { protected Transaction(Repository repository, TransactionData transactionData) {
this.repository = repository; this.repository = repository;
this.transactionData = transactionData; this.transactionData = transactionData;
} }
/**
* Returns subclass of Transaction constructed using passed transaction data.
* <p>
* Uses transaction-type in transaction data to call relevant subclass constructor.
*
* @param repository
* @param transactionData
* @return a Transaction subclass, or null if a transaction couldn't be determined/built from passed data
*/
public static Transaction fromData(Repository repository, TransactionData transactionData) { public static Transaction fromData(Repository repository, TransactionData transactionData) {
switch (transactionData.getType()) { switch (transactionData.getType()) {
case GENESIS: case GENESIS:

View File

@ -13,13 +13,19 @@ public class Poll {
// Constructors // Constructors
/**
* Construct Poll business object using poll data.
*
* @param repository
* @param pollData
*/
public Poll(Repository repository, PollData pollData) { public Poll(Repository repository, PollData pollData) {
this.repository = repository; this.repository = repository;
this.pollData = pollData; this.pollData = pollData;
} }
/** /**
* Create Poll business object using info from create poll transaction. * Construct Poll business object using info from create poll transaction.
* *
* @param repository * @param repository
* @param createPollTransactionData * @param createPollTransactionData
@ -27,9 +33,17 @@ public class Poll {
public Poll(Repository repository, CreatePollTransactionData createPollTransactionData) { public Poll(Repository repository, CreatePollTransactionData createPollTransactionData) {
this.repository = repository; this.repository = repository;
this.pollData = new PollData(createPollTransactionData.getCreatorPublicKey(), createPollTransactionData.getOwner(), this.pollData = new PollData(createPollTransactionData.getCreatorPublicKey(), createPollTransactionData.getOwner(),
createPollTransactionData.getPollName(), createPollTransactionData.getDescription(), createPollTransactionData.getPollOptions(), createPollTransactionData.getTimestamp()); createPollTransactionData.getPollName(), createPollTransactionData.getDescription(), createPollTransactionData.getPollOptions(),
createPollTransactionData.getTimestamp());
} }
/**
* Construct Poll business object using existing poll from repository, identified by pollName.
*
* @param repository
* @param pollName
* @throws DataException
*/
public Poll(Repository repository, String pollName) throws DataException { public Poll(Repository repository, String pollName) throws DataException {
this.repository = repository; this.repository = repository;
this.pollData = this.repository.getVotingRepository().fromPollName(pollName); this.pollData = this.repository.getVotingRepository().fromPollName(pollName);
@ -46,6 +60,13 @@ public class Poll {
this.repository.getVotingRepository().save(this.pollData); this.repository.getVotingRepository().save(this.pollData);
} }
/**
* "Unpublish" poll, removing it from blockchain.
* <p>
* Typically used when orphaning create poll transaction.
*
* @throws DataException
*/
public void unpublish() throws DataException { public void unpublish() throws DataException {
this.repository.getVotingRepository().delete(this.pollData.getPollName()); this.repository.getVotingRepository().delete(this.pollData.getPollName());
} }

View File

@ -66,7 +66,9 @@ public class CancelOrderTransactionTransformer extends TransactionTransformer {
bytes.write(cancelOrderTransactionData.getOrderId()); bytes.write(cancelOrderTransactionData.getOrderId());
Serialization.serializeBigDecimal(bytes, cancelOrderTransactionData.getFee()); Serialization.serializeBigDecimal(bytes, cancelOrderTransactionData.getFee());
bytes.write(cancelOrderTransactionData.getSignature());
if (cancelOrderTransactionData.getSignature() != null)
bytes.write(cancelOrderTransactionData.getSignature());
return bytes.toByteArray(); return bytes.toByteArray();
} catch (IOException | ClassCastException e) { } catch (IOException | ClassCastException e) {

View File

@ -71,7 +71,9 @@ public class CreateOrderTransactionTransformer extends TransactionTransformer {
Serialization.serializeBigDecimal(bytes, createOrderTransactionData.getPrice(), AMOUNT_LENGTH); Serialization.serializeBigDecimal(bytes, createOrderTransactionData.getPrice(), AMOUNT_LENGTH);
Serialization.serializeBigDecimal(bytes, createOrderTransactionData.getFee()); Serialization.serializeBigDecimal(bytes, createOrderTransactionData.getFee());
bytes.write(createOrderTransactionData.getSignature());
if (createOrderTransactionData.getSignature() != null)
bytes.write(createOrderTransactionData.getSignature());
return bytes.toByteArray(); return bytes.toByteArray();
} catch (IOException | ClassCastException e) { } catch (IOException | ClassCastException e) {

View File

@ -86,7 +86,9 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer {
bytes.write((byte) (issueAssetTransactionData.getIsDivisible() ? 1 : 0)); bytes.write((byte) (issueAssetTransactionData.getIsDivisible() ? 1 : 0));
Serialization.serializeBigDecimal(bytes, issueAssetTransactionData.getFee()); Serialization.serializeBigDecimal(bytes, issueAssetTransactionData.getFee());
bytes.write(issueAssetTransactionData.getSignature());
if (issueAssetTransactionData.getSignature() != null)
bytes.write(issueAssetTransactionData.getSignature());
return bytes.toByteArray(); return bytes.toByteArray();
} catch (IOException | ClassCastException e) { } catch (IOException | ClassCastException e) {

View File

@ -120,7 +120,9 @@ public class MessageTransactionTransformer extends TransactionTransformer {
bytes.write((byte) (messageTransactionData.getIsText() ? 1 : 0)); bytes.write((byte) (messageTransactionData.getIsText() ? 1 : 0));
Serialization.serializeBigDecimal(bytes, messageTransactionData.getFee()); Serialization.serializeBigDecimal(bytes, messageTransactionData.getFee());
bytes.write(messageTransactionData.getSignature());
if (messageTransactionData.getSignature() != null)
bytes.write(messageTransactionData.getSignature());
return bytes.toByteArray(); return bytes.toByteArray();
} catch (IOException | ClassCastException e) { } catch (IOException | ClassCastException e) {

View File

@ -84,7 +84,9 @@ public class MultiPaymentTransactionTransformer extends TransactionTransformer {
PaymentTransformer.toBytes(paymentData); PaymentTransformer.toBytes(paymentData);
Serialization.serializeBigDecimal(bytes, multiPaymentTransactionData.getFee()); Serialization.serializeBigDecimal(bytes, multiPaymentTransactionData.getFee());
bytes.write(multiPaymentTransactionData.getSignature());
if (multiPaymentTransactionData.getSignature() != null)
bytes.write(multiPaymentTransactionData.getSignature());
return bytes.toByteArray(); return bytes.toByteArray();
} catch (IOException | ClassCastException e) { } catch (IOException | ClassCastException e) {

View File

@ -70,7 +70,9 @@ public class TransferAssetTransactionTransformer extends TransactionTransformer
Serialization.serializeBigDecimal(bytes, transferAssetTransactionData.getAmount(), AMOUNT_LENGTH); Serialization.serializeBigDecimal(bytes, transferAssetTransactionData.getAmount(), AMOUNT_LENGTH);
Serialization.serializeBigDecimal(bytes, transferAssetTransactionData.getFee()); Serialization.serializeBigDecimal(bytes, transferAssetTransactionData.getFee());
bytes.write(transferAssetTransactionData.getSignature());
if (transferAssetTransactionData.getSignature() != null)
bytes.write(transferAssetTransactionData.getSignature());
return bytes.toByteArray(); return bytes.toByteArray();
} catch (IOException | ClassCastException e) { } catch (IOException | ClassCastException e) {