Browse Source

Interim commit of *TransactionData classes for safety

pull/67/head
catbref 5 years ago
parent
commit
c9968b3dd2
  1. 9
      src/main/java/org/qora/api/resource/TransactionsResource.java
  2. 62
      src/main/java/org/qora/block/Block.java
  3. 7
      src/main/java/org/qora/block/BlockGenerator.java
  4. 4
      src/main/java/org/qora/controller/Controller.java
  5. 11
      src/main/java/org/qora/data/group/GroupApprovalData.java
  6. 11
      src/main/java/org/qora/data/transaction/ATTransactionData.java
  7. 16
      src/main/java/org/qora/data/transaction/AccountFlagsTransactionData.java
  8. 16
      src/main/java/org/qora/data/transaction/AddGroupAdminTransactionData.java
  9. 25
      src/main/java/org/qora/data/transaction/ArbitraryTransactionData.java
  10. 17
      src/main/java/org/qora/data/transaction/BuyNameTransactionData.java
  11. 12
      src/main/java/org/qora/data/transaction/CancelAssetOrderTransactionData.java
  12. 16
      src/main/java/org/qora/data/transaction/CancelGroupBanTransactionData.java
  13. 16
      src/main/java/org/qora/data/transaction/CancelGroupInviteTransactionData.java
  14. 13
      src/main/java/org/qora/data/transaction/CancelSellNameTransactionData.java
  15. 13
      src/main/java/org/qora/data/transaction/CreateAssetOrderTransactionData.java
  16. 19
      src/main/java/org/qora/data/transaction/CreateGroupTransactionData.java
  17. 14
      src/main/java/org/qora/data/transaction/CreatePollTransactionData.java
  18. 12
      src/main/java/org/qora/data/transaction/DeployAtTransactionData.java
  19. 13
      src/main/java/org/qora/data/transaction/EnableForgingTransactionData.java
  20. 12
      src/main/java/org/qora/data/transaction/GenesisTransactionData.java
  21. 16
      src/main/java/org/qora/data/transaction/GroupApprovalTransactionData.java
  22. 17
      src/main/java/org/qora/data/transaction/GroupBanTransactionData.java
  23. 15
      src/main/java/org/qora/data/transaction/GroupInviteTransactionData.java
  24. 16
      src/main/java/org/qora/data/transaction/GroupKickTransactionData.java
  25. 13
      src/main/java/org/qora/data/transaction/IssueAssetTransactionData.java
  26. 16
      src/main/java/org/qora/data/transaction/JoinGroupTransactionData.java
  27. 15
      src/main/java/org/qora/data/transaction/LeaveGroupTransactionData.java
  28. 13
      src/main/java/org/qora/data/transaction/MessageTransactionData.java
  29. 13
      src/main/java/org/qora/data/transaction/MultiPaymentTransactionData.java
  30. 12
      src/main/java/org/qora/data/transaction/PaymentTransactionData.java
  31. 20
      src/main/java/org/qora/data/transaction/ProxyForgingTransactionData.java
  32. 12
      src/main/java/org/qora/data/transaction/RegisterNameTransactionData.java
  33. 16
      src/main/java/org/qora/data/transaction/RemoveGroupAdminTransactionData.java
  34. 13
      src/main/java/org/qora/data/transaction/SellNameTransactionData.java
  35. 18
      src/main/java/org/qora/data/transaction/SetGroupTransactionData.java
  36. 33
      src/main/java/org/qora/data/transaction/TransactionData.java
  37. 15
      src/main/java/org/qora/data/transaction/TransferAssetTransactionData.java
  38. 17
      src/main/java/org/qora/data/transaction/UpdateAssetTransactionData.java
  39. 24
      src/main/java/org/qora/data/transaction/UpdateGroupTransactionData.java
  40. 14
      src/main/java/org/qora/data/transaction/UpdateNameTransactionData.java
  41. 12
      src/main/java/org/qora/data/transaction/VoteOnPollTransactionData.java
  42. 24
      src/main/java/org/qora/group/Group.java
  43. 39
      src/main/java/org/qora/repository/TransactionRepository.java
  44. 17
      src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java
  45. 7
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java
  46. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java
  47. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java
  48. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java
  49. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java
  50. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java
  51. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java
  52. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java
  53. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java
  54. 6
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java
  55. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java
  56. 6
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java
  57. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java
  58. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBEnableForgingTransactionRepository.java
  59. 3
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java
  60. 7
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java
  61. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java
  62. 6
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java
  63. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java
  64. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java
  65. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java
  66. 6
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java
  67. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java
  68. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java
  69. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java
  70. 6
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBProxyForgingTransactionRepository.java
  71. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java
  72. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java
  73. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java
  74. 6
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java
  75. 349
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java
  76. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransferAssetTransactionRepository.java
  77. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java
  78. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java
  79. 5
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java
  80. 6
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java
  81. 6
      src/main/java/org/qora/transaction/GroupApprovalTransaction.java
  82. 89
      src/main/java/org/qora/transaction/Transaction.java
  83. 2
      src/main/java/org/qora/transform/transaction/CreateGroupTransactionTransformer.java
  84. 2
      src/main/java/org/qora/transform/transaction/GroupApprovalTransactionTransformer.java
  85. 2
      src/main/java/org/qora/transform/transaction/UpdateAssetTransactionTransformer.java
  86. 4
      src/test/java/org/qora/test/GroupApprovalTests.java
  87. 6
      src/test/java/org/qora/test/TransactionTests.java

9
src/main/java/org/qora/api/resource/TransactionsResource.java

@ -249,7 +249,7 @@ public class TransactionsResource {
ref = "reverse"
) @QueryParam("reverse") Boolean reverse) {
try (final Repository repository = RepositoryManager.getRepository()) {
return repository.getTransactionRepository().getPendingTransactions(txGroupId, limit, offset, reverse);
return repository.getTransactionRepository().getApprovalPendingTransactions(txGroupId, limit, offset, reverse);
} catch (ApiException e) {
throw e;
} catch (DataException e) {
@ -413,11 +413,14 @@ public class TransactionsResource {
public String processTransaction(String rawBytes58) {
try (final Repository repository = RepositoryManager.getRepository()) {
byte[] rawBytes = Base58.decode(rawBytes58);
TransactionData transactionData = TransactionTransformer.fromBytes(rawBytes);
if (transactionData == null)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA);
Transaction transaction = Transaction.fromData(repository, transactionData);
if (!transaction.isSignatureValid())
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_SIGNATURE);
@ -425,9 +428,7 @@ public class TransactionsResource {
if (result != ValidationResult.OK)
throw createTransactionInvalidException(request, result);
repository.getTransactionRepository().save(transactionData);
repository.getTransactionRepository().unconfirmTransaction(transactionData);
repository.saveChanges();
transaction.importAsUnconfirmed();
// Notify controller of new transaction
Controller.getInstance().onNewTransaction(transactionData);

62
src/main/java/org/qora/block/Block.java

@ -34,6 +34,7 @@ import org.qora.repository.Repository;
import org.qora.transaction.AtTransaction;
import org.qora.transaction.GenesisTransaction;
import org.qora.transaction.Transaction;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import org.qora.transform.TransformationException;
import org.qora.transform.block.BlockTransformer;
@ -908,10 +909,6 @@ public class Block {
if (this.repository.getTransactionRepository().isConfirmed(transaction.getTransactionData().getSignature()))
return ValidationResult.TRANSACTION_ALREADY_PROCESSED;
// Check transaction doesn't still need approval
if (transaction.needsGroupApproval() && !transaction.meetsGroupApprovalThreshold())
return ValidationResult.TRANSACTION_NEEDS_APPROVAL;
// Check transaction is even valid
// NOTE: in Gen1 there was an extra block height passed to DeployATTransaction.isValid
Transaction.ValidationResult validationResult = transaction.isValid();
@ -1053,9 +1050,18 @@ public class Block {
if (transaction.getTransactionData().getType() == TransactionType.AT)
this.repository.getTransactionRepository().save(transaction.getTransactionData());
transaction.process();
// Only process transactions that don't require group-approval.
// Group-approval transactions are dealt with later.
if (transaction.getTransactionData().getApprovalStatus() == ApprovalStatus.NOT_REQUIRED)
transaction.process();
// Regardless of group-approval, update relevant info for creator (e.g. lastReference)
transaction.processCreatorUpdates();
}
// Group-approval transactions
processGroupApprovalTransactions();
// Give transaction fees to generator/proxy
rewardTransactionFees();
@ -1087,6 +1093,11 @@ public class Block {
transaction.getTransactionData().getSignature());
this.repository.getBlockRepository().save(blockTransactionData);
// Update transaction's height in repository
this.repository.getTransactionRepository().updateHeight(transaction.getTransactionData().getSignature(), this.blockData.getHeight());
// Update local transactionData's height too
transaction.getTransactionData().setBlockHeight(this.blockData.getHeight());
// No longer unconfirmed
this.repository.getTransactionRepository().confirmTransaction(transaction.getTransactionData().getSignature());
@ -1096,6 +1107,47 @@ public class Block {
}
}
protected void processGroupApprovalTransactions() throws DataException {
// Search for pending transactions that have now expired
List<TransactionData> approvalExpiringTransactions = this.repository.getTransactionRepository().getApprovalExpiringTransactions(this.blockData.getHeight());
for (TransactionData transactionData : approvalExpiringTransactions) {
transactionData.setApprovalStatus(ApprovalStatus.EXPIRED);
this.repository.getTransactionRepository().save(transactionData);
}
// Search for pending transactions within min/max block delay range
List<TransactionData> approvalPendingTransactions = this.repository.getTransactionRepository().getApprovalPendingTransactions(this.blockData.getHeight());
for (TransactionData transactionData : approvalPendingTransactions) {
Transaction transaction = Transaction.fromData(this.repository, transactionData);
// something like:
Boolean isApproved = transaction.getApprovalDecision();
if (isApproved == null)
continue; // approve/reject threshold not yet met
if (!isApproved) {
// REJECT
transactionData.setApprovalStatus(ApprovalStatus.REJECTED);
this.repository.getTransactionRepository().save(transactionData);
continue;
}
// Approved, but check transaction is still valid
if (transaction.isValid() != Transaction.ValidationResult.OK) {
transactionData.setApprovalStatus(ApprovalStatus.INVALID);
this.repository.getTransactionRepository().save(transactionData);
continue;
}
// APPROVED, in which case do transaction.process();
transactionData.setApprovalStatus(ApprovalStatus.INVALID);
this.repository.getTransactionRepository().save(transactionData);
transaction.process();
}
}
protected void processBlockRewards() throws DataException {
BigDecimal reward = getRewardAtHeight(this.blockData.getHeight());

7
src/main/java/org/qora/block/BlockGenerator.java

@ -240,13 +240,6 @@ public class BlockGenerator extends Thread {
--i;
continue;
}
// Ignore transactions that have not met group-admin approval threshold
if (transaction.needsGroupApproval() && !transaction.meetsGroupApprovalThreshold()) {
unconfirmedTransactions.remove(i);
--i;
continue;
}
}
// Attempt to add transactions until block is full, or we run out

4
src/main/java/org/qora/controller/Controller.java

@ -578,9 +578,7 @@ public class Controller extends Thread {
}
// Seems ok - add to unconfirmed pile
repository.getTransactionRepository().save(transactionData);
repository.getTransactionRepository().unconfirmTransaction(transactionData);
repository.saveChanges();
transaction.importAsUnconfirmed();
} finally {
blockchainLock.unlock();
}

11
src/main/java/org/qora/data/group/GroupApprovalData.java

@ -0,0 +1,11 @@
package org.qora.data.group;
import java.util.ArrayList;
import java.util.List;
public class GroupApprovalData {
public List<byte[]> approvingAdmins = new ArrayList<>();
public List<byte[]> rejectingAdmins = new ArrayList<>();
}

11
src/main/java/org/qora/data/transaction/ATTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.qora.account.GenesisAccount;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -34,9 +35,10 @@ public class ATTransactionData extends TransactionData {
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
}
/** From repository */
public ATTransactionData(long timestamp, int txGroupId, byte[] reference, String atAddress, String recipient, BigDecimal amount, Long assetId,
byte[] message, BigDecimal fee, byte[] signature) {
super(TransactionType.AT, timestamp, txGroupId, reference, GenesisAccount.PUBLIC_KEY, fee, signature);
byte[] message, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.AT, timestamp, txGroupId, reference, GenesisAccount.PUBLIC_KEY, fee, approvalStatus, height, signature);
this.atAddress = atAddress;
this.recipient = recipient;
@ -45,9 +47,12 @@ public class ATTransactionData extends TransactionData {
this.message = message;
}
// Never from network/API!
/** New, unsigned */
public ATTransactionData(long timestamp, int txGroupId, byte[] reference, String atAddress, String recipient, BigDecimal amount, Long assetId,
byte[] message, BigDecimal fee) {
this(timestamp, txGroupId, reference, atAddress, recipient, amount, assetId, message, fee, null);
this(timestamp, txGroupId, reference, atAddress, recipient, amount, assetId, message, fee, null, null, null);
}
// Getters/Setters

16
src/main/java/org/qora/data/transaction/AccountFlagsTransactionData.java

@ -10,6 +10,7 @@ import javax.xml.bind.annotation.XmlElement;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import org.qora.account.GenesisAccount;
import org.qora.block.GenesisBlock;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -44,9 +45,10 @@ public class AccountFlagsTransactionData extends TransactionData {
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
}
/** From repository */
public AccountFlagsTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, String target, int andMask, int orMask,
int xorMask, Integer previousFlags, BigDecimal fee, byte[] signature) {
super(TransactionType.ACCOUNT_FLAGS, timestamp, groupId, reference, creatorPublicKey, fee, signature);
int xorMask, Integer previousFlags, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.ACCOUNT_FLAGS, timestamp, groupId, reference, creatorPublicKey, fee, approvalStatus, height, signature);
this.target = target;
this.andMask = andMask;
@ -55,10 +57,16 @@ public class AccountFlagsTransactionData extends TransactionData {
this.previousFlags = previousFlags;
}
// Typically used in deserialization context
/** From network/API */
public AccountFlagsTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, String target, int andMask, int orMask,
int xorMask, BigDecimal fee, byte[] signature) {
this(timestamp, groupId, reference, creatorPublicKey, target, andMask, orMask, xorMask, null, fee, signature);
this(timestamp, groupId, reference, creatorPublicKey, target, andMask, orMask, xorMask, null, fee, null, null, signature);
}
/** New, unsigned */
public AccountFlagsTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, String target, int andMask, int orMask,
int xorMask, BigDecimal fee) {
this(timestamp, groupId, reference, creatorPublicKey, target, andMask, orMask, xorMask, fee, null);
}
// Getters / setters

