diff --git a/src/main/java/org/qora/api/resource/TransactionsResource.java b/src/main/java/org/qora/api/resource/TransactionsResource.java index 6aa5f9f6..217f52bb 100644 --- a/src/main/java/org/qora/api/resource/TransactionsResource.java +++ b/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); diff --git a/src/main/java/org/qora/block/Block.java b/src/main/java/org/qora/block/Block.java index e0b1a7f9..e1933fbf 100644 --- a/src/main/java/org/qora/block/Block.java +++ b/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 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 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()); diff --git a/src/main/java/org/qora/block/BlockGenerator.java b/src/main/java/org/qora/block/BlockGenerator.java index b6ab9a69..1df953a8 100644 --- a/src/main/java/org/qora/block/BlockGenerator.java +++ b/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 diff --git a/src/main/java/org/qora/controller/Controller.java b/src/main/java/org/qora/controller/Controller.java index ac0bedd5..22ba78d5 100644 --- a/src/main/java/org/qora/controller/Controller.java +++ b/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(); } diff --git a/src/main/java/org/qora/data/group/GroupApprovalData.java b/src/main/java/org/qora/data/group/GroupApprovalData.java new file mode 100644 index 00000000..20487a0e --- /dev/null +++ b/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 approvingAdmins = new ArrayList<>(); + public List rejectingAdmins = new ArrayList<>(); + +} diff --git a/src/main/java/org/qora/data/transaction/ATTransactionData.java b/src/main/java/org/qora/data/transaction/ATTransactionData.java index ee409669..60fa3abf 100644 --- a/src/main/java/org/qora/data/transaction/ATTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/AccountFlagsTransactionData.java b/src/main/java/org/qora/data/transaction/AccountFlagsTransactionData.java index 5960aceb..338ea4a5 100644 --- a/src/main/java/org/qora/data/transaction/AccountFlagsTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/AddGroupAdminTransactionData.java b/src/main/java/org/qora/data/transaction/AddGroupAdminTransactionData.java index 67373c4b..c8ecb15e 100644 --- a/src/main/java/org/qora/data/transaction/AddGroupAdminTransactionData.java +++ b/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() { diff --git a/src/main/java/org/qora/data/transaction/ArbitraryTransactionData.java b/src/main/java/org/qora/data/transaction/ArbitraryTransactionData.java index 074f291d..ee2bc2b1 100644 --- a/src/main/java/org/qora/data/transaction/ArbitraryTransactionData.java +++ b/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 payments, BigDecimal fee, byte[] signature) { - super(TransactionType.ARBITRARY, timestamp, txGroupId, reference, senderPublicKey, fee, signature); + byte[] data, DataType dataType, List 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 payments, BigDecimal fee) { + byte[] data, DataType dataType, List payments, BigDecimal fee, byte[] signature) { + this(timestamp, txGroupId, reference, senderPublicKey, version, service, data, dataType, payments, fee, null, null, 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, 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 payments, BigDecimal fee) { this(timestamp, txGroupId, reference, senderPublicKey, version, service, data, dataType, payments, fee, null); } - /** Reconstructing a V1 arbitrary transaction with signature */ - 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); - } - - /** 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); diff --git a/src/main/java/org/qora/data/transaction/BuyNameTransactionData.java b/src/main/java/org/qora/data/transaction/BuyNameTransactionData.java index 8f98253c..2ee9ec43 100644 --- a/src/main/java/org/qora/data/transaction/BuyNameTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/CancelAssetOrderTransactionData.java b/src/main/java/org/qora/data/transaction/CancelAssetOrderTransactionData.java index 514114f4..e32922c2 100644 --- a/src/main/java/org/qora/data/transaction/CancelAssetOrderTransactionData.java +++ b/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); } diff --git a/src/main/java/org/qora/data/transaction/CancelGroupBanTransactionData.java b/src/main/java/org/qora/data/transaction/CancelGroupBanTransactionData.java index f20d8a56..29854c1a 100644 --- a/src/main/java/org/qora/data/transaction/CancelGroupBanTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/CancelGroupInviteTransactionData.java b/src/main/java/org/qora/data/transaction/CancelGroupInviteTransactionData.java index 35dbaca0..4dff9ddd 100644 --- a/src/main/java/org/qora/data/transaction/CancelGroupInviteTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/CancelSellNameTransactionData.java b/src/main/java/org/qora/data/transaction/CancelSellNameTransactionData.java index 3372c298..4ed5c5ea 100644 --- a/src/main/java/org/qora/data/transaction/CancelSellNameTransactionData.java +++ b/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); } diff --git a/src/main/java/org/qora/data/transaction/CreateAssetOrderTransactionData.java b/src/main/java/org/qora/data/transaction/CreateAssetOrderTransactionData.java index 88d6078d..6277ef40 100644 --- a/src/main/java/org/qora/data/transaction/CreateAssetOrderTransactionData.java +++ b/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); diff --git a/src/main/java/org/qora/data/transaction/CreateGroupTransactionData.java b/src/main/java/org/qora/data/transaction/CreateGroupTransactionData.java index f7980236..b290e7ae 100644 --- a/src/main/java/org/qora/data/transaction/CreateGroupTransactionData.java +++ b/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() { diff --git a/src/main/java/org/qora/data/transaction/CreatePollTransactionData.java b/src/main/java/org/qora/data/transaction/CreatePollTransactionData.java index 69fe05af..7d8ccac8 100644 --- a/src/main/java/org/qora/data/transaction/CreatePollTransactionData.java +++ b/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 pollOptions, BigDecimal fee, byte[] signature) { - super(Transaction.TransactionType.CREATE_POLL, timestamp, txGroupId, reference, creatorPublicKey, fee, signature); + String pollName, String description, List 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 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 pollOptions, BigDecimal fee) { this(timestamp, txGroupId, reference, creatorPublicKey, owner, pollName, description, pollOptions, fee, null); diff --git a/src/main/java/org/qora/data/transaction/DeployAtTransactionData.java b/src/main/java/org/qora/data/transaction/DeployAtTransactionData.java index 04e3f681..b5e064f7 100644 --- a/src/main/java/org/qora/data/transaction/DeployAtTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/EnableForgingTransactionData.java b/src/main/java/org/qora/data/transaction/EnableForgingTransactionData.java index 62b17572..fff47588 100644 --- a/src/main/java/org/qora/data/transaction/EnableForgingTransactionData.java +++ b/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); } diff --git a/src/main/java/org/qora/data/transaction/GenesisTransactionData.java b/src/main/java/org/qora/data/transaction/GenesisTransactionData.java index 63df40fa..c3cd54a5 100644 --- a/src/main/java/org/qora/data/transaction/GenesisTransactionData.java +++ b/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); } diff --git a/src/main/java/org/qora/data/transaction/GroupApprovalTransactionData.java b/src/main/java/org/qora/data/transaction/GroupApprovalTransactionData.java index 7e12f168..b8321e2b 100644 --- a/src/main/java/org/qora/data/transaction/GroupApprovalTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/GroupBanTransactionData.java b/src/main/java/org/qora/data/transaction/GroupBanTransactionData.java index 23089374..f785ed28 100644 --- a/src/main/java/org/qora/data/transaction/GroupBanTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/GroupInviteTransactionData.java b/src/main/java/org/qora/data/transaction/GroupInviteTransactionData.java index 7c4048ba..20293daa 100644 --- a/src/main/java/org/qora/data/transaction/GroupInviteTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/GroupKickTransactionData.java b/src/main/java/org/qora/data/transaction/GroupKickTransactionData.java index 82255fc6..ae61f31c 100644 --- a/src/main/java/org/qora/data/transaction/GroupKickTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/IssueAssetTransactionData.java b/src/main/java/org/qora/data/transaction/IssueAssetTransactionData.java index ce05690a..15093f2c 100644 --- a/src/main/java/org/qora/data/transaction/IssueAssetTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/JoinGroupTransactionData.java b/src/main/java/org/qora/data/transaction/JoinGroupTransactionData.java index eb23855e..93b1a1d8 100644 --- a/src/main/java/org/qora/data/transaction/JoinGroupTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/LeaveGroupTransactionData.java b/src/main/java/org/qora/data/transaction/LeaveGroupTransactionData.java index 7a823444..0cd3534b 100644 --- a/src/main/java/org/qora/data/transaction/LeaveGroupTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/MessageTransactionData.java b/src/main/java/org/qora/data/transaction/MessageTransactionData.java index a48a4584..f7013117 100644 --- a/src/main/java/org/qora/data/transaction/MessageTransactionData.java +++ b/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); diff --git a/src/main/java/org/qora/data/transaction/MultiPaymentTransactionData.java b/src/main/java/org/qora/data/transaction/MultiPaymentTransactionData.java index d524eefc..5155549d 100644 --- a/src/main/java/org/qora/data/transaction/MultiPaymentTransactionData.java +++ b/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 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 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 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 payments, BigDecimal fee) { this(timestamp, txGroupId, reference, senderPublicKey, payments, fee, null); } diff --git a/src/main/java/org/qora/data/transaction/PaymentTransactionData.java b/src/main/java/org/qora/data/transaction/PaymentTransactionData.java index cfd08a79..3a62dd39 100644 --- a/src/main/java/org/qora/data/transaction/PaymentTransactionData.java +++ b/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); } diff --git a/src/main/java/org/qora/data/transaction/ProxyForgingTransactionData.java b/src/main/java/org/qora/data/transaction/ProxyForgingTransactionData.java index 44b2bb5b..3bec21dc 100644 --- a/src/main/java/org/qora/data/transaction/ProxyForgingTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/RegisterNameTransactionData.java b/src/main/java/org/qora/data/transaction/RegisterNameTransactionData.java index 4582fdbc..f430c5be 100644 --- a/src/main/java/org/qora/data/transaction/RegisterNameTransactionData.java +++ b/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); } diff --git a/src/main/java/org/qora/data/transaction/RemoveGroupAdminTransactionData.java b/src/main/java/org/qora/data/transaction/RemoveGroupAdminTransactionData.java index 40639d9c..b25f5670 100644 --- a/src/main/java/org/qora/data/transaction/RemoveGroupAdminTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/SellNameTransactionData.java b/src/main/java/org/qora/data/transaction/SellNameTransactionData.java index 94f495a9..00c2bca9 100644 --- a/src/main/java/org/qora/data/transaction/SellNameTransactionData.java +++ b/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); } diff --git a/src/main/java/org/qora/data/transaction/SetGroupTransactionData.java b/src/main/java/org/qora/data/transaction/SetGroupTransactionData.java index d1274a44..7f7e5bfd 100644 --- a/src/main/java/org/qora/data/transaction/SetGroupTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/TransactionData.java b/src/main/java/org/qora/data/transaction/TransactionData.java index aff493a0..5023a2d9 100644 --- a/src/main/java/org/qora/data/transaction/TransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/TransferAssetTransactionData.java b/src/main/java/org/qora/data/transaction/TransferAssetTransactionData.java index a8757fb3..c92665f8 100644 --- a/src/main/java/org/qora/data/transaction/TransferAssetTransactionData.java +++ b/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; @@ -53,11 +54,17 @@ 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, byte[] signature) { - this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, assetId, fee, null, signature); + long assetId, BigDecimal fee, ApprovalStatus approvalStatus, Integer height, byte[] signature) { + this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, assetId, fee, null, null, null, signature); } - /** Constructs using data typically received over network. */ + /** 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, null, null, signature); + } + + /** 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); diff --git a/src/main/java/org/qora/data/transaction/UpdateAssetTransactionData.java b/src/main/java/org/qora/data/transaction/UpdateAssetTransactionData.java index 3d839a86..fae79b38 100644 --- a/src/main/java/org/qora/data/transaction/UpdateAssetTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/UpdateGroupTransactionData.java b/src/main/java/org/qora/data/transaction/UpdateGroupTransactionData.java index 9792e3b1..14b3c6f3 100644 --- a/src/main/java/org/qora/data/transaction/UpdateGroupTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/UpdateNameTransactionData.java b/src/main/java/org/qora/data/transaction/UpdateNameTransactionData.java index 7abc601b..e157b8e1 100644 --- a/src/main/java/org/qora/data/transaction/UpdateNameTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/data/transaction/VoteOnPollTransactionData.java b/src/main/java/org/qora/data/transaction/VoteOnPollTransactionData.java index 124d7c07..63c241e7 100644 --- a/src/main/java/org/qora/data/transaction/VoteOnPollTransactionData.java +++ b/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 diff --git a/src/main/java/org/qora/group/Group.java b/src/main/java/org/qora/group/Group.java index b0b79e41..7142b97c 100644 --- a/src/main/java/org/qora/group/Group.java +++ b/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 diff --git a/src/main/java/org/qora/repository/TransactionRepository.java b/src/main/java/org/qora/repository/TransactionRepository.java index 5d83983d..29ac7b9c 100644 --- a/src/main/java/org/qora/repository/TransactionRepository.java +++ b/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 getPendingTransactions(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; + public List getApprovalPendingTransactions(Integer txGroupId, Integer limit, Integer offset, Boolean reverse) throws DataException; /** - * Returns list of latest approval decisions per admin for given pending transaction signature. + * Returns list of transactions pending approval that can be resolved as of passed blockHeight. + *

+ * 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 getLatestApprovals(byte[] pendingSignature, byte[] adminPublicKey) throws DataException; + public List getApprovalPendingTransactions(int blockHeight) throws DataException; + + /** + * Returns list of transactions that have now expired as of passed blockHeight. + *

+ * Typically called by Block.process(). + * + * @param blockHeight + * @return + * @throws DataException + */ + public List 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. * diff --git a/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java index 65ed7512..39d3dd7b 100644 --- a/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/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; diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java index c70fc600..eb051602 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java index 11a7b511..90d5f038 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java index 43df4c26..d2809fe1 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java +++ b/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 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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java index 3b4f378f..d3d62092 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java index 6c9f3f6b..184aff4a 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java index e035b936..257fb0e1 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java index 6f16fadb..23a74b9b 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java index 382c4a4e..227e0baa 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java index 6ff43a01..efc6fcb0 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java index 1c577b6f..859979a1 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java index 003dcdd7..496753f2 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java index 50c63547..205f814f 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java +++ b/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); diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java index fb011631..96e7d008 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBEnableForgingTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBEnableForgingTransactionRepository.java index 061397d8..6ade5c34 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBEnableForgingTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java index 130af39b..09af997f 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java +++ b/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) diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java index 351efac1..db30b8d7 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java index 740bb7cd..58f8df46 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java index dfce7eeb..d21a4f2e 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java index 9f1bf535..ddb54cc6 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java index 5a1365cd..48d4d6bf 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java index ef95aa5d..7c4c8a01 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java index fd48906b..4ea89eeb 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java index af71837b..0d92cd8a 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java index b7e62f8f..aa4990f4 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java +++ b/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 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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java index 6307f833..d1429af5 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBProxyForgingTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBProxyForgingTransactionRepository.java index 6643c03f..b4ada8e0 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBProxyForgingTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java index 261aa1ca..bd482a6f 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java index a01d6e38..b67a9496 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java index f02c6f67..c001255d 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java index 92dba478..594d363b 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java index 9c89f072..c27c0a8d 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java +++ b/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)); - 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); } } - 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 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 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 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 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); + public List getApprovalPendingTransactions(Integer txGroupId, Integer limit, Integer offset, Boolean reverse) throws DataException { + String sql = "SELECT signature FROM Transactions WHERE Transactions.approval_status = ? "; - String txTypes = String.join(", ", txTypesNeedingApproval); + List bindParams = new ArrayList<>(); + bindParams.add(ApprovalStatus.PENDING.value); - /* - * 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"; + 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 transactions = new ArrayList(); // 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 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"; - // 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"; + List transactions = new ArrayList(); - 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 = ?"; - - try (ResultSet resultSet = this.repository.checkedExecute(sql, signature, txGroupId)) { - return resultSet.getInt(1); - } catch (SQLException e) { - throw new DataException("Unable to count transaction group-admin approvals from repository", e); - } - } - - @Override - public List getLatestApprovals(byte[] pendingSignature, byte[] adminPublicKey) throws DataException { - // Fetch latest 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 - - 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"; - - 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"; - - if (adminPublicKey != null) - bindArgs = new Object[] { pendingSignature, adminPublicKey }; - else - bindArgs = new Object[] { pendingSignature }; - - List approvals = new ArrayList<>(); - - try (ResultSet resultSet = this.repository.checkedExecute(sql, bindArgs)) { + try (ResultSet resultSet = this.repository.checkedExecute(sql, ApprovalStatus.PENDING, blockHeight)) { if (resultSet == null) - return approvals; + return transactions; do { byte[] signature = resultSet.getBytes(1); - approvals.add((GroupApprovalTransactionData) this.fromSignature(signature)); + 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 approvals; + return transactions; + } catch (SQLException | DataException e) { + throw new DataException("Unable to fetch approval-expiring transactions from repository", e); + } + } + + @Override + public List 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 transactions = new ArrayList(); + + 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 fetch latest transaction group-admin approvals from repository", e); + throw new DataException("Unable to fetch latest transaction group-admin approval from repository", e); + } + } + + @Override + 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 + + // 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 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"; + + GroupApprovalData groupApprovalData = new GroupApprovalData(); + + try (ResultSet resultSet = this.repository.checkedExecute(sql, pendingSignature, pendingSignature)) { + if (resultSet == null) + return groupApprovalData; + + do { + byte[] adminPublicKey = resultSet.getBytes(1); + boolean approval = resultSet.getBoolean(2); + + if (approval) + groupApprovalData.approvingAdmins.add(adminPublicKey); + else + groupApprovalData.rejectingAdmins.add(adminPublicKey); + } while (resultSet.next()); + + return groupApprovalData; + } catch (SQLException 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 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 transactions = new ArrayList(); @@ -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) { diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransferAssetTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransferAssetTransactionRepository.java index d81cd253..490dfab8 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransferAssetTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java index 5e272a7e..43765a33 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java index 6995d090..74a54f3c 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java index 788dc97f..26301251 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java index 077f845c..8802eef6 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java +++ b/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); } diff --git a/src/main/java/org/qora/transaction/GroupApprovalTransaction.java b/src/main/java/org/qora/transaction/GroupApprovalTransaction.java index 76ba1a68..2cc78c5e 100644 --- a/src/main/java/org/qora/transaction/GroupApprovalTransaction.java +++ b/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 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); diff --git a/src/main/java/org/qora/transaction/Transaction.java b/src/main/java/org/qora/transaction/Transaction.java index 05fec77d..ac2024e1 100644 --- a/src/main/java/org/qora/transaction/Transaction.java +++ b/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 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. *

diff --git a/src/main/java/org/qora/transform/transaction/CreateGroupTransactionTransformer.java b/src/main/java/org/qora/transform/transaction/CreateGroupTransactionTransformer.java index 8717f421..24705d7b 100644 --- a/src/main/java/org/qora/transform/transaction/CreateGroupTransactionTransformer.java +++ b/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 { diff --git a/src/main/java/org/qora/transform/transaction/GroupApprovalTransactionTransformer.java b/src/main/java/org/qora/transform/transaction/GroupApprovalTransactionTransformer.java index 84040e53..75542bb0 100644 --- a/src/main/java/org/qora/transform/transaction/GroupApprovalTransactionTransformer.java +++ b/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 { diff --git a/src/main/java/org/qora/transform/transaction/UpdateAssetTransactionTransformer.java b/src/main/java/org/qora/transform/transaction/UpdateAssetTransactionTransformer.java index e7e61dc9..486d2f51 100644 --- a/src/main/java/org/qora/transform/transaction/UpdateAssetTransactionTransformer.java +++ b/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 { diff --git a/src/test/java/org/qora/test/GroupApprovalTests.java b/src/test/java/org/qora/test/GroupApprovalTests.java index 76745de5..5f211db3 100644 --- a/src/test/java/org/qora/test/GroupApprovalTests.java +++ b/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 diff --git a/src/test/java/org/qora/test/TransactionTests.java b/src/test/java/org/qora/test/TransactionTests.java index cd193505..10548867 100644 --- a/src/test/java/org/qora/test/TransactionTests.java +++ b/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);