16
src/main/java/org/qora/data/transaction/AddGroupAdminTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -39,14 +40,25 @@ public class AddGroupAdminTransactionData extends TransactionData {
this.creatorPublicKey = this.ownerPublicKey;
}
public AddGroupAdminTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId, String member, BigDecimal fee, byte[] signature) {
super(TransactionType.ADD_GROUP_ADMIN, timestamp, txGroupId, reference, ownerPublicKey, fee, signature);
/** From repository */
public AddGroupAdminTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId, String member, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.ADD_GROUP_ADMIN, timestamp, txGroupId, reference, ownerPublicKey, fee, approvalStatus, height, signature);
this.ownerPublicKey = ownerPublicKey;
this.groupId = groupId;
this.member = member;
}
/** From network/API */
public AddGroupAdminTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId, String member, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, ownerPublicKey, groupId, member, fee, null, null, signature);
}
/** New, unsigned */
public AddGroupAdminTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId, String member, BigDecimal fee) {
this(timestamp, txGroupId, reference, ownerPublicKey, groupId, member, fee, null);
}
// Getters / setters
public byte[] getOwnerPublicKey() {

25
src/main/java/org/qora/data/transaction/ArbitraryTransactionData.java

@ -9,6 +9,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import org.qora.data.PaymentData;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -52,10 +53,10 @@ public class ArbitraryTransactionData extends TransactionData {
this.creatorPublicKey = this.senderPublicKey;
}
/** Reconstructing a V3 arbitrary transaction with signature */
/** From repository */
public ArbitraryTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, int version, int service,
byte[] data, DataType dataType, List<PaymentData> payments, BigDecimal fee, byte[] signature) {
super(TransactionType.ARBITRARY, timestamp, txGroupId, reference, senderPublicKey, fee, signature);
byte[] data, DataType dataType, List<PaymentData> payments, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.ARBITRARY, timestamp, txGroupId, reference, senderPublicKey, fee, approvalStatus, height, signature);
this.senderPublicKey = senderPublicKey;
this.version = version;
@ -65,19 +66,25 @@ public class ArbitraryTransactionData extends TransactionData {
this.payments = payments;
}
/** Constructing a new V3 arbitrary transaction without signature */
/** From network/API (V3) */
public ArbitraryTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, int version, int service,
byte[] data, DataType dataType, List<PaymentData> payments, BigDecimal fee) {
this(timestamp, txGroupId, reference, senderPublicKey, version, service, data, dataType, payments, fee, null);
byte[] data, DataType dataType, List<PaymentData> payments, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, senderPublicKey, version, service, data, dataType, payments, fee, null, null, signature);
}
/** Reconstructing a V1 arbitrary transaction with signature */
/** From network/API (V1) */
public ArbitraryTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, int version, int service, byte[] data,
DataType dataType, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, senderPublicKey, version, service, data, dataType, null, fee, signature);
this(timestamp, txGroupId, reference, senderPublicKey, version, service, data, dataType, null, fee, null, null, signature);
}
/** New, unsigned (V3) */
public ArbitraryTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, int version, int service, byte[] data,
DataType dataType, List<PaymentData> payments, BigDecimal fee) {
this(timestamp, txGroupId, reference, senderPublicKey, version, service, data, dataType, payments, fee, null);
}
/** Constructing a new V1 arbitrary transaction without signature */
/** New, unsigned (V1) */
public ArbitraryTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, int version, int service, byte[] data,
DataType dataType, BigDecimal fee) {
this(timestamp, txGroupId, reference, senderPublicKey, version, service, data, dataType, null, fee, null);

17
src/main/java/org/qora/data/transaction/BuyNameTransactionData.java

@ -8,6 +8,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -46,9 +47,10 @@ public class BuyNameTransactionData extends TransactionData {
this.creatorPublicKey = this.buyerPublicKey;
}
/** From repository */
public BuyNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] buyerPublicKey, String name, BigDecimal amount, String seller,
byte[] nameReference, BigDecimal fee, byte[] signature) {
super(TransactionType.BUY_NAME, timestamp, txGroupId, reference, buyerPublicKey, fee, signature);
byte[] nameReference, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.BUY_NAME, timestamp, txGroupId, reference, buyerPublicKey, fee, approvalStatus, height, signature);
this.buyerPublicKey = buyerPublicKey;
this.name = name;
@ -57,18 +59,15 @@ public class BuyNameTransactionData extends TransactionData {
this.nameReference = nameReference;
}
/** From network/API */
public BuyNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] buyerPublicKey, String name, BigDecimal amount, String seller,
BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, buyerPublicKey, name, amount, seller, null, fee, signature);
}
public BuyNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] buyerPublicKey, String name, BigDecimal amount, String seller,
byte[] nameReference, BigDecimal fee) {
this(timestamp, txGroupId, reference, buyerPublicKey, name, amount, seller, nameReference, fee, null);
this(timestamp, txGroupId, reference, buyerPublicKey, name, amount, seller, null, fee, null, null, signature);
}
/** New, unsigned */
public BuyNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] buyerPublicKey, String name, BigDecimal amount, String seller, BigDecimal fee) {
this(timestamp, txGroupId, reference, buyerPublicKey, name, amount, seller, null, fee, null);
this(timestamp, txGroupId, reference, buyerPublicKey, name, amount, seller, fee, null);
}
// Getters / setters

12
src/main/java/org/qora/data/transaction/CancelAssetOrderTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import org.qora.transaction.Transaction;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -27,12 +28,19 @@ public class CancelAssetOrderTransactionData extends TransactionData {
super(TransactionType.CANCEL_ASSET_ORDER);
}
public CancelAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, byte[] orderId, BigDecimal fee, byte[] signature) {
super(Transaction.TransactionType.CANCEL_ASSET_ORDER, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
/** From network/API */
public CancelAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, byte[] orderId, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(Transaction.TransactionType.CANCEL_ASSET_ORDER, timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, height, signature);
this.orderId = orderId;
}
/** From network/API */
public CancelAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, byte[] orderId, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, creatorPublicKey, orderId, fee, null, null, signature);
}
/** New, unsigned */
public CancelAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, byte[] orderId, BigDecimal fee) {
this(timestamp, txGroupId, reference, creatorPublicKey, orderId, fee, null);
}

16
src/main/java/org/qora/data/transaction/CancelGroupBanTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -40,8 +41,10 @@ public class CancelGroupBanTransactionData extends TransactionData {
this.creatorPublicKey = this.adminPublicKey;
}
public CancelGroupBanTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member, byte[] banReference, BigDecimal fee, byte[] signature) {
super(TransactionType.CANCEL_GROUP_BAN, timestamp, txGroupId, reference, adminPublicKey, fee, signature);
/** From repository */
public CancelGroupBanTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member, byte[] banReference,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.CANCEL_GROUP_BAN, timestamp, txGroupId, reference, adminPublicKey, fee, approvalStatus, height, signature);
this.adminPublicKey = adminPublicKey;
this.groupId = groupId;
@ -49,9 +52,14 @@ public class CancelGroupBanTransactionData extends TransactionData {
this.banReference = banReference;
}
/** Constructor typically used after deserialization */
/** From network/API */
public CancelGroupBanTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, adminPublicKey, groupId, member, null, fee, signature);
this(timestamp, txGroupId, reference, adminPublicKey, groupId, member, null, fee, null, null, signature);
}
/** New, unsigned */
public CancelGroupBanTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member, BigDecimal fee) {
this(timestamp, txGroupId, reference, adminPublicKey, groupId, member, fee, null);
}
// Getters / setters

16
src/main/java/org/qora/data/transaction/CancelGroupInviteTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -40,8 +41,10 @@ public class CancelGroupInviteTransactionData extends TransactionData {
this.creatorPublicKey = this.adminPublicKey;
}
public CancelGroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, byte[] inviteReference, BigDecimal fee, byte[] signature) {
super(TransactionType.CANCEL_GROUP_INVITE, timestamp, txGroupId, reference, adminPublicKey, fee, signature);
/** From repository */
public CancelGroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, byte[] inviteReference,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.CANCEL_GROUP_INVITE, timestamp, txGroupId, reference, adminPublicKey, fee, approvalStatus, height, signature);
this.adminPublicKey = adminPublicKey;
this.groupId = groupId;
@ -49,9 +52,14 @@ public class CancelGroupInviteTransactionData extends TransactionData {
this.inviteReference = inviteReference;
}
/** Constructor typically used after deserialization */
/** From network/API */
public CancelGroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, adminPublicKey, groupId, invitee, null, fee, signature);
this(timestamp, txGroupId, reference, adminPublicKey, groupId, invitee, null, fee, null, null, signature);
}
/** New, unsigned */
public CancelGroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, BigDecimal fee) {
this(timestamp, txGroupId, reference, adminPublicKey, groupId, invitee, fee, null);
}
// Getters / setters

13
src/main/java/org/qora/data/transaction/CancelSellNameTransactionData.java

@ -6,6 +6,7 @@ import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -32,13 +33,21 @@ public class CancelSellNameTransactionData extends TransactionData {
this.creatorPublicKey = this.ownerPublicKey;
}
public CancelSellNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String name, BigDecimal fee, byte[] signature) {
super(TransactionType.CANCEL_SELL_NAME, timestamp, txGroupId, reference, ownerPublicKey, fee, signature);
/** From repository */
public CancelSellNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String name,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.CANCEL_SELL_NAME, timestamp, txGroupId, reference, ownerPublicKey, fee, approvalStatus, height, signature);
this.ownerPublicKey = ownerPublicKey;
this.name = name;
}
/** From network/API */
public CancelSellNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String name, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, ownerPublicKey, name, fee, null, null, signature);
}
/** New, unsigned */
public CancelSellNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String name, BigDecimal fee) {
this(timestamp, txGroupId, reference, ownerPublicKey, name, fee, null);
}

13
src/main/java/org/qora/data/transaction/CreateAssetOrderTransactionData.java

@ -8,6 +8,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import org.qora.block.BlockChain;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -80,8 +81,8 @@ public class CreateAssetOrderTransactionData extends TransactionData {
/** Constructs using data from repository, including optional asset names. */
public CreateAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, long haveAssetId, long wantAssetId,
BigDecimal amount, BigDecimal price, BigDecimal fee, String haveAssetName, String wantAssetName, byte[] signature) {
super(TransactionType.CREATE_ASSET_ORDER, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
BigDecimal amount, BigDecimal price, BigDecimal fee, String haveAssetName, String wantAssetName, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.CREATE_ASSET_ORDER, timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, height, signature);
this.haveAssetId = haveAssetId;
this.wantAssetId = wantAssetId;
@ -93,12 +94,18 @@ public class CreateAssetOrderTransactionData extends TransactionData {
}
/** Constructs using data from repository, excluding optional asset names. */
public CreateAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, long haveAssetId, long wantAssetId,
BigDecimal amount, BigDecimal price, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
this(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, null, null, approvalStatus, height, signature);
}
/** From network/API */
public CreateAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, long haveAssetId, long wantAssetId,
BigDecimal amount, BigDecimal price, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, null, null, signature);
}
/** Constructor typically used with data from network. */
/** New, unsigned */
public CreateAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, long haveAssetId, long wantAssetId,
BigDecimal amount, BigDecimal price, BigDecimal fee) {
this(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, null);

19
src/main/java/org/qora/data/transaction/CreateGroupTransactionData.java

@ -8,6 +8,7 @@ import javax.xml.bind.annotation.XmlElement;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import org.qora.group.Group.ApprovalThreshold;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -67,9 +68,11 @@ public class CreateGroupTransactionData extends TransactionData {
super(TransactionType.CREATE_GROUP);
}
/** From repository */
public CreateGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String owner, String groupName, String description,
boolean isOpen, ApprovalThreshold approvalThreshold, int minimumBlockDelay, int maximumBlockDelay, Integer groupId, BigDecimal fee, byte[] signature) {
super(TransactionType.CREATE_GROUP, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
boolean isOpen, ApprovalThreshold approvalThreshold, int minimumBlockDelay, int maximumBlockDelay, Integer groupId,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.CREATE_GROUP, timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, height, signature);
this.creatorPublicKey = creatorPublicKey;
this.owner = owner;
@ -82,6 +85,18 @@ public class CreateGroupTransactionData extends TransactionData {
this.groupId = groupId;
}
/** From network/API */
public CreateGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String owner, String groupName, String description,
boolean isOpen, ApprovalThreshold approvalThreshold, int minimumBlockDelay, int maximumBlockDelay, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, creatorPublicKey, owner, groupName, description, isOpen, approvalThreshold, minimumBlockDelay, maximumBlockDelay, null, fee, null, null, signature);
}
/** New, unsigned */
public CreateGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String owner, String groupName, String description,
boolean isOpen, ApprovalThreshold approvalThreshold, int minimumBlockDelay, int maximumBlockDelay, BigDecimal fee) {
this(timestamp, txGroupId, reference, creatorPublicKey, owner, groupName, description, isOpen, approvalThreshold, minimumBlockDelay, maximumBlockDelay, fee, null);
}
// Getters / setters
public String getOwner() {

14
src/main/java/org/qora/data/transaction/CreatePollTransactionData.java

@ -8,6 +8,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import org.qora.data.voting.PollOptionData;
import org.qora.transaction.Transaction;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -30,9 +31,11 @@ public class CreatePollTransactionData extends TransactionData {
super(TransactionType.CREATE_POLL);
}
/** From repository */
public CreatePollTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String owner,
String pollName, String description, List<PollOptionData> pollOptions, BigDecimal fee, byte[] signature) {
super(Transaction.TransactionType.CREATE_POLL, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
String pollName, String description, List<PollOptionData> pollOptions,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(Transaction.TransactionType.CREATE_POLL, timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, height, signature);
this.owner = owner;
this.pollName = pollName;
@ -40,6 +43,13 @@ public class CreatePollTransactionData extends TransactionData {
this.pollOptions = pollOptions;
}
/** From network/API */
public CreatePollTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String owner,
String pollName, String description, List<PollOptionData> pollOptions, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, creatorPublicKey, owner, pollName, description, pollOptions, fee, null, null, signature);
}
/** New, unsigned */
public CreatePollTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String owner,
String pollName, String description, List<PollOptionData> pollOptions, BigDecimal fee) {
this(timestamp, txGroupId, reference, creatorPublicKey, owner, pollName, description, pollOptions, fee, null);

12
src/main/java/org/qora/data/transaction/DeployAtTransactionData.java

@ -5,6 +5,7 @@ import java.math.BigDecimal;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -31,9 +32,10 @@ public class DeployAtTransactionData extends TransactionData {
super(TransactionType.DEPLOY_AT);
}
/** From repository */
public DeployAtTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String aTAddress, String name, String description,
String aTType, String tags, byte[] creationBytes, BigDecimal amount, long assetId, BigDecimal fee, byte[] signature) {
super(TransactionType.DEPLOY_AT, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
String aTType, String tags, byte[] creationBytes, BigDecimal amount, long assetId, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.DEPLOY_AT, timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, height, signature);
this.aTAddress = aTAddress;
this.name = name;
@ -45,14 +47,16 @@ public class DeployAtTransactionData extends TransactionData {
this.assetId = assetId;
}
/** From network/API */
public DeployAtTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String name, String description,
String aTType, String tags, byte[] creationBytes, BigDecimal amount, long assetId, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, creatorPublicKey, null, name, description, aTType, tags, creationBytes, amount, assetId, fee, signature);
this(timestamp, txGroupId, reference, creatorPublicKey, null, name, description, aTType, tags, creationBytes, amount, assetId, fee, null, null, signature);
}
/** New, unsigned */
public DeployAtTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String name, String description,
String aTType, String tags, byte[] creationBytes, BigDecimal amount, long assetId, BigDecimal fee) {
this(timestamp, txGroupId, reference, creatorPublicKey, null, name, description, aTType, tags, creationBytes, amount, assetId, fee, null);
this(timestamp, txGroupId, reference, creatorPublicKey, name, description, aTType, tags, creationBytes, amount, assetId, fee, null);
}
// Getters/Setters

13
src/main/java/org/qora/data/transaction/EnableForgingTransactionData.java

@ -6,6 +6,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -24,12 +25,20 @@ public class EnableForgingTransactionData extends TransactionData {
super(TransactionType.ENABLE_FORGING);
}
public EnableForgingTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, String target, BigDecimal fee, byte[] signature) {
super(TransactionType.ENABLE_FORGING, timestamp, groupId, reference, creatorPublicKey, fee, signature);
/** From repository */
public EnableForgingTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, String target,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.ENABLE_FORGING, timestamp, groupId, reference, creatorPublicKey, fee, approvalStatus, height, signature);
this.target = target;
}
/** From network/API */
public EnableForgingTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, String target, BigDecimal fee, byte[] signature) {
this(timestamp, groupId, reference, creatorPublicKey, target, fee, null, null, signature);
}
/** New, unsigned */
public EnableForgingTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, String target, BigDecimal fee) {
this(timestamp, groupId, reference, creatorPublicKey, target, fee, null);
}

12
src/main/java/org/qora/data/transaction/GenesisTransactionData.java

@ -8,6 +8,8 @@ import javax.xml.bind.annotation.XmlAccessorType;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import org.qora.account.GenesisAccount;
import org.qora.asset.Asset;
import org.qora.group.Group;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -35,23 +37,29 @@ public class GenesisTransactionData extends TransactionData {
super(TransactionType.GENESIS);
}
/** From repository (V2) */
public GenesisTransactionData(long timestamp, String recipient, BigDecimal amount, long assetId, byte[] signature) {
// no groupID, Zero fee
super(TransactionType.GENESIS, timestamp, 0, null, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, signature);
// No groupID, null reference, zero fee, no approval required, height always 1
super(TransactionType.GENESIS, timestamp, Group.NO_GROUP, null, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, ApprovalStatus.NOT_REQUIRED, 1, signature);
this.recipient = recipient;
this.amount = amount;
this.assetId = assetId;
}
/** From repository (V1, where asset locked to QORA) */
public GenesisTransactionData(long timestamp, String recipient, BigDecimal amount, byte[] signature) {
this(timestamp, recipient, amount, Asset.QORA, signature);
}
// Never from network/API!
/** New, unsigned (V2) */
public GenesisTransactionData(long timestamp, String recipient, BigDecimal amount, long assetId) {
this(timestamp, recipient, amount, assetId, null);
}
/** New, unsigned (V1) */
public GenesisTransactionData(long timestamp, String recipient, BigDecimal amount) {
this(timestamp, recipient, amount, Asset.QORA, null);
}

16
src/main/java/org/qora/data/transaction/GroupApprovalTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -55,9 +56,10 @@ public class GroupApprovalTransactionData extends TransactionData {
this.creatorPublicKey = this.adminPublicKey;
}
/** From repository */
public GroupApprovalTransactionData(long timestamp, int groupId, byte[] reference, byte[] adminPublicKey, byte[] pendingSignature, boolean approval,
byte[] priorReference, BigDecimal fee, byte[] signature) {
super(TransactionType.GROUP_APPROVAL, timestamp, groupId, reference, adminPublicKey, fee, signature);
byte[] priorReference, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.GROUP_APPROVAL, timestamp, groupId, reference, adminPublicKey, fee, approvalStatus, height, signature);
this.adminPublicKey = adminPublicKey;
this.pendingSignature = pendingSignature;
@ -65,10 +67,16 @@ public class GroupApprovalTransactionData extends TransactionData {
this.priorReference = priorReference;
}
/** Constructor typically used after deserialization */
/** From network/API */
public GroupApprovalTransactionData(long timestamp, int groupId, byte[] reference, byte[] adminPublicKey, byte[] pendingSignature, boolean approval,
BigDecimal fee, byte[] signature) {
this(timestamp, groupId, reference, adminPublicKey, pendingSignature, approval, null, fee, signature);
this(timestamp, groupId, reference, adminPublicKey, pendingSignature, approval, null, fee, null, null, signature);
}
/** New, unsigned */
public GroupApprovalTransactionData(long timestamp, int groupId, byte[] reference, byte[] adminPublicKey, byte[] pendingSignature, boolean approval,
BigDecimal fee) {
this(timestamp, groupId, reference, adminPublicKey, pendingSignature, approval, fee, null);
}
// Getters / setters

17
src/main/java/org/qora/data/transaction/GroupBanTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -75,9 +76,11 @@ public class GroupBanTransactionData extends TransactionData {
this.creatorPublicKey = this.adminPublicKey;
}
/** From repository */
public GroupBanTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member,
String reason, int timeToLive, byte[] memberReference, byte[] adminReference, byte[] joinInviteReference, Integer previousGroupId, BigDecimal fee, byte[] signature) {
super(TransactionType.GROUP_BAN, timestamp, txGroupId, reference, adminPublicKey, fee, signature);
String reason, int timeToLive, byte[] memberReference, byte[] adminReference, byte[] joinInviteReference, Integer previousGroupId,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.GROUP_BAN, timestamp, txGroupId, reference, adminPublicKey, fee, approvalStatus, height, signature);
this.adminPublicKey = adminPublicKey;
this.groupId = groupId;
@ -90,10 +93,16 @@ public class GroupBanTransactionData extends TransactionData {
this.previousGroupId = previousGroupId;
}
/** Constructor typically used after deserialization */
/** From network/API */
public GroupBanTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String offender, String reason,
int timeToLive, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, adminPublicKey, groupId, offender, reason, timeToLive, null, null, null, null, fee, signature);
this(timestamp, txGroupId, reference, adminPublicKey, groupId, offender, reason, timeToLive, null, null, null, null, fee, null, null, signature);
}
/** New, unsigned */
public GroupBanTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String offender, String reason,
int timeToLive, BigDecimal fee) {
this(timestamp, txGroupId, reference, adminPublicKey, groupId, offender, reason, timeToLive, fee, null);
}
// Getters / setters

15
src/main/java/org/qora/data/transaction/GroupInviteTransactionData.java

@ -8,6 +8,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -50,9 +51,10 @@ public class GroupInviteTransactionData extends TransactionData {
this.creatorPublicKey = this.adminPublicKey;
}
/** From repository */
public GroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, int timeToLive, byte[] joinReference, Integer previousGroupId,
BigDecimal fee, byte[] signature) {
super(TransactionType.GROUP_INVITE, timestamp, txGroupId, reference, adminPublicKey, fee, signature);
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.GROUP_INVITE, timestamp, txGroupId, reference, adminPublicKey, fee, approvalStatus, height, signature);
this.adminPublicKey = adminPublicKey;
this.groupId = groupId;
@ -62,9 +64,14 @@ public class GroupInviteTransactionData extends TransactionData {
this.previousGroupId = previousGroupId;
}
/** Constructor typically used after deserialization */
/** From network/API */
public GroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, int timeToLive, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, adminPublicKey, groupId, invitee, timeToLive, null, null, fee, signature);
this(timestamp, txGroupId, reference, adminPublicKey, groupId, invitee, timeToLive, null, null, fee, null, null, signature);
}
/** New, unsigned */
public GroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, int timeToLive, BigDecimal fee) {
this(timestamp, txGroupId, reference, adminPublicKey, groupId, invitee, timeToLive, fee, null);
}
// Getters / setters

16
src/main/java/org/qora/data/transaction/GroupKickTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -72,9 +73,11 @@ public class GroupKickTransactionData extends TransactionData {
this.creatorPublicKey = this.adminPublicKey;
}
/** From repository */
public GroupKickTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member,
String reason, byte[] memberReference, byte[] adminReference, byte[] joinReference, Integer previousGroupId, BigDecimal fee, byte[] signature) {
super(TransactionType.GROUP_KICK, timestamp, txGroupId, reference, adminPublicKey, fee, signature);
String reason, byte[] memberReference, byte[] adminReference, byte[] joinReference, Integer previousGroupId,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.GROUP_KICK, timestamp, txGroupId, reference, adminPublicKey, fee, approvalStatus, height, signature);
this.adminPublicKey = adminPublicKey;
this.groupId = groupId;
@ -86,10 +89,15 @@ public class GroupKickTransactionData extends TransactionData {
this.previousGroupId = previousGroupId;
}
/** Constructor typically used after deserialization */
/** From network/API */
public GroupKickTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member, String reason,
BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, adminPublicKey, groupId, member, reason, null, null, null, null, fee, signature);
this(timestamp, txGroupId, reference, adminPublicKey, groupId, member, reason, null, null, null, null, fee, null, null, signature);
}
/** New, unsigned */
public GroupKickTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member, String reason, BigDecimal fee) {
this(timestamp, txGroupId, reference, adminPublicKey, groupId, member, reason, fee, null);
}
// Getters / setters

13
src/main/java/org/qora/data/transaction/IssueAssetTransactionData.java

@ -9,6 +9,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import org.qora.account.GenesisAccount;
import org.qora.block.GenesisBlock;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -59,9 +60,11 @@ public class IssueAssetTransactionData extends TransactionData {
this.creatorPublicKey = this.issuerPublicKey;
}
/** From repository */
public IssueAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] issuerPublicKey, Long assetId, String owner,
String assetName, String description, long quantity, boolean isDivisible, String data, BigDecimal fee, byte[] signature) {
super(TransactionType.ISSUE_ASSET, timestamp, txGroupId, reference, issuerPublicKey, fee, signature);
String assetName, String description, long quantity, boolean isDivisible, String data,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.ISSUE_ASSET, timestamp, txGroupId, reference, issuerPublicKey, fee, approvalStatus, height, signature);
this.assetId = assetId;
this.issuerPublicKey = issuerPublicKey;
@ -73,14 +76,16 @@ public class IssueAssetTransactionData extends TransactionData {
this.data = data;
}
/** From network/API */
public IssueAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] issuerPublicKey, String owner, String assetName,
String description, long quantity, boolean isDivisible, String data, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, issuerPublicKey, null, owner, assetName, description, quantity, isDivisible, data, fee, signature);
this(timestamp, txGroupId, reference, issuerPublicKey, null, owner, assetName, description, quantity, isDivisible, data, fee, null, null, signature);
}
/** New, unsigned */
public IssueAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] issuerPublicKey, String owner, String assetName,
String description, long quantity, boolean isDivisible, String data, BigDecimal fee) {
this(timestamp, txGroupId, reference, issuerPublicKey, null, owner, assetName, description, quantity, isDivisible, data, fee, null);
this(timestamp, txGroupId, reference, issuerPublicKey, owner, assetName, description, quantity, isDivisible, data, fee, null);
}
// Getters/Setters

16
src/main/java/org/qora/data/transaction/JoinGroupTransactionData.java

@ -8,6 +8,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -46,8 +47,10 @@ public class JoinGroupTransactionData extends TransactionData {
this.creatorPublicKey = this.joinerPublicKey;
}
public JoinGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] joinerPublicKey, int groupId, byte[] inviteReference, Integer previousGroupId, BigDecimal fee, byte[] signature) {
super(TransactionType.JOIN_GROUP, timestamp, txGroupId, reference, joinerPublicKey, fee, signature);
/** From repository */
public JoinGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] joinerPublicKey, int groupId, byte[] inviteReference, Integer previousGroupId,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.JOIN_GROUP, timestamp, txGroupId, reference, joinerPublicKey, fee, approvalStatus, height, signature);
this.joinerPublicKey = joinerPublicKey;
this.groupId = groupId;
@ -55,9 +58,14 @@ public class JoinGroupTransactionData extends TransactionData {
this.previousGroupId = previousGroupId;
}
/** Constructor typically used after deserialization */
/** From network/API */
public JoinGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] joinerPublicKey, int groupId, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, joinerPublicKey, groupId, null, null, fee, signature);
this(timestamp, txGroupId, reference, joinerPublicKey, groupId, null, null, fee, null, null, signature);
}
/** New, unsigned */
public JoinGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] joinerPublicKey, int groupId, BigDecimal fee) {
this(timestamp, txGroupId, reference, joinerPublicKey, groupId, fee, null);
}
// Getters / setters

15
src/main/java/org/qora/data/transaction/LeaveGroupTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -48,9 +49,10 @@ public class LeaveGroupTransactionData extends TransactionData {
this.creatorPublicKey = this.leaverPublicKey;
}
/** From repository */
public LeaveGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] leaverPublicKey, int groupId, byte[] memberReference, byte[] adminReference, Integer previousGroupId,
BigDecimal fee, byte[] signature) {
super(TransactionType.LEAVE_GROUP, timestamp, txGroupId, reference, leaverPublicKey, fee, signature);
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.LEAVE_GROUP, timestamp, txGroupId, reference, leaverPublicKey, fee, approvalStatus, height, signature);
this.leaverPublicKey = leaverPublicKey;
this.groupId = groupId;
@ -59,9 +61,14 @@ public class LeaveGroupTransactionData extends TransactionData {
this.previousGroupId = previousGroupId;
}
/** Constructor typically used after deserialization */
/** From network/API */
public LeaveGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] leaverPublicKey, int groupId, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, leaverPublicKey, groupId, null, null, null, fee, signature);
this(timestamp, txGroupId, reference, leaverPublicKey, groupId, null, null, null, fee, null, null, signature);
}
/** New, unsigned */
public LeaveGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] leaverPublicKey, int groupId, BigDecimal fee) {
this(timestamp, txGroupId, reference, leaverPublicKey, groupId, fee, null);
}
// Getters / setters

13
src/main/java/org/qora/data/transaction/MessageTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.qora.asset.Asset;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -37,9 +38,10 @@ public class MessageTransactionData extends TransactionData {
this.creatorPublicKey = this.senderPublicKey;
}
/** From repository */
public MessageTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, int version, String recipient, Long assetId,
BigDecimal amount, byte[] data, boolean isText, boolean isEncrypted, BigDecimal fee, byte[] signature) {
super(TransactionType.MESSAGE, timestamp, txGroupId, reference, senderPublicKey, fee, signature);
BigDecimal amount, byte[] data, boolean isText, boolean isEncrypted, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.MESSAGE, timestamp, txGroupId, reference, senderPublicKey, fee, approvalStatus, height, signature);
this.senderPublicKey = senderPublicKey;
this.version = version;
@ -56,6 +58,13 @@ public class MessageTransactionData extends TransactionData {
this.isEncrypted = isEncrypted;
}
/** From network/API */
public MessageTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, int version, String recipient, Long assetId,
BigDecimal amount, byte[] data, boolean isText, boolean isEncrypted, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, senderPublicKey, version, recipient, assetId, amount, data, isText, isEncrypted, fee, null, null, signature);
}
/** New, unsigned */
public MessageTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, int version, String recipient, Long assetId,
BigDecimal amount, byte[] data, boolean isText, boolean isEncrypted, BigDecimal fee) {
this(timestamp, txGroupId, reference, senderPublicKey, version, recipient, assetId, amount, data, isText, isEncrypted, fee, null);

13
src/main/java/org/qora/data/transaction/MultiPaymentTransactionData.java

@ -9,6 +9,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import org.qora.data.PaymentData;
import org.qora.transaction.Transaction;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -33,13 +34,21 @@ public class MultiPaymentTransactionData extends TransactionData {
this.creatorPublicKey = this.senderPublicKey;
}
public MultiPaymentTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, List<PaymentData> payments, BigDecimal fee, byte[] signature) {
super(Transaction.TransactionType.MULTI_PAYMENT, timestamp, txGroupId, reference, senderPublicKey, fee, signature);
/** From repository */
public MultiPaymentTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, List<PaymentData> payments,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(Transaction.TransactionType.MULTI_PAYMENT, timestamp, txGroupId, reference, senderPublicKey, fee, approvalStatus, height, signature);
this.senderPublicKey = senderPublicKey;
this.payments = payments;
}
/** From network/API */
public MultiPaymentTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, List<PaymentData> payments, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, senderPublicKey, payments, fee, null, null, signature);
}
/** New, unsigned */
public MultiPaymentTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, List<PaymentData> payments, BigDecimal fee) {
this(timestamp, txGroupId, reference, senderPublicKey, payments, fee, null);
}

12
src/main/java/org/qora/data/transaction/PaymentTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -39,15 +40,22 @@ public class PaymentTransactionData extends TransactionData {
this.creatorPublicKey = this.senderPublicKey;
}
/** From repository */
public PaymentTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
BigDecimal fee, byte[] signature) {
super(TransactionType.PAYMENT, timestamp, txGroupId, reference, senderPublicKey, fee, signature);
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.PAYMENT, timestamp, txGroupId, reference, senderPublicKey, fee, approvalStatus, height, signature);
this.senderPublicKey = senderPublicKey;
this.recipient = recipient;
this.amount = amount;
}
/** From network/API */
public PaymentTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, fee, null, null, signature);
}
/** New, unsigned */
public PaymentTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount, BigDecimal fee) {
this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, fee, null);
}

20
src/main/java/org/qora/data/transaction/ProxyForgingTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -42,9 +43,11 @@ public class ProxyForgingTransactionData extends TransactionData {
this.creatorPublicKey = this.forgerPublicKey;
}
public ProxyForgingTransactionData(long timestamp, int groupId, byte[] reference, byte[] forgerPublicKey, String recipient, byte[] proxyPublicKey, BigDecimal share, BigDecimal previousShare, BigDecimal fee, byte[] signature) {
super(TransactionType.PROXY_FORGING, timestamp, groupId, reference, forgerPublicKey, fee, signature);
/** From repository */
public ProxyForgingTransactionData(long timestamp, int groupId, byte[] reference, byte[] forgerPublicKey, String recipient,
byte[] proxyPublicKey, BigDecimal share, BigDecimal previousShare,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.PROXY_FORGING, timestamp, groupId, reference, forgerPublicKey, fee, approvalStatus, height, signature);
this.forgerPublicKey = forgerPublicKey;
this.recipient = recipient;
@ -53,13 +56,14 @@ public class ProxyForgingTransactionData extends TransactionData {
this.previousShare = previousShare;
}
public ProxyForgingTransactionData(long timestamp, int groupId, byte[] reference, byte[] forgerPublicKey, String recipient, byte[] proxyPublicKey, BigDecimal share, BigDecimal fee) {
this(timestamp, groupId, reference, forgerPublicKey, recipient, proxyPublicKey, share, fee, null);
/** From network/API */
public ProxyForgingTransactionData(long timestamp, int groupId, byte[] reference, byte[] forgerPublicKey, String recipient, byte[] proxyPublicKey, BigDecimal share, BigDecimal fee, byte[] signature) {
this(timestamp, groupId, reference, forgerPublicKey, recipient, proxyPublicKey, share, null, fee, null, null, signature);
}
// Used in deserialization context
public ProxyForgingTransactionData(long timestamp, int groupId, byte[] reference, byte[] forgerPublicKey, String recipient, byte[] proxyPublicKey, BigDecimal share, BigDecimal fee, byte[] signature) {
this(timestamp, groupId, reference, forgerPublicKey, recipient, proxyPublicKey, share, null, fee, signature);
/** New, unsigned */
public ProxyForgingTransactionData(long timestamp, int groupId, byte[] reference, byte[] forgerPublicKey, String recipient, byte[] proxyPublicKey, BigDecimal share, BigDecimal fee) {
this(timestamp, groupId, reference, forgerPublicKey, recipient, proxyPublicKey, share, fee, null);
}
// Getters / setters

12
src/main/java/org/qora/data/transaction/RegisterNameTransactionData.java

@ -6,6 +6,7 @@ import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -36,9 +37,10 @@ public class RegisterNameTransactionData extends TransactionData {
this.creatorPublicKey = this.registrantPublicKey;
}
/** From repository */
public RegisterNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] registrantPublicKey, String owner, String name, String data,
BigDecimal fee, byte[] signature) {
super(TransactionType.REGISTER_NAME, timestamp, txGroupId, reference, registrantPublicKey, fee, signature);
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.REGISTER_NAME, timestamp, txGroupId, reference, registrantPublicKey, fee, approvalStatus, height, signature);
this.registrantPublicKey = registrantPublicKey;
this.owner = owner;
@ -46,6 +48,12 @@ public class RegisterNameTransactionData extends TransactionData {
this.data = data;
}
/** From network/API */
public RegisterNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] registrantPublicKey, String owner, String name, String data, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, registrantPublicKey, owner, name, data, fee, null, null, signature);
}
/** New, unsigned */
public RegisterNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] registrantPublicKey, String owner, String name, String data, BigDecimal fee) {
this(timestamp, txGroupId, reference, registrantPublicKey, owner, name, data, fee, null);
}

16
src/main/java/org/qora/data/transaction/RemoveGroupAdminTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -40,8 +41,10 @@ public class RemoveGroupAdminTransactionData extends TransactionData {
this.creatorPublicKey = this.ownerPublicKey;
}
public RemoveGroupAdminTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId, String admin, byte[] adminReference, BigDecimal fee, byte[] signature) {
super(TransactionType.REMOVE_GROUP_ADMIN, timestamp, txGroupId, reference, ownerPublicKey, fee, signature);
/** From repository */
public RemoveGroupAdminTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId, String admin, byte[] adminReference,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.REMOVE_GROUP_ADMIN, timestamp, txGroupId, reference, ownerPublicKey, fee, approvalStatus, height, signature);
this.ownerPublicKey = ownerPublicKey;
this.groupId = groupId;
@ -49,9 +52,14 @@ public class RemoveGroupAdminTransactionData extends TransactionData {
this.adminReference = adminReference;
}
/** Constructor typically used after deserialization */
/** From network/API */
public RemoveGroupAdminTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId, String admin, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, ownerPublicKey, groupId, admin, null, fee, signature);
this(timestamp, txGroupId, reference, ownerPublicKey, groupId, admin, null, fee, null, null, signature);
}
/** New, unsigned */
public RemoveGroupAdminTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId, String admin, BigDecimal fee) {
this(timestamp, txGroupId, reference, ownerPublicKey, groupId, admin, fee, null);
}
// Getters / setters

13
src/main/java/org/qora/data/transaction/SellNameTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -39,14 +40,22 @@ public class SellNameTransactionData extends TransactionData {
this.creatorPublicKey = this.ownerPublicKey;
}
public SellNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String name, BigDecimal amount, BigDecimal fee, byte[] signature) {
super(TransactionType.SELL_NAME, timestamp, txGroupId, reference, ownerPublicKey, fee, signature);
/** From repository */
public SellNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String name, BigDecimal amount,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.SELL_NAME, timestamp, txGroupId, reference, ownerPublicKey, fee, approvalStatus, height, signature);
this.ownerPublicKey = ownerPublicKey;
this.name = name;
this.amount = amount;
}
/** From network/API */
public SellNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String name, BigDecimal amount, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, ownerPublicKey, name, amount, fee, null, null, signature);
}
/** New, unsigned */
public SellNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String name, BigDecimal amount, BigDecimal fee) {
this(timestamp, txGroupId, reference, ownerPublicKey, name, amount, fee, null);
}

18
src/main/java/org/qora/data/transaction/SetGroupTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -41,18 +42,23 @@ public class SetGroupTransactionData extends TransactionData {
super(TransactionType.SET_GROUP);
}
/** From repository */
public SetGroupTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, int defaultGroupId, Integer previousDefaultGroupId,
BigDecimal fee, byte[] signature) {
super(TransactionType.SET_GROUP, timestamp, groupId, reference, creatorPublicKey, fee, signature);
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.SET_GROUP, timestamp, groupId, reference, creatorPublicKey, fee, approvalStatus, height, signature);
this.defaultGroupId = defaultGroupId;
this.previousDefaultGroupId = previousDefaultGroupId;
}
/** Constructor typically used after deserialization */
public SetGroupTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, int defaultGroupId, BigDecimal fee,
byte[] signature) {
this(timestamp, groupId, reference, creatorPublicKey, defaultGroupId, null, fee, signature);
/** From network/API */
public SetGroupTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, int defaultGroupId, BigDecimal fee, byte[] signature) {
this(timestamp, groupId, reference, creatorPublicKey, defaultGroupId, null, fee, null, null, signature);
}
/** New, unsigned */
public SetGroupTransactionData(long timestamp, int groupId, byte[] reference, byte[] creatorPublicKey, int defaultGroupId, BigDecimal fee) {
this(timestamp, groupId, reference, creatorPublicKey, defaultGroupId, fee, null);
}
// Getters / setters

33
src/main/java/org/qora/data/transaction/TransactionData.java

@ -12,6 +12,7 @@ import javax.xml.bind.annotation.XmlTransient;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode;
import org.qora.crypto.Crypto;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -62,8 +63,10 @@ public abstract class TransactionData {
protected byte[] signature;
@Schema(description = "groupID for this transaction")
protected int txGroupId;
@Schema(description = "group-approval status")
protected ApprovalStatus approvalStatus;
// For JAX-RS use
// Not always present
@Schema(accessMode = AccessMode.READ_ONLY, hidden = true, description = "height of block containing transaction")
protected Integer blockHeight;
@ -78,18 +81,20 @@ public abstract class TransactionData {
this.type = type;
}
public TransactionData(TransactionType type, long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) {
public TransactionData(TransactionType type, long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer blockHeight, byte[] signature) {
this.type = type;
this.timestamp = timestamp;
this.txGroupId = txGroupId;
this.reference = reference;
this.creatorPublicKey = creatorPublicKey;
this.fee = fee;
this.approvalStatus = approvalStatus;
this.blockHeight = blockHeight;
this.signature = signature;
}
public TransactionData(TransactionType type, long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee) {
this(type, timestamp, txGroupId, reference, creatorPublicKey, fee, null);
this(type, timestamp, txGroupId, reference, creatorPublicKey, fee, null, null, null);
}
// Getters/setters
@ -135,6 +140,14 @@ public abstract class TransactionData {
this.fee = fee;
}
public ApprovalStatus getApprovalStatus() {
return approvalStatus;
}
public void setApprovalStatus(ApprovalStatus approvalStatus) {
this.approvalStatus = approvalStatus;
}
public byte[] getSignature() {
return this.signature;
}
@ -143,6 +156,15 @@ public abstract class TransactionData {
this.signature = signature;
}
public Integer getBlockHeight() {
return this.blockHeight;
}
@XmlTransient
public void setBlockHeight(Integer blockHeight) {
this.blockHeight = blockHeight;
}
// JAXB special
@XmlElement(name = "creatorAddress")
@ -150,11 +172,6 @@ public abstract class TransactionData {
return Crypto.toAddress(this.creatorPublicKey);
}
@XmlTransient
public void setBlockHeight(int blockHeight) {
this.blockHeight = blockHeight;
}
// Comparison
@Override

15
src/main/java/org/qora/data/transaction/TransferAssetTransactionData.java

@ -6,6 +6,7 @@ import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -41,8 +42,8 @@ public class TransferAssetTransactionData extends TransactionData {
/** Constructs using data from repository, including optional assetName. */
public TransferAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
long assetId, BigDecimal fee, String assetName, byte[] signature) {
super(TransactionType.TRANSFER_ASSET, timestamp, txGroupId, reference, senderPublicKey, fee, signature);
long assetId, BigDecimal fee, String assetName, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.TRANSFER_ASSET, timestamp, txGroupId, reference, senderPublicKey, fee, approvalStatus, height, signature);
this.senderPublicKey = senderPublicKey;
this.recipient = recipient;
@ -52,12 +53,18 @@ public class TransferAssetTransactionData extends TransactionData {
}
/** Constructs using data from repository, excluding optional assetName. */
public TransferAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
long assetId, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, assetId, fee, null, null, null, signature);
}
/** From network/API */
public TransferAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
long assetId, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, assetId, fee, null, signature);
this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, assetId, fee, null, null, null, signature);
}
/** Constructs using data typically received over network. */
/** New, unsigned */
public TransferAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
long assetId, BigDecimal fee) {
this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, assetId, fee, null);

17
src/main/java/org/qora/data/transaction/UpdateAssetTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -42,9 +43,10 @@ public class UpdateAssetTransactionData extends TransactionData {
this.creatorPublicKey = this.ownerPublicKey;
}
/** From repository */
public UpdateAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, long assetId, String newOwner,
String newDescription, String newData, BigDecimal fee, byte[] orphanReference, byte[] signature) {
super(TransactionType.UPDATE_ASSET, timestamp, txGroupId, reference, ownerPublicKey, fee, signature);
String newDescription, String newData, BigDecimal fee, byte[] orphanReference, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.UPDATE_ASSET, timestamp, txGroupId, reference, ownerPublicKey, fee, approvalStatus, height, signature);
this.assetId = assetId;
this.ownerPublicKey = ownerPublicKey;
@ -54,9 +56,16 @@ public class UpdateAssetTransactionData extends TransactionData {
this.orphanReference = orphanReference;
}
/** From network/API */
public UpdateAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, long assetId, String newOwner,
String newDescription, String newData, BigDecimal fee, byte[] orphanReference) {
this(timestamp, txGroupId, reference, ownerPublicKey, assetId, newOwner, newDescription, newData, fee, orphanReference, null);
String newDescription, String newData, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, ownerPublicKey, assetId, newOwner, newDescription, newData, fee, null, null, null, signature);
}
/** New, unsigned */
public UpdateAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, long assetId, String newOwner,
String newDescription, String newData, BigDecimal fee) {
this(timestamp, txGroupId, reference, ownerPublicKey, assetId, newOwner, newDescription, newData, fee, null);
}
// Getters/Setters

24
src/main/java/org/qora/data/transaction/UpdateGroupTransactionData.java

@ -9,6 +9,7 @@ import javax.xml.bind.annotation.XmlTransient;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import org.qora.group.Group.ApprovalThreshold;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -81,9 +82,12 @@ public class UpdateGroupTransactionData extends TransactionData {
this.creatorPublicKey = this.ownerPublicKey;
}
/** From repository */
public UpdateGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId,
String newOwner, String newDescription, boolean newIsOpen, ApprovalThreshold newApprovalThreshold, int newMinimumBlockDelay, int newMaximumBlockDelay, byte[] groupReference, BigDecimal fee, byte[] signature) {
super(TransactionType.UPDATE_GROUP, timestamp, txGroupId, reference, ownerPublicKey, fee, signature);
String newOwner, String newDescription, boolean newIsOpen, ApprovalThreshold newApprovalThreshold,
int newMinimumBlockDelay, int newMaximumBlockDelay, byte[] groupReference,
BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.UPDATE_GROUP, timestamp, txGroupId, reference, ownerPublicKey, fee, approvalStatus, height, signature);
this.ownerPublicKey = ownerPublicKey;
this.newOwner = newOwner;
@ -96,10 +100,20 @@ public class UpdateGroupTransactionData extends TransactionData {
this.groupReference = groupReference;
}
/** Constructor typically used after deserialization */
/** From network/API */
public UpdateGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId,
String newOwner, String newDescription, boolean newIsOpen, ApprovalThreshold newApprovalThreshold, int newMinimumBlockDelay, int newMaximumBlockDelay, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, ownerPublicKey, groupId, newOwner, newDescription, newIsOpen, newApprovalThreshold, newMinimumBlockDelay, newMaximumBlockDelay, null, fee, signature);
String newOwner, String newDescription, boolean newIsOpen, ApprovalThreshold newApprovalThreshold,
int newMinimumBlockDelay, int newMaximumBlockDelay, BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, ownerPublicKey, groupId, newOwner, newDescription, newIsOpen, newApprovalThreshold,
newMinimumBlockDelay, newMaximumBlockDelay, null, fee, null, null, signature);
}
/** New, unsigned */
public UpdateGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId,
String newOwner, String newDescription, boolean newIsOpen, ApprovalThreshold newApprovalThreshold,
int newMinimumBlockDelay, int newMaximumBlockDelay, BigDecimal fee) {
this(timestamp, txGroupId, reference, ownerPublicKey, groupId, newOwner, newDescription, newIsOpen, newApprovalThreshold,
newMinimumBlockDelay, newMaximumBlockDelay, fee, null);
}
// Getters / setters

14
src/main/java/org/qora/data/transaction/UpdateNameTransactionData.java

@ -7,6 +7,7 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -41,9 +42,10 @@ public class UpdateNameTransactionData extends TransactionData {
this.creatorPublicKey = this.ownerPublicKey;
}
/** From repository */
public UpdateNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String newOwner, String name, String newData,
byte[] nameReference, BigDecimal fee, byte[] signature) {
super(TransactionType.UPDATE_NAME, timestamp, txGroupId, reference, ownerPublicKey, fee, signature);
byte[] nameReference, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.UPDATE_NAME, timestamp, txGroupId, reference, ownerPublicKey, fee, approvalStatus, height, signature);
this.ownerPublicKey = ownerPublicKey;
this.newOwner = newOwner;
@ -52,14 +54,16 @@ public class UpdateNameTransactionData extends TransactionData {
this.nameReference = nameReference;
}
/** From network/API */
public UpdateNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String newOwner, String name, String newData,
BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, ownerPublicKey, newOwner, name, newData, null, fee, signature);
this(timestamp, txGroupId, reference, ownerPublicKey, newOwner, name, newData, null, fee, null, null, signature);
}
/** New, unsigned */
public UpdateNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String newOwner, String name, String newData,
byte[] nameReference, BigDecimal fee) {
this(timestamp, txGroupId, reference, ownerPublicKey, newOwner, name, newData, nameReference, fee, null);
BigDecimal fee) {
this(timestamp, txGroupId, reference, ownerPublicKey, newOwner, name, newData, fee, null);
}
// Getters / setters

12
src/main/java/org/qora/data/transaction/VoteOnPollTransactionData.java

@ -6,6 +6,7 @@ import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema;
@ -32,9 +33,10 @@ public class VoteOnPollTransactionData extends TransactionData {
this.creatorPublicKey = this.voterPublicKey;
}
/** From repository */
public VoteOnPollTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] voterPublicKey, String pollName, int optionIndex,
Integer previousOptionIndex, BigDecimal fee, byte[] signature) {
super(TransactionType.VOTE_ON_POLL, timestamp, txGroupId, reference, voterPublicKey, fee, signature);
Integer previousOptionIndex, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) {
super(TransactionType.VOTE_ON_POLL, timestamp, txGroupId, reference, voterPublicKey, fee, approvalStatus, height, signature);
this.voterPublicKey = voterPublicKey;
this.pollName = pollName;
@ -42,13 +44,15 @@ public class VoteOnPollTransactionData extends TransactionData {
this.previousOptionIndex = previousOptionIndex;
}
/** From network/API */
public VoteOnPollTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] voterPublicKey, String pollName, int optionIndex,
BigDecimal fee, byte[] signature) {
this(timestamp, txGroupId, reference, voterPublicKey, pollName, optionIndex, null, fee, signature);
this(timestamp, txGroupId, reference, voterPublicKey, pollName, optionIndex, null, fee, null, null, signature);
}
/** New, unsigned */
public VoteOnPollTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] voterPublicKey, String pollName, int optionIndex, BigDecimal fee) {
this(timestamp, txGroupId, reference, voterPublicKey, pollName, optionIndex, null, fee, null);
this(timestamp, txGroupId, reference, voterPublicKey, pollName, optionIndex, fee, null);
}
// Getters / setters

24
src/main/java/org/qora/group/Group.java

@ -58,34 +58,12 @@ public class Group {
return map.get(value);
}
private boolean meetsTheshold(int currentApprovals, int totalAdmins) {
public boolean meetsTheshold(int currentApprovals, int totalAdmins) {
if (!this.isPercentage)
return currentApprovals >= this.value;
return currentApprovals >= (totalAdmins * this.value / 100);
}
/**
* Returns whether transaction meets approval threshold.
*
* @param repository
* @param txGroupId
* transaction's groupID
* @param signature
* transaction's signature
* @return true if approval still needed, false if transaction can be included in block
* @throws DataException
*/
public boolean meetsApprovalThreshold(Repository repository, int txGroupId, byte[] signature) throws DataException {
// Fetch total number of admins in group
final int totalAdmins = repository.getGroupRepository().countGroupAdmins(txGroupId);
// Fetch total number of approvals for signature
// NOT simply number of GROUP_APPROVE transactions as some may be rejecting transaction, or changed opinions
final int currentApprovals = repository.getTransactionRepository().countTransactionApprovals(txGroupId, signature);
return meetsTheshold(currentApprovals, totalAdmins);
}
}
// Properties

39
src/main/java/org/qora/repository/TransactionRepository.java

@ -4,6 +4,7 @@ import java.util.List;
import java.util.Map;
import org.qora.api.resource.TransactionsResource.ConfirmationStatus;
import org.qora.data.group.GroupApprovalData;
import org.qora.data.transaction.GroupApprovalTransactionData;
import org.qora.data.transaction.TransactionData;
import org.qora.data.transaction.TransferAssetTransactionData;
@ -88,21 +89,41 @@ public interface TransactionRepository {
* @return list of transactions, or empty if none.
* @throws DataException
*/
public List<TransactionData> getPendingTransactions(Integer txGroupId, Integer limit, Integer offset, Boolean reverse) throws DataException;
public List<TransactionData> getApprovalPendingTransactions(Integer txGroupId, Integer limit, Integer offset, Boolean reverse) throws DataException;
/** Returns number of approvals for transaction with given signature. */
public int countTransactionApprovals(int txGroupId, byte[] signature) throws DataException;
/**
* Returns list of transactions pending approval that can be resolved as of passed blockHeight.
* <p>
* Typically called by Block.process().
*
* @param blockHeight
* @return
* @throws DataException
*/
public List<TransactionData> getApprovalPendingTransactions(int blockHeight) throws DataException;
/**
* Returns list of latest approval decisions per admin for given pending transaction signature.
* Returns list of transactions that have now expired as of passed blockHeight.
* <p>
* Typically called by Block.process().
*
* @param signature
* @param adminPublicKey
* restrict results to decision by this admin, pass null for all admins' results
* @param blockHeight
* @return
* @throws DataException
*/
public List<GroupApprovalTransactionData> getLatestApprovals(byte[] pendingSignature, byte[] adminPublicKey) throws DataException;
public List<TransactionData> getApprovalExpiringTransactions(int blockHeight) throws DataException;
/** Returns latest approval decision by given admin for given pending transaction signature. */
public GroupApprovalTransactionData getLatestApproval(byte[] pendingSignature, byte[] adminPublicKey) throws DataException;
/**
* Returns list of latest approval decisions for given pending transaction signature.
*
* @param pendingSignature
* @return
* @throws DataException
*/
public GroupApprovalData getApprovalData(byte[] pendingSignature) throws DataException;
/**
* Returns whether transaction is confirmed or not.
@ -143,6 +164,8 @@ public interface TransactionRepository {
*/
public void confirmTransaction(byte[] signature) throws DataException;
public void updateHeight(byte[] signature, Integer height) throws DataException;
/**
* Add transaction to unconfirmed transactions pile.
*

17
src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java

@ -737,6 +737,23 @@ public class HSQLDBDatabaseUpdates {
stmt.execute("ALTER TABLE Peers ADD COLUMN last_block_generator QoraPublicKey BEFORE last_misbehaved");
break;
case 50:
// Cached block height in Transactions to save loads of JOINs
stmt.execute("ALTER TABLE Transactions ADD COLUMN height INT");
// Add height-based index
stmt.execute("CREATE INDEX TransactionHeightIndex on Transactions (height)");
break;
case 51:
// Transaction group-approval rework
// Add index to GroupApprovalTransactions
stmt.execute("CREATE INDEX GroupApprovalLatestIndex on GroupApprovalTransactions (pending_signature, admin)");
// Transaction's approval status (Java enum) stored as tiny integer for efficiency
stmt.execute("ALTER TABLE Transactions ADD COLUMN approval_status TINYINT NOT NULL");
// For search transactions based on approval status
stmt.execute("CREATE INDEX TransactionApprovalStatusIndex on Transactions (approval_status, height)");
break;
default:
// nothing to do
return false;

7
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBAccountFlagsTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBAccountFlagsTransactionRepository extends HSQLDBTransactionRe
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT target, and_mask, or_mask, xor_mask, previous_flags FROM AccountFlagsTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -31,8 +32,8 @@ public class HSQLDBAccountFlagsTransactionRepository extends HSQLDBTransactionRe
if (resultSet.wasNull())
previousFlags = null;
return new AccountFlagsTransactionData(timestamp, txGroupId, reference, creatorPublicKey, target, andMask, orMask, xorMask, previousFlags, fee,
signature);
return new AccountFlagsTransactionData(timestamp, txGroupId, reference, creatorPublicKey, target, andMask, orMask, xorMask, previousFlags,
fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch account flags transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBAddGroupAdminTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBAddGroupAdminTransactionRepository extends HSQLDBTransactionR
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT group_id, address FROM AddGroupAdminTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
return null;
@ -24,7 +25,7 @@ public class HSQLDBAddGroupAdminTransactionRepository extends HSQLDBTransactionR
int groupId = resultSet.getInt(1);
String member = resultSet.getString(2);
return new AddGroupAdminTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, member, fee, signature);
return new AddGroupAdminTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, member, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch add group admin transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java

@ -12,6 +12,7 @@ import org.qora.data.transaction.ArbitraryTransactionData.DataType;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBArbitraryTransactionRepository extends HSQLDBTransactionRepository {
@ -19,7 +20,7 @@ public class HSQLDBArbitraryTransactionRepository extends HSQLDBTransactionRepos
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT version, service, data_hash from ArbitraryTransactions WHERE signature = ?",
signature)) {
if (resultSet == null)
@ -32,7 +33,7 @@ public class HSQLDBArbitraryTransactionRepository extends HSQLDBTransactionRepos
List<PaymentData> payments = this.getPaymentsFromSignature(signature);
return new ArbitraryTransactionData(timestamp, txGroupId, reference, creatorPublicKey, version, service, dataHash, DataType.DATA_HASH, payments,
fee, signature);
fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch arbitrary transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBAtTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBAtTransactionRepository extends HSQLDBTransactionRepository {
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT AT_address, recipient, amount, asset_id, message FROM ATTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -37,7 +38,7 @@ public class HSQLDBAtTransactionRepository extends HSQLDBTransactionRepository {
if (resultSet.wasNull())
message = null;
return new ATTransactionData(timestamp, txGroupId, reference, atAddress, recipient, amount, assetId, message, fee, signature);
return new ATTransactionData(timestamp, txGroupId, reference, atAddress, recipient, amount, assetId, message, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch AT transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBBuyNameTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBBuyNameTransactionRepository extends HSQLDBTransactionReposit
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT name, amount, seller, name_reference FROM BuyNameTransactions WHERE signature = ?",
signature)) {
if (resultSet == null)
@ -27,7 +28,7 @@ public class HSQLDBBuyNameTransactionRepository extends HSQLDBTransactionReposit
String seller = resultSet.getString(3);
byte[] nameReference = resultSet.getBytes(4);
return new BuyNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, name, amount, seller, nameReference, fee, signature);
return new BuyNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, name, amount, seller, nameReference, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch buy name transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBCancelAssetOrderTransactionRepository extends HSQLDBTransactionRepository {
@ -16,14 +17,14 @@ public class HSQLDBCancelAssetOrderTransactionRepository extends HSQLDBTransacti
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT asset_order_id FROM CancelAssetOrderTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
return null;
byte[] assetOrderId = resultSet.getBytes(1);
return new CancelAssetOrderTransactionData(timestamp, txGroupId, reference, creatorPublicKey, assetOrderId, fee, signature);
return new CancelAssetOrderTransactionData(timestamp, txGroupId, reference, creatorPublicKey, assetOrderId, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch cancel order transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBCancelGroupBanTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBCancelGroupBanTransactionRepository extends HSQLDBTransaction
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT group_id, address, ban_reference FROM CancelGroupBanTransactions WHERE signature = ?",
signature)) {
if (resultSet == null)
@ -26,7 +27,7 @@ public class HSQLDBCancelGroupBanTransactionRepository extends HSQLDBTransaction
String member = resultSet.getString(2);
byte[] banReference = resultSet.getBytes(3);
return new CancelGroupBanTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, member, banReference, fee, signature);
return new CancelGroupBanTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, member, banReference, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch group unban transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBCancelGroupInviteTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBCancelGroupInviteTransactionRepository extends HSQLDBTransact
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT group_id, invitee, invite_reference FROM CancelGroupInviteTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -26,7 +27,7 @@ public class HSQLDBCancelGroupInviteTransactionRepository extends HSQLDBTransact
String invitee = resultSet.getString(2);
byte[] inviteReference = resultSet.getBytes(3);
return new CancelGroupInviteTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, invitee, inviteReference, fee, signature);
return new CancelGroupInviteTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, invitee, inviteReference, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch cancel group invite transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBCancelSellNameTransactionRepository extends HSQLDBTransactionRepository {
@ -16,14 +17,14 @@ public class HSQLDBCancelSellNameTransactionRepository extends HSQLDBTransaction
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT name FROM CancelSellNameTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
return null;
String name = resultSet.getString(1);
return new CancelSellNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, name, fee, signature);
return new CancelSellNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, name, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch cancel sell name transaction from repository", e);
}

6
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBCreateAssetOrderTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBCreateAssetOrderTransactionRepository extends HSQLDBTransacti
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
String sql = "SELECT have_asset_id, amount, want_asset_id, price, HaveAsset.asset_name, WantAsset.asset_name "
+ "FROM CreateAssetOrderTransactions "
+ "JOIN Assets AS HaveAsset ON HaveAsset.asset_id = have_asset_id "
@ -34,7 +35,8 @@ public class HSQLDBCreateAssetOrderTransactionRepository extends HSQLDBTransacti
String haveAssetName = resultSet.getString(5);
String wantAssetName = resultSet.getString(6);
return new CreateAssetOrderTransactionData(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, haveAssetName, wantAssetName, signature);
return new CreateAssetOrderTransactionData(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee,
haveAssetName, wantAssetName, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch create order transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java

@ -10,6 +10,7 @@ import org.qora.group.Group.ApprovalThreshold;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBCreateGroupTransactionRepository extends HSQLDBTransactionRepository {
@ -17,7 +18,7 @@ public class HSQLDBCreateGroupTransactionRepository extends HSQLDBTransactionRep
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT owner, group_name, description, is_open, approval_threshold, min_block_delay, max_block_delay, group_id FROM CreateGroupTransactions WHERE signature = ?",
signature)) {
@ -39,7 +40,7 @@ public class HSQLDBCreateGroupTransactionRepository extends HSQLDBTransactionRep
groupId = null;
return new CreateGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, owner, groupName, description, isOpen, approvalThreshold,
minBlockDelay, maxBlockDelay, groupId, fee, signature);
minBlockDelay, maxBlockDelay, groupId, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch create group transaction from repository", e);
}

6
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java

@ -12,6 +12,7 @@ import org.qora.data.voting.PollOptionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBCreatePollTransactionRepository extends HSQLDBTransactionRepository {
@ -19,7 +20,7 @@ public class HSQLDBCreatePollTransactionRepository extends HSQLDBTransactionRepo
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT owner, poll_name, description FROM CreatePollTransactions WHERE signature = ?",
signature)) {
if (resultSet == null)
@ -43,7 +44,8 @@ public class HSQLDBCreatePollTransactionRepository extends HSQLDBTransactionRepo
pollOptions.add(new PollOptionData(optionName));
} while (optionsResultSet.next());
return new CreatePollTransactionData(timestamp, txGroupId, reference, creatorPublicKey, owner, pollName, description, pollOptions, fee, signature);
return new CreatePollTransactionData(timestamp, txGroupId, reference, creatorPublicKey, owner, pollName, description, pollOptions,
fee, approvalStatus, height, signature);
}
} catch (SQLException e) {
throw new DataException("Unable to fetch create poll transaction from repository", e);

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBDeployAtTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBDeployAtTransactionRepository extends HSQLDBTransactionReposi
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT AT_name, description, AT_type, AT_tags, creation_bytes, amount, asset_id, AT_address FROM DeployATTransactions WHERE signature = ?",
signature)) {
@ -37,7 +38,7 @@ public class HSQLDBDeployAtTransactionRepository extends HSQLDBTransactionReposi
atAddress = null;
return new DeployAtTransactionData(timestamp, txGroupId, reference, creatorPublicKey, atAddress, name, description, atType, tags, creationBytes, amount,
assetId, fee, signature);
assetId, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch deploy AT transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBEnableForgingTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBEnableForgingTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBEnableForgingTransactionRepository extends HSQLDBTransactionR
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT target FROM EnableForgingTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -24,7 +25,7 @@ public class HSQLDBEnableForgingTransactionRepository extends HSQLDBTransactionR
String target = resultSet.getString(1);
return new EnableForgingTransactionData(timestamp, txGroupId, reference, creatorPublicKey, target, fee, signature);
return new EnableForgingTransactionData(timestamp, txGroupId, reference, creatorPublicKey, target, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch account flags transaction from repository", e);
}

3
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBGenesisTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBGenesisTransactionRepository extends HSQLDBTransactionReposit
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT recipient, amount, asset_id FROM GenesisTransactions WHERE signature = ?",
signature)) {
if (resultSet == null)

7
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBGroupApprovalTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBGroupApprovalTransactionRepository extends HSQLDBTransactionR
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT pending_signature, approval, prior_reference FROM GroupApprovalTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -26,8 +27,8 @@ public class HSQLDBGroupApprovalTransactionRepository extends HSQLDBTransactionR
boolean approval = resultSet.getBoolean(2);
byte[] priorReference = resultSet.getBytes(3);
return new GroupApprovalTransactionData(timestamp, txGroupId, reference, creatorPublicKey, pendingSignature, approval, priorReference, fee,
signature);
return new GroupApprovalTransactionData(timestamp, txGroupId, reference, creatorPublicKey, pendingSignature, approval, priorReference,
fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch group approval transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBGroupBanTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBGroupBanTransactionRepository extends HSQLDBTransactionReposi
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT group_id, address, reason, time_to_live, member_reference, admin_reference, join_invite_reference, previous_group_id FROM GroupBanTransactions WHERE signature = ?",
signature)) {
@ -36,7 +37,7 @@ public class HSQLDBGroupBanTransactionRepository extends HSQLDBTransactionReposi
previousGroupId = null;
return new GroupBanTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, offender, reason, timeToLive,
memberReference, adminReference, joinInviteReference, previousGroupId, fee, signature);
memberReference, adminReference, joinInviteReference, previousGroupId, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch group ban transaction from repository", e);
}

6
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBGroupInviteTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBGroupInviteTransactionRepository extends HSQLDBTransactionRep
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT group_id, invitee, time_to_live, join_reference, previous_group_id FROM GroupInviteTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -31,7 +32,8 @@ public class HSQLDBGroupInviteTransactionRepository extends HSQLDBTransactionRep
if (resultSet.wasNull())
previousGroupId = null;
return new GroupInviteTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, invitee, timeToLive, joinReference, previousGroupId, fee, signature);
return new GroupInviteTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, invitee, timeToLive, joinReference, previousGroupId,
fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch group invite transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBGroupKickTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBGroupKickTransactionRepository extends HSQLDBTransactionRepos
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT group_id, address, reason, member_reference, admin_reference, join_reference, previous_group_id FROM GroupKickTransactions WHERE signature = ?",
signature)) {
@ -35,7 +36,7 @@ public class HSQLDBGroupKickTransactionRepository extends HSQLDBTransactionRepos
previousGroupId = null;
return new GroupKickTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, member, reason, memberReference, adminReference,
joinReference, previousGroupId, fee, signature);
joinReference, previousGroupId, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch group kick transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepo
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT owner, asset_name, description, quantity, is_divisible, data, asset_id FROM IssueAssetTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -35,7 +36,7 @@ public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepo
assetId = null;
return new IssueAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, assetId, owner, assetName, description, quantity, isDivisible,
data, fee, signature);
data, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch issue asset transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBJoinGroupTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBJoinGroupTransactionRepository extends HSQLDBTransactionRepos
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT group_id, invite_reference, previous_group_id FROM JoinGroupTransactions WHERE signature = ?",
signature)) {
if (resultSet == null)
@ -29,7 +30,7 @@ public class HSQLDBJoinGroupTransactionRepository extends HSQLDBTransactionRepos
if (resultSet.wasNull())
previousGroupId = null;
return new JoinGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, inviteReference, previousGroupId, fee, signature);
return new JoinGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, inviteReference, previousGroupId, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch join group transaction from repository", e);
}

6
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBLeaveGroupTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBLeaveGroupTransactionRepository extends HSQLDBTransactionRepo
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT group_id, member_reference, admin_reference, previous_group_id FROM LeaveGroupTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -30,7 +31,8 @@ public class HSQLDBLeaveGroupTransactionRepository extends HSQLDBTransactionRepo
if (resultSet.wasNull())
previousGroupId = null;
return new LeaveGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, memberReference, adminReference, previousGroupId, fee, signature);
return new LeaveGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, memberReference, adminReference, previousGroupId,
fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch leave group transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBMessageTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBMessageTransactionRepository extends HSQLDBTransactionReposit
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT version, recipient, is_text, is_encrypted, amount, asset_id, data FROM MessageTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -36,7 +37,7 @@ public class HSQLDBMessageTransactionRepository extends HSQLDBTransactionReposit
byte[] data = resultSet.getBytes(7);
return new MessageTransactionData(timestamp, txGroupId, reference, creatorPublicKey, version, recipient, assetId, amount, data, isText, isEncrypted,
fee, signature);
fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch message transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java

@ -11,6 +11,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBMultiPaymentTransactionRepository extends HSQLDBTransactionRepository {
@ -18,14 +19,14 @@ public class HSQLDBMultiPaymentTransactionRepository extends HSQLDBTransactionRe
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT TRUE from MultiPaymentTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
return null;
List<PaymentData> payments = this.getPaymentsFromSignature(signature);
return new MultiPaymentTransactionData(timestamp, txGroupId, reference, creatorPublicKey, payments, fee, signature);
return new MultiPaymentTransactionData(timestamp, txGroupId, reference, creatorPublicKey, payments, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch multi-payment transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBPaymentTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBPaymentTransactionRepository extends HSQLDBTransactionReposit
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT recipient, amount FROM PaymentTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
return null;
@ -24,7 +25,7 @@ public class HSQLDBPaymentTransactionRepository extends HSQLDBTransactionReposit
String recipient = resultSet.getString(1);
BigDecimal amount = resultSet.getBigDecimal(2);
return new PaymentTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, fee, signature);
return new PaymentTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch payment transaction from repository", e);
}

6
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBProxyForgingTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBProxyForgingTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBProxyForgingTransactionRepository extends HSQLDBTransactionRe
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT recipient, proxy_public_key, share, previous_share FROM ProxyForgingTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -27,7 +28,8 @@ public class HSQLDBProxyForgingTransactionRepository extends HSQLDBTransactionRe
BigDecimal share = resultSet.getBigDecimal(3);
BigDecimal previousShare = resultSet.getBigDecimal(4);
return new ProxyForgingTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, proxyPublicKey, share, previousShare, fee, signature);
return new ProxyForgingTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, proxyPublicKey, share, previousShare,
fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch proxy forging transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBRegisterNameTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBRegisterNameTransactionRepository extends HSQLDBTransactionRe
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT owner, name, data FROM RegisterNameTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
return null;
@ -25,7 +26,7 @@ public class HSQLDBRegisterNameTransactionRepository extends HSQLDBTransactionRe
String name = resultSet.getString(2);
String data = resultSet.getString(3);
return new RegisterNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, owner, name, data, fee, signature);
return new RegisterNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, owner, name, data, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch register name transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBRemoveGroupAdminTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBRemoveGroupAdminTransactionRepository extends HSQLDBTransacti
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT group_id, admin, admin_reference FROM RemoveGroupAdminTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -26,7 +27,7 @@ public class HSQLDBRemoveGroupAdminTransactionRepository extends HSQLDBTransacti
String admin = resultSet.getString(2);
byte[] adminReference = resultSet.getBytes(3);
return new RemoveGroupAdminTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, admin, adminReference, fee, signature);
return new RemoveGroupAdminTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, admin, adminReference, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch remove group admin transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBSellNameTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBSellNameTransactionRepository extends HSQLDBTransactionReposi
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT name, amount FROM SellNameTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
return null;
@ -24,7 +25,7 @@ public class HSQLDBSellNameTransactionRepository extends HSQLDBTransactionReposi
String name = resultSet.getString(1);
BigDecimal amount = resultSet.getBigDecimal(2);
return new SellNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, name, amount, fee, signature);
return new SellNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, name, amount, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch sell name transaction from repository", e);
}

6
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBSetGroupTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBSetGroupTransactionRepository extends HSQLDBTransactionReposi
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT default_group_id, previous_default_group_id FROM SetGroupTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -27,7 +28,8 @@ public class HSQLDBSetGroupTransactionRepository extends HSQLDBTransactionReposi
if (resultSet.wasNull())
previousDefaultGroupId = null;
return new SetGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, defaultGroupId, previousDefaultGroupId, fee, signature);
return new SetGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, defaultGroupId, previousDefaultGroupId,
fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch set group transaction from repository", e);
}

349
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java

@ -9,7 +9,6 @@ import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import static java.util.Arrays.stream;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
@ -20,15 +19,15 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.qora.api.resource.TransactionsResource.ConfirmationStatus;
import org.qora.data.PaymentData;
import org.qora.data.group.GroupApprovalData;
import org.qora.data.transaction.GroupApprovalTransactionData;
import org.qora.data.transaction.TransactionData;
import org.qora.data.transaction.TransferAssetTransactionData;
import org.qora.group.Group;
import org.qora.repository.DataException;
import org.qora.repository.TransactionRepository;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction;
import org.qora.transaction.Transaction.ApprovalStatus;
import org.qora.transaction.Transaction.TransactionType;
import static org.qora.transaction.Transaction.TransactionType.*;
@ -69,7 +68,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
try {
// params: long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature
subclassInfo.fromBaseMethod = subclassInfo.clazz.getDeclaredMethod("fromBase", long.class, int.class, byte[].class, byte[].class, BigDecimal.class, byte[].class);
subclassInfo.fromBaseMethod = subclassInfo.clazz.getDeclaredMethod("fromBase", long.class, int.class, byte[].class, byte[].class, BigDecimal.class, ApprovalStatus.class, Integer.class, byte[].class);
} catch (IllegalArgumentException | SecurityException | NoSuchMethodException e) {
LOGGER.debug(String.format("HSQLDBTransactionRepository subclass's \"fromBase\" method not found for transaction type \"%s\"", txType.name()));
}
@ -129,7 +128,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public TransactionData fromSignature(byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT type, reference, creator, creation, fee, tx_group_id FROM Transactions WHERE signature = ?",
try (ResultSet resultSet = this.repository.checkedExecute("SELECT type, reference, creator, creation, fee, tx_group_id, approval_status, height FROM Transactions WHERE signature = ?",
signature)) {
if (resultSet == null)
return null;
@ -140,9 +139,14 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
long timestamp = resultSet.getTimestamp(4, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
BigDecimal fee = resultSet.getBigDecimal(5).setScale(8);
int txGroupId = resultSet.getInt(6);
ApprovalStatus approvalStatus = ApprovalStatus.valueOf(resultSet.getInt(7));
TransactionData transactionData = this.fromBase(type, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
return maybeIncludeBlockHeight(transactionData);
Integer height = resultSet.getInt(8);
if (resultSet.wasNull())
height = null;
TransactionData transactionData = this.fromBase(type, timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, height, signature);
return transactionData;
} catch (SQLException e) {
throw new DataException("Unable to fetch transaction from repository", e);
}
@ -150,7 +154,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public TransactionData fromReference(byte[] reference) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT type, signature, creator, creation, fee, tx_group_id FROM Transactions WHERE reference = ?",
try (ResultSet resultSet = this.repository.checkedExecute("SELECT type, signature, creator, creation, fee, tx_group_id, approval_status, height FROM Transactions WHERE reference = ?",
reference)) {
if (resultSet == null)
return null;
@ -161,27 +165,24 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
long timestamp = resultSet.getTimestamp(4, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
BigDecimal fee = resultSet.getBigDecimal(5).setScale(8);
int txGroupId = resultSet.getInt(6);
ApprovalStatus approvalStatus = ApprovalStatus.valueOf(resultSet.getInt(7));
Integer height = resultSet.getInt(8);
if (resultSet.wasNull())
height = null;
TransactionData transactionData = this.fromBase(type, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
return maybeIncludeBlockHeight(transactionData);
TransactionData transactionData = this.fromBase(type, timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, height, signature);
return transactionData;
} catch (SQLException e) {
throw new DataException("Unable to fetch transaction from repository", e);
}
}
private TransactionData maybeIncludeBlockHeight(TransactionData transactionData) throws DataException {
int blockHeight = getHeightFromSignature(transactionData.getSignature());
if (blockHeight != 0)
transactionData.setBlockHeight(blockHeight);
return transactionData;
}
@Override
public TransactionData fromHeightAndSequence(int height, int sequence) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT transaction_signature FROM BlockTransactions JOIN Blocks ON signature = block_signature WHERE height = ? AND sequence = ?", height,
sequence)) {
String sql = "SELECT transaction_signature FROM BlockTransactions JOIN Blocks ON signature = block_signature WHERE height = ? AND sequence = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, height, sequence)) {
if (resultSet == null)
return null;
@ -189,19 +190,19 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
return this.fromSignature(signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch transaction from repository", e);
throw new DataException("Unable to fetch transaction height and sequence from repository", e);
}
}
private TransactionData fromBase(TransactionType type, long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature)
private TransactionData fromBase(TransactionType type, long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer blockHeight, byte[] signature)
throws DataException {
HSQLDBTransactionRepository txRepository = repositoryByTxType[type.value];
if (txRepository == null)
throw new DataException("Unsupported transaction type [" + type.name() + "] during fetch from HSQLDB repository");
try {
// params: long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature
return (TransactionData) subclassInfos[type.value].fromBaseMethod.invoke(txRepository, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
// params: long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer blockHeight, byte[] signature
return (TransactionData) subclassInfos[type.value].fromBaseMethod.invoke(txRepository, timestamp, txGroupId, reference, creatorPublicKey, fee, approvalStatus, blockHeight, signature);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof DataException)
throw (DataException) e.getCause();
@ -264,15 +265,19 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
if (signature == null)
return 0;
String sql = "SELECT height from Transactions WHERE signature = ? LIMIT 1";
// Fetch height using join via block's transactions
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT height from BlockTransactions JOIN Blocks ON Blocks.signature = BlockTransactions.block_signature WHERE transaction_signature = ? LIMIT 1",
signature)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql, signature)) {
if (resultSet == null)
return 0;
return resultSet.getInt(1);
Integer height = resultSet.getInt(1);
if (resultSet.wasNull())
return 0;
return height;
} catch (SQLException e) {
throw new DataException("Unable to fetch transaction's height from repository", e);
}
@ -340,10 +345,8 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public Map<TransactionType, Integer> getTransactionSummary(int startHeight, int endHeight) throws DataException {
String sql = "SELECT type, COUNT(signature) FROM Transactions "
+ "JOIN BlockTransactions ON transaction_signature = signature "
+ "JOIN Blocks ON Blocks.signature = block_signature "
+ "WHERE height BETWEEN ? AND ? "
+ "GROUP BY type";
+ "WHERE height BETWEEN ? AND ? "
+ "GROUP BY type";
Map<TransactionType, Integer> transactionCounts = new HashMap<>();
@ -385,25 +388,6 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
// Tables, starting with Transactions
String tables = "Transactions";
// BlockTransactions if we want confirmed transactions
switch (confirmationStatus) {
case BOTH:
break;
case CONFIRMED:
tables += " JOIN BlockTransactions ON BlockTransactions.transaction_signature = Transactions.signature";
if (hasHeightRange)
tables += " JOIN Blocks ON Blocks.signature = BlockTransactions.block_signature";
break;
case UNCONFIRMED:
tables += " LEFT OUTER JOIN BlockTransactions ON BlockTransactions.transaction_signature = Transactions.signature";
whereClauses.add("BlockTransactions.transaction_signature IS NULL");
break;
}
if (hasAddress) {
tables += " JOIN TransactionParticipants ON TransactionParticipants.signature = Transactions.signature";
groupBy = " GROUP BY TransactionParticipants.signature, Transactions.creation";
@ -416,11 +400,27 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
}
// WHERE clauses next
// Confirmation status
switch (confirmationStatus) {
case BOTH:
break;
case CONFIRMED:
whereClauses.add("Transactions.height IS NOT NULL");
break;
case UNCONFIRMED:
whereClauses.add("Transactions.height IS NULL");
break;
}
// Height range
if (hasHeightRange) {
whereClauses.add("Blocks.height >= " + startBlock);
whereClauses.add("Transactions.height >= " + startBlock);
if (blockLimit != null)
whereClauses.add("Blocks.height < " + (startBlock + blockLimit));
whereClauses.add("Transactions.height < " + (startBlock + blockLimit));
}
if (txGroupId != null) {
@ -484,20 +484,6 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
String sql = "SELECT Transactions.signature FROM Transactions";
// BlockTransactions if we want confirmed transactions
switch (confirmationStatus) {
case BOTH:
break;
case CONFIRMED:
sql += " JOIN BlockTransactions ON BlockTransactions.transaction_signature = Transactions.signature";
break;
case UNCONFIRMED:
sql += " LEFT OUTER JOIN BlockTransactions ON BlockTransactions.transaction_signature = Transactions.signature";
break;
}
for (TransactionType type : transactionTypes)
sql += " LEFT OUTER JOIN " + type.className + "Transactions USING (signature)";
@ -506,16 +492,17 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
sql += " WHERE Transactions.type IN (" + String.join(", ", typeValueStrings) + ")";
// BlockTransactions if we want confirmed transactions
// Confirmation status
switch (confirmationStatus) {
case BOTH:
break;
case CONFIRMED:
sql += " AND Transactions.height IS NOT NULL";
break;
case UNCONFIRMED:
sql += " AND BlockTransactions.transaction_signature IS NULL";
sql += " AND Transactions.height IS NULL";
break;
}
@ -565,7 +552,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
throws DataException {
List<Object> bindParams = new ArrayList<>(3);
String sql = "SELECT creation, tx_group_id, reference, fee, signature, sender, recipient, amount, asset_name "
String sql = "SELECT creation, tx_group_id, reference, fee, signature, sender, recipient, amount, asset_name, approval_status, height "
+ "FROM TransferAssetTransactions JOIN Transactions USING (signature) ";
if (address != null)
@ -600,8 +587,12 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
String recipient = resultSet.getString(7);
BigDecimal amount = resultSet.getBigDecimal(8);
String assetName = resultSet.getString(9);
ApprovalStatus approvalStatus = ApprovalStatus.valueOf(resultSet.getInt(10));
Integer height = resultSet.getInt(11);
if (resultSet.wasNull())
height = null;
assetTransfers.add(new TransferAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, assetId, fee, assetName, signature));
assetTransfers.add(new TransferAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, assetId, fee, assetName, approvalStatus, height, signature));
} while (resultSet.next());
return assetTransfers;
@ -611,37 +602,31 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
}
@Override
public List<TransactionData> getPendingTransactions(Integer txGroupId, Integer limit, Integer offset, Boolean reverse) throws DataException {
String[] txTypesNeedingApproval = stream(Transaction.TransactionType.values())
.filter(txType -> txType.needsApproval)
.map(txType -> String.valueOf(txType.value))
.toArray(String[]::new);
String txTypes = String.join(", ", txTypesNeedingApproval);
/*
* We only want transactions matching certain types needing approval,
* with txGroupId not set to NO_GROUP and where auto-approval won't
* happen due to the transaction creator being an admin of that group.
*/
String sql = "SELECT signature FROM UnconfirmedTransactions "
+ "NATURAL JOIN Transactions "
+ "LEFT OUTER JOIN Accounts ON Accounts.public_key = Transactions.creator "
+ "LEFT OUTER JOIN GroupAdmins ON GroupAdmins.admin = Accounts.account AND GroupAdmins.group_id = Transactions.tx_group_id "
+ "WHERE Transactions.tx_group_id != ? AND GroupAdmins.admin IS NULL "
+ "AND Transactions.type IN (" + txTypes + ") "
+ "ORDER BY creation";
public List<TransactionData> getApprovalPendingTransactions(Integer txGroupId, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT signature FROM Transactions WHERE Transactions.approval_status = ? ";
List<Object> bindParams = new ArrayList<>();
bindParams.add(ApprovalStatus.PENDING.value);
if (txGroupId != null) {
sql += "AND Transactions.tx_group_id = ? ";
bindParams.add(txGroupId);
}
sql += "ORDER BY creation";
if (reverse != null && reverse)
sql += " DESC";
sql += ", signature";
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
List<TransactionData> transactions = new ArrayList<TransactionData>();
// Find transactions with no corresponding row in BlockTransactions
try (ResultSet resultSet = this.repository.checkedExecute(sql, Group.NO_GROUP)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql, bindParams.toArray())) {
if (resultSet == null)
return transactions;
@ -652,85 +637,136 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
if (transactionData == null)
// Something inconsistent with the repository
throw new DataException("Unable to fetch unconfirmed transaction from repository?");
throw new DataException("Unable to fetch approval-pending transaction from repository?");
transactions.add(transactionData);
} while (resultSet.next());
return transactions;
} catch (SQLException | DataException e) {
throw new DataException("Unable to fetch unconfirmed transactions from repository", e);
throw new DataException("Unable to fetch approval-pending transactions from repository", e);
}
}
@Override
public int countTransactionApprovals(int txGroupId, byte[] signature) throws DataException {
// Fetch total number of approvals for signature
// NOT simply number of GROUP_APPROVAL transactions as some may be rejecting transaction, or changed opinions
// Also make sure that GROUP_APPROVAL transaction's admin is still an admin of group
public List<TransactionData> getApprovalPendingTransactions(int blockHeight) throws DataException {
String sql = "SELECT signature FROM Transactions "
+ "JOIN Groups on Groups.group_id = Transactions.tx_group_id "
+ "WHERE Transactions.approval_status = ? "
+ "AND Transactions.height >= ? - Groups.min_block_delay";
List<TransactionData> transactions = new ArrayList<TransactionData>();
// Sub-query SQL to find latest GroupApprovalTransaction relating to passed signature
String latestApprovalSql = "SELECT admin AS creator, MAX(creation) AS creation FROM GroupApprovalTransactions NATURAL JOIN Transactions WHERE pending_signature = ? GROUP BY admin";
try (ResultSet resultSet = this.repository.checkedExecute(sql, ApprovalStatus.PENDING, blockHeight)) {
if (resultSet == null)
return transactions;
String sql = "SELECT COUNT(*) FROM "
+ "(" + latestApprovalSql + ") "
+ "NATURAL JOIN Transactions "
+ "NATURAL JOIN GroupApprovalTransactions "
+ "LEFT OUTER JOIN BlockTransactions ON BlockTransactions.transaction_signature = Transactions.signature "
+ "LEFT OUTER JOIN Accounts ON Accounts.public_key = GroupApprovalTransactions.admin "
+ "LEFT OUTER JOIN GroupAdmins ON GroupAdmins.admin = Accounts.account "
+ "WHERE approval = TRUE AND GroupAdmins.group_id = ?";
do {
byte[] signature = resultSet.getBytes(1);
try (ResultSet resultSet = this.repository.checkedExecute(sql, signature, txGroupId)) {
return resultSet.getInt(1);
TransactionData transactionData = this.fromSignature(signature);
if (transactionData == null)
// Something inconsistent with the repository
throw new DataException("Unable to fetch approval-expiring transaction from repository?");
transactions.add(transactionData);
} while (resultSet.next());
return transactions;
} catch (SQLException | DataException e) {
throw new DataException("Unable to fetch approval-expiring transactions from repository", e);
}
}
@Override
public List<TransactionData> getApprovalExpiringTransactions(int blockHeight) throws DataException {
String sql = "SELECT signature FROM Transactions "
+ "JOIN Groups on Groups.group_id = Transactions.tx_group_id "
+ "WHERE Transactions.approval_status = ? "
+ "AND Transactions.height < ? - Groups.max_block_delay";
List<TransactionData> transactions = new ArrayList<TransactionData>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, ApprovalStatus.PENDING, blockHeight)) {
if (resultSet == null)
return transactions;
do {
byte[] signature = resultSet.getBytes(1);
TransactionData transactionData = this.fromSignature(signature);
if (transactionData == null)
// Something inconsistent with the repository
throw new DataException("Unable to fetch approval-expiring transaction from repository?");
transactions.add(transactionData);
} while (resultSet.next());
return transactions;
} catch (SQLException | DataException e) {
throw new DataException("Unable to fetch approval-expiring transactions from repository", e);
}
}
@Override
public GroupApprovalTransactionData getLatestApproval(byte[] pendingSignature, byte[] adminPublicKey) throws DataException {
String sql = "SELECT signature FROM GroupApprovalTransactions "
+ "NATURAL JOIN Transactions "
+ "WHERE pending_signature = ? AND admin = ? AND height IS NOT NULL "
+ "ORDER BY creation DESC, signature DESC LIMIT 1";
try (ResultSet resultSet = this.repository.checkedExecute(sql, pendingSignature, adminPublicKey)) {
if (resultSet == null)
return null;
byte[] signature = resultSet.getBytes(1);
return (GroupApprovalTransactionData) this.fromSignature(signature);
} catch (SQLException e) {
throw new DataException("Unable to count transaction group-admin approvals from repository", e);
throw new DataException("Unable to fetch latest transaction group-admin approval from repository", e);
}
}
@Override
public List<GroupApprovalTransactionData> getLatestApprovals(byte[] pendingSignature, byte[] adminPublicKey) throws DataException {
// Fetch latest approvals for signature
public GroupApprovalData getApprovalData(byte[] pendingSignature) throws DataException {
// Fetch latest approval data for pending transaction's signature
// NOT simply number of GROUP_APPROVAL transactions as some may be rejecting transaction, or changed opinions
// Also make sure that GROUP_APPROVAL transaction's admin is still an admin of group
Object[] bindArgs;
// Sub-query SQL to find latest GroupApprovalTransaction relating to passed signature
String latestApprovalSql = "SELECT admin AS creator, MAX(creation) AS creation FROM GroupApprovalTransactions NATURAL JOIN Transactions WHERE pending_signature = ? ";
if (adminPublicKey != null)
latestApprovalSql += "AND admin = ? ";
latestApprovalSql += "GROUP BY admin";
// Sub-query SQL to find latest GroupApprovalTransaction relating to passed pending signature
String latestApprovalSql = "SELECT pending_signature, admin, approval, creation, signature FROM GroupApprovalTransactions "
+ "NATURAL JOIN Transactions WHERE pending_signature = ? AND height IS NOT NULL";
String sql = "SELECT signature FROM "
+ "(" + latestApprovalSql + ") "
+ "NATURAL JOIN Transactions "
+ "NATURAL JOIN GroupApprovalTransactions "
+ "LEFT OUTER JOIN BlockTransactions ON BlockTransactions.transaction_signature = Transactions.signature "
+ "LEFT OUTER JOIN Accounts ON Accounts.public_key = GroupApprovalTransactions.admin "
+ "LEFT OUTER JOIN GroupAdmins ON GroupAdmins.admin = Accounts.account "
+ "WHERE approval = TRUE AND GroupAdmins.group_id = Transactions.tx_group_id";
String sql = "SELECT GAT.admin, GAT.approval FROM "
+ "(" + latestApprovalSql + ") AS GAT "
+ "LEFT OUTER JOIN (" + latestApprovalSql + ") AS NewerGAT "
+ "ON NewerGAT.admin = GAT.admin AND (NewerGAT.creation > GAT.creation OR (NewerGAT.creation = GAT.creation AND NewerGat.signature > GAT.signature)) "
+ "JOIN Transactions AS PendingTransactions ON PendingTransactions.signature = GAT.pending_signature "
+ "LEFT OUTER JOIN Accounts ON Accounts.public_key = GAT.admin "
+ "LEFT OUTER JOIN GroupAdmins ON GroupAdmins.admin = Accounts.account AND GroupAdmins.group_id = PendingTransactions.tx_group_id "
+ "WHERE NewerGAT.admin IS NULL";
if (adminPublicKey != null)
bindArgs = new Object[] { pendingSignature, adminPublicKey };
else
bindArgs = new Object[] { pendingSignature };
GroupApprovalData groupApprovalData = new GroupApprovalData();
List<GroupApprovalTransactionData> approvals = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, bindArgs)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql, pendingSignature, pendingSignature)) {
if (resultSet == null)
return approvals;
return groupApprovalData;
do {
byte[] signature = resultSet.getBytes(1);
byte[] adminPublicKey = resultSet.getBytes(1);
boolean approval = resultSet.getBoolean(2);
approvals.add((GroupApprovalTransactionData) this.fromSignature(signature));
if (approval)
groupApprovalData.approvingAdmins.add(adminPublicKey);
else
groupApprovalData.rejectingAdmins.add(adminPublicKey);
} while (resultSet.next());
return approvals;
return groupApprovalData;
} catch (SQLException e) {
throw new DataException("Unable to fetch latest transaction group-admin approvals from repository", e);
throw new DataException("Unable to fetch latest transaction group-approval decisions from repository", e);
}
}
@ -745,12 +781,16 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public List<TransactionData> getUnconfirmedTransactions(Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT signature FROM UnconfirmedTransactions ORDER BY creation";
String sql = "SELECT signature FROM UnconfirmedTransactions ";
sql += "ORDER BY creation";
if (reverse != null && reverse)
sql += " DESC";
sql += ", signature";
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
List<TransactionData> transactions = new ArrayList<TransactionData>();
@ -787,10 +827,25 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
}
}
@Override
public void updateHeight(byte[] signature, Integer height) throws DataException {
HSQLDBSaver saver = new HSQLDBSaver("Transactions");
saver.bind("signature", signature).bind("height", height);
try {
saver.execute(repository);
} catch (SQLException e) {
throw new DataException("Unable to update transaction's height in repository", e);
}
}
@Override
public void unconfirmTransaction(TransactionData transactionData) throws DataException {
HSQLDBSaver saver = new HSQLDBSaver("UnconfirmedTransactions");
saver.bind("signature", transactionData.getSignature()).bind("creation", new Timestamp(transactionData.getTimestamp()));
try {
saver.execute(repository);
} catch (SQLException e) {
@ -801,9 +856,13 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public void save(TransactionData transactionData) throws DataException {
HSQLDBSaver saver = new HSQLDBSaver("Transactions");
saver.bind("signature", transactionData.getSignature()).bind("reference", transactionData.getReference()).bind("type", transactionData.getType().value)
.bind("creator", transactionData.getCreatorPublicKey()).bind("creation", new Timestamp(transactionData.getTimestamp()))
.bind("fee", transactionData.getFee()).bind("milestone_block", null).bind("tx_group_id", transactionData.getTxGroupId());
// Do not include "height" as that is modified a different way
saver.bind("signature", transactionData.getSignature()).bind("reference", transactionData.getReference())
.bind("type", transactionData.getType().value)
.bind("creator", transactionData.getCreatorPublicKey()).bind("creation", new Timestamp(transactionData.getTimestamp()))
.bind("fee", transactionData.getFee()).bind("milestone_block", null).bind("tx_group_id", transactionData.getTxGroupId());
try {
saver.execute(this.repository);
} catch (SQLException e) {

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransferAssetTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.TransferAssetTransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBTransferAssetTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBTransferAssetTransactionRepository extends HSQLDBTransactionR
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
String sql = "SELECT recipient, asset_id, amount, asset_name FROM TransferAssetTransactions JOIN Assets USING (asset_id) WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, signature)) {
@ -28,7 +29,7 @@ public class HSQLDBTransferAssetTransactionRepository extends HSQLDBTransactionR
BigDecimal amount = resultSet.getBigDecimal(3);
String assetName = resultSet.getString(4);
return new TransferAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, assetId, fee, assetName, signature);
return new TransferAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, assetId, fee, assetName, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch transfer asset transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.UpdateAssetTransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBUpdateAssetTransactionRepository extends HSQLDBTransactionRepository {
@ -17,7 +18,7 @@ public class HSQLDBUpdateAssetTransactionRepository extends HSQLDBTransactionRep
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee,
byte[] signature) throws DataException {
ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT asset_id, new_owner, new_description, new_data, orphan_reference FROM UpdateAssetTransactions WHERE signature = ?",
signature)) {
@ -31,7 +32,7 @@ public class HSQLDBUpdateAssetTransactionRepository extends HSQLDBTransactionRep
byte[] orphanReference = resultSet.getBytes(5);
return new UpdateAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, assetId, newOwner,
newDescription, newData, fee, orphanReference, signature);
newDescription, newData, fee, orphanReference, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch update asset transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java

@ -10,6 +10,7 @@ import org.qora.data.transaction.TransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBUpdateGroupTransactionRepository extends HSQLDBTransactionRepository {
@ -17,7 +18,7 @@ public class HSQLDBUpdateGroupTransactionRepository extends HSQLDBTransactionRep
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT group_id, new_owner, new_description, new_is_open, new_approval_threshold, new_min_block_delay, new_max_block_delay, group_reference FROM UpdateGroupTransactions WHERE signature = ?",
signature)) {
@ -34,7 +35,7 @@ public class HSQLDBUpdateGroupTransactionRepository extends HSQLDBTransactionRep
byte[] groupReference = resultSet.getBytes(8);
return new UpdateGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, newOwner, newDescription, newIsOpen,
newApprovalThreshold, newMinBlockDelay, newMaxBlockDelay, groupReference, fee, signature);
newApprovalThreshold, newMinBlockDelay, newMaxBlockDelay, groupReference, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch update group transaction from repository", e);
}

5
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.UpdateNameTransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBUpdateNameTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBUpdateNameTransactionRepository extends HSQLDBTransactionRepo
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT new_owner, name, new_data, name_reference FROM UpdateNameTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -27,7 +28,7 @@ public class HSQLDBUpdateNameTransactionRepository extends HSQLDBTransactionRepo
String newData = resultSet.getString(3);
byte[] nameReference = resultSet.getBytes(4);
return new UpdateNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, newOwner, name, newData, nameReference, fee, signature);
return new UpdateNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, newOwner, name, newData, nameReference, fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch update name transaction from repository", e);
}

6
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java

@ -9,6 +9,7 @@ import org.qora.data.transaction.VoteOnPollTransactionData;
import org.qora.repository.DataException;
import org.qora.repository.hsqldb.HSQLDBRepository;
import org.qora.repository.hsqldb.HSQLDBSaver;
import org.qora.transaction.Transaction.ApprovalStatus;
public class HSQLDBVoteOnPollTransactionRepository extends HSQLDBTransactionRepository {
@ -16,7 +17,7 @@ public class HSQLDBVoteOnPollTransactionRepository extends HSQLDBTransactionRepo
this.repository = repository;
}
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT poll_name, option_index, previous_option_index FROM VoteOnPollTransactions WHERE signature = ?", signature)) {
if (resultSet == null)
@ -30,7 +31,8 @@ public class HSQLDBVoteOnPollTransactionRepository extends HSQLDBTransactionRepo
if (resultSet.wasNull())
previousOptionIndex = null;
return new VoteOnPollTransactionData(timestamp, txGroupId, reference, creatorPublicKey, pollName, optionIndex, previousOptionIndex, fee, signature);
return new VoteOnPollTransactionData(timestamp, txGroupId, reference, creatorPublicKey, pollName, optionIndex, previousOptionIndex,
fee, approvalStatus, height, signature);
} catch (SQLException e) {
throw new DataException("Unable to fetch vote on poll transaction from repository", e);
}

6
src/main/java/org/qora/transaction/GroupApprovalTransaction.java

@ -97,10 +97,10 @@ public class GroupApprovalTransaction extends Transaction {
@Override
public void process() throws DataException {
// Find previous approval decision (if any) by this admin for pending transaction
List<GroupApprovalTransactionData> approvals = this.repository.getTransactionRepository().getLatestApprovals(groupApprovalTransactionData.getPendingSignature(), groupApprovalTransactionData.getAdminPublicKey());
GroupApprovalTransactionData previousApproval = this.repository.getTransactionRepository().getLatestApproval(groupApprovalTransactionData.getPendingSignature(), groupApprovalTransactionData.getAdminPublicKey());
if (!approvals.isEmpty())
groupApprovalTransactionData.setPriorReference(approvals.get(0).getSignature());
if (previousApproval != null)
groupApprovalTransactionData.setPriorReference(previousApproval.getSignature());
// Save this transaction with updated prior reference to transaction that can help restore state
this.repository.getTransactionRepository().save(groupApprovalTransactionData);

89
src/main/java/org/qora/transaction/Transaction.java

@ -15,12 +15,15 @@ import org.apache.logging.log4j.Logger;
import org.qora.account.Account;
import org.qora.account.PrivateKeyAccount;
import org.qora.account.PublicKeyAccount;
import org.qora.asset.Asset;
import org.qora.block.BlockChain;
import org.qora.controller.Controller;
import org.qora.data.block.BlockData;
import org.qora.data.group.GroupApprovalData;
import org.qora.data.group.GroupData;
import org.qora.data.transaction.TransactionData;
import org.qora.group.Group;
import org.qora.group.Group.ApprovalThreshold;
import org.qora.repository.DataException;
import org.qora.repository.GroupRepository;
import org.qora.repository.Repository;
@ -124,6 +127,28 @@ public abstract class Transaction {
}
}
// Group-approval status
public enum ApprovalStatus {
NOT_REQUIRED(0),
PENDING(1),
APPROVED(2),
REJECTED(3),
EXPIRED(4),
INVALID(5);
public final int value;
private final static Map<Integer, ApprovalStatus> map = stream(ApprovalStatus.values()).collect(toMap(result -> result.value, result -> result));
ApprovalStatus(int value) {
this.value = value;
}
public static ApprovalStatus valueOf(int value) {
return map.get(value);
}
}
// Validation results
public enum ValidationResult {
OK(1),
@ -510,6 +535,10 @@ public abstract class Transaction {
if (creator == null)
return ValidationResult.MISSING_CREATOR;
// Reject if unconfirmed pile already has X transactions from same creator
if (countUnconfirmedByCreator(creator) >= Settings.getInstance().getMaxUnconfirmedPerAccount())
return ValidationResult.TOO_MANY_UNCONFIRMED;
// Check transaction's txGroupId
if (!this.isValidTxGroupId())
return ValidationResult.INVALID_TX_GROUP_ID;
@ -520,10 +549,6 @@ public abstract class Transaction {
ValidationResult result = this.isValid();
// Reject if unconfirmed pile already has X transactions from same creator
if (result == ValidationResult.OK && countUnconfirmedByCreator(creator) >= Settings.getInstance().getMaxUnconfirmedPerAccount())
return ValidationResult.TOO_MANY_UNCONFIRMED;
return result;
} finally {
repository.discardChanges();
@ -755,20 +780,44 @@ public abstract class Transaction {
return true;
}
public boolean meetsGroupApprovalThreshold() throws DataException {
public Boolean getApprovalDecision() throws DataException {
// Grab latest decisions from repository
GroupApprovalData groupApprovalData = this.repository.getTransactionRepository().getApprovalData(this.transactionData.getSignature());
if (groupApprovalData == null)
return null;
// We need group info
int txGroupId = this.transactionData.getTxGroupId();
GroupData groupData = repository.getGroupRepository().fromGroupId(txGroupId);
ApprovalThreshold approvalThreshold = groupData.getApprovalThreshold();
Group group = new Group(repository, txGroupId);
GroupData groupData = group.getGroupData();
// Fetch total number of admins in group
int totalAdmins = repository.getGroupRepository().countGroupAdmins(txGroupId);
// Is transaction is outside of min/max approval period?
int creationBlockHeight = this.repository.getBlockRepository().getHeightFromTimestamp(this.transactionData.getTimestamp());
int currentBlockHeight = this.repository.getBlockRepository().getBlockchainHeight();
if (currentBlockHeight < creationBlockHeight + groupData.getMinimumBlockDelay()
|| currentBlockHeight > creationBlockHeight + groupData.getMaximumBlockDelay())
// Are there enough approvals?
if (approvalThreshold.meetsTheshold(groupApprovalData.approvingAdmins.size(), totalAdmins))
return true;
// Are there enough rejections?
if (approvalThreshold.meetsTheshold(groupApprovalData.rejectingAdmins.size(), totalAdmins))
return false;
return group.getGroupData().getApprovalThreshold().meetsApprovalThreshold(repository, txGroupId, this.transactionData.getSignature());
// No definitive decision yet
return null;
}
/** Import into our repository as a new, unconfirmed transaction. */
public void importAsUnconfirmed() throws DataException {
// Fix up approval status
if (this.needsGroupApproval()) {
transactionData.setApprovalStatus(ApprovalStatus.PENDING);
} else {
transactionData.setApprovalStatus(ApprovalStatus.NOT_REQUIRED);
}
repository.getTransactionRepository().save(transactionData);
repository.getTransactionRepository().unconfirmTransaction(transactionData);
repository.saveChanges();
}
/**
@ -791,6 +840,20 @@ public abstract class Transaction {
*/
public abstract void process() throws DataException;
/**
* Update creator's last reference, subtract transaction fee, etc.
*
* @throws DataException
*/
public void processCreatorUpdates() throws DataException {
// Update transaction creator's balance
Account creator = getCreator();
creator.setConfirmedBalance(Asset.QORA, creator.getConfirmedBalance(Asset.QORA).subtract(transactionData.getFee()));
// Update transaction creator's reference
creator.setLastReference(transactionData.getSignature());
}
/**
* Undo transaction, updating the blockchain.
* <p>

2
src/main/java/org/qora/transform/transaction/CreateGroupTransactionTransformer.java

@ -81,7 +81,7 @@ public class CreateGroupTransactionTransformer extends TransactionTransformer {
byteBuffer.get(signature);
return new CreateGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, owner, groupName, description, isOpen, approvalThreshold,
minBlockDelay, maxBlockDelay, null, fee, signature);
minBlockDelay, maxBlockDelay, fee, signature);
}
public static int getDataLength(TransactionData transactionData) throws TransformationException {

2
src/main/java/org/qora/transform/transaction/GroupApprovalTransactionTransformer.java

@ -57,7 +57,7 @@ public class GroupApprovalTransactionTransformer extends TransactionTransformer
byte[] signature = new byte[SIGNATURE_LENGTH];
byteBuffer.get(signature);
return new GroupApprovalTransactionData(timestamp, txGroupId, reference, adminPublicKey, pendingSignature, approval, null, fee, signature);
return new GroupApprovalTransactionData(timestamp, txGroupId, reference, adminPublicKey, pendingSignature, approval, fee, signature);
}
public static int getDataLength(TransactionData transactionData) throws TransformationException {

2
src/main/java/org/qora/transform/transaction/UpdateAssetTransactionTransformer.java

@ -72,7 +72,7 @@ public class UpdateAssetTransactionTransformer extends TransactionTransformer {
byteBuffer.get(signature);
return new UpdateAssetTransactionData(timestamp, txGroupId, reference, ownerPublicKey, assetId, newOwner,
newDescription, newData, fee, null, signature);
newDescription, newData, fee, signature);
}
public static int getDataLength(TransactionData transactionData) throws TransformationException {

4
src/test/java/org/qora/test/GroupApprovalTests.java

@ -65,12 +65,10 @@ public class GroupApprovalTests extends Common {
ApprovalThreshold approvalThreshold = ApprovalThreshold.ONE;
int minimumBlockDelay = 0;
int maximumBlockDelay = 1440;
Integer groupId = null;
BigDecimal fee = BigDecimal.ONE.setScale(8);
byte[] signature = null;
TransactionData transactionData = new CreateGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, owner, groupName, description,
isOpen, approvalThreshold, minimumBlockDelay, maximumBlockDelay, groupId, fee, signature);
isOpen, approvalThreshold, minimumBlockDelay, maximumBlockDelay, fee);
Transaction transaction = new CreateGroupTransaction(repository, transactionData);
// Sign transaction

6
src/test/java/org/qora/test/TransactionTests.java

@ -257,12 +257,11 @@ public class TransactionTests extends Common {
// Update name's owner and data
Account newOwner = new PublicKeyAccount(repository, recipientSeed);
String newData = "{\"newKey\":\"newValue\"}";
byte[] nameReference = reference;
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
UpdateNameTransactionData updateNameTransactionData = new UpdateNameTransactionData(timestamp, Group.NO_GROUP, reference, sender.getPublicKey(),
newOwner.getAddress(), name, newData, nameReference, fee);
newOwner.getAddress(), name, newData, fee);
Transaction updateNameTransaction = new UpdateNameTransaction(repository, updateNameTransactionData);
updateNameTransaction.sign(sender);
@ -402,7 +401,6 @@ public class TransactionTests extends Common {
// Buyer
PrivateKeyAccount buyer = new PrivateKeyAccount(repository, recipientSeed);
byte[] nameReference = reference;
// Send buyer some funds so they have a reference
Transaction somePaymentTransaction = createPayment(sender, buyer.getAddress());
@ -418,7 +416,7 @@ public class TransactionTests extends Common {
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
BuyNameTransactionData buyNameTransactionData = new BuyNameTransactionData(timestamp, Group.NO_GROUP, buyersReference, buyer.getPublicKey(), name,
originalNameData.getSalePrice(), seller, nameReference, fee);
originalNameData.getSalePrice(), seller, fee);
Transaction buyNameTransaction = new BuyNameTransaction(repository, buyNameTransactionData);
buyNameTransaction.sign(buyer);

Loading…
Cancel
Save