mirror of
https://github.com/Qortal/qortal.git
synced 2025-02-14 11:15:49 +00:00
Interim safety commit due to large number of changes!
log4j2.properties now has debugging entries removed. log4j2-test.properties (not in repo) takes priority so using that in development instead. Unconfirmed transactions no longer wiped on start-up by default - see Settings Reworking of {Public,Private,Genesis}Accounts as it seemed possible to silently lose public key in repository. The use of AccountData didn't work and so field-specific repository calls have been made instead (e.g. setLastReference) that try to opportunistically store public key too, if available (i.e. caller is PublicKeyAccount subclass, or better). Added API call GET /addresses/{address} to return general account info in one go. (Essentially the AccountData object as fetched from repository). Initial work on adding default groupID to accounts, along with corresponding SET_GROUP transaction type. In additional, added blockchain-wide default groupID and flag to allow/disallow no-group/groupless transactions. Initial work on group-admin approval of transactions tied to a specific group via txGroupId. More work needed on transaction's "effective txGroupId"! API call /transactions/pending to list transactions pending group-admin approval. However, this needs more work (see effective txGroupId above) and potentially offloading to HSQLDB repository if possible. Minor CIYAM AT renames to help static reflection initializers. Block.orphan() no longer adds orphaned transactions back to unconfirmed pile as they are themselves deleted during Transaction.orphan(). Maybe the answer is to NOT delete them during Transaction.orphan() but to add them to unconfirmed pile at that point? Very old transactions leftover from major resync would simply expire, whereas recently transactions leftover from minor resync could still make it into a new block on synced chain fork. Changes/tidying/improvements to block generator regarding removing invalid transactions and dealing with transactions pending group approval. Approval threshold added to groups. Mass refactoring of transaction-related classes to unify constructors, particularly field ordering, to fall in line with raw transaction layout. e.g. constructors now reflect that raw transactions mostly start with type, timestamp, txGroupId, publicKey, reference e.g. JAXB afterUnmarshal methods added where needed and corresponding nasty code in Transaction subclass constructors ripped out. e.g. TransactionTransformer subclasses contain less duplicated code. Fixed bug with repository save points thanks to swapping to Deque. Some fixes to do with missing transaction types being passed to JAXB TransactionData subclass constructors. Ripped out obsolete toJSON in TransactionTransformers as this is all nicely taken care of by Swagger/OpenAPI (thanks @Kc)
This commit is contained in:
parent
82e9e1e7dc
commit
00656f6724
@ -18,23 +18,18 @@ logger.hsqldbDebug.level = debug
|
||||
logger.jerseyInject.name = org.glassfish.jersey.internal.inject.Providers
|
||||
logger.jerseyInject.level = error
|
||||
|
||||
# Debugging transaction searches
|
||||
logger.txSearch.name = org.qora.repository.hsqldb.transaction.HSQLDBTransactionRepository
|
||||
logger.txSearch.level = trace
|
||||
# Suppress extraneous Jetty entries
|
||||
# 2019-02-14 11:46:27 INFO ContextHandler:851 - Started o.e.j.s.ServletContextHandler@6949e948{/,null,AVAILABLE}
|
||||
# 2019-02-14 11:46:27 INFO AbstractConnector:289 - Started ServerConnector@50ad322b{HTTP/1.1,[http/1.1]}{0.0.0.0:9085}
|
||||
# 2019-02-14 11:46:27 INFO Server:374 - jetty-9.4.11.v20180605; built: 2018-06-05T18:24:03.829Z; git: d5fc0523cfa96bfebfbda19606cad384d772f04c; jvm 1.8.0_181-b13
|
||||
# 2019-02-14 11:46:27 INFO Server:411 - Started @2539ms
|
||||
logger.oejsSCH.name = org.eclipse.jetty
|
||||
logger.oejsSCH.level = warn
|
||||
|
||||
# Debug block generator
|
||||
logger.blockgen.name = org.qora.block.BlockGenerator
|
||||
logger.blockgen.level = trace
|
||||
|
||||
# Debug synchronization
|
||||
logger.sync.name = org.qora.controller.Synchronizer
|
||||
logger.sync.level = trace
|
||||
|
||||
# Debug networking
|
||||
logger.network.name = org.qora.network.Network
|
||||
logger.network.level = trace
|
||||
logger.peer.name = org.qora.network.Peer
|
||||
logger.peer.level = trace
|
||||
# Suppress extraneous slf4j entries
|
||||
# 2019-02-14 11:46:27 INFO log:193 - Logging initialized @1636ms to org.eclipse.jetty.util.log.Slf4jLog
|
||||
logger.slf4j.name = org.slf4j
|
||||
logger.slf4j.level = warn
|
||||
|
||||
appender.console.type = Console
|
||||
appender.console.name = stdout
|
||||
|
@ -24,7 +24,7 @@ public class Account {
|
||||
public static final int ADDRESS_LENGTH = 25;
|
||||
|
||||
protected Repository repository;
|
||||
protected AccountData accountData;
|
||||
protected String address;
|
||||
|
||||
protected Account() {
|
||||
}
|
||||
@ -32,11 +32,24 @@ public class Account {
|
||||
/** Construct Account business object using account's address */
|
||||
public Account(Repository repository, String address) {
|
||||
this.repository = repository;
|
||||
this.accountData = new AccountData(address);
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
// Simple getters / setters
|
||||
|
||||
public String getAddress() {
|
||||
return this.accountData.getAddress();
|
||||
return this.address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build AccountData object using available account information.
|
||||
* <p>
|
||||
* For example, PublicKeyAccount might override and add public key info.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected AccountData buildAccountData() {
|
||||
return new AccountData(this.address);
|
||||
}
|
||||
|
||||
// More information
|
||||
@ -109,7 +122,7 @@ public class Account {
|
||||
}
|
||||
|
||||
public BigDecimal getConfirmedBalance(long assetId) throws DataException {
|
||||
AccountBalanceData accountBalanceData = this.repository.getAccountRepository().getBalance(this.accountData.getAddress(), assetId);
|
||||
AccountBalanceData accountBalanceData = this.repository.getAccountRepository().getBalance(this.address, assetId);
|
||||
if (accountBalanceData == null)
|
||||
return BigDecimal.ZERO.setScale(8);
|
||||
|
||||
@ -118,16 +131,16 @@ public class Account {
|
||||
|
||||
public void setConfirmedBalance(long assetId, BigDecimal balance) throws DataException {
|
||||
// Can't have a balance without an account - make sure it exists!
|
||||
this.repository.getAccountRepository().create(this.accountData);
|
||||
this.repository.getAccountRepository().ensureAccount(this.buildAccountData());
|
||||
|
||||
AccountBalanceData accountBalanceData = new AccountBalanceData(this.accountData.getAddress(), assetId, balance);
|
||||
AccountBalanceData accountBalanceData = new AccountBalanceData(this.address, assetId, balance);
|
||||
this.repository.getAccountRepository().save(accountBalanceData);
|
||||
|
||||
LOGGER.trace(this.accountData.getAddress() + " balance now: " + balance.toPlainString() + " [assetId " + assetId + "]");
|
||||
LOGGER.trace(this.address + " balance now: " + balance.toPlainString() + " [assetId " + assetId + "]");
|
||||
}
|
||||
|
||||
public void deleteBalance(long assetId) throws DataException {
|
||||
this.repository.getAccountRepository().delete(this.accountData.getAddress(), assetId);
|
||||
this.repository.getAccountRepository().delete(this.address, assetId);
|
||||
}
|
||||
|
||||
// Reference manipulations
|
||||
@ -139,17 +152,13 @@ public class Account {
|
||||
* @throws DataException
|
||||
*/
|
||||
public byte[] getLastReference() throws DataException {
|
||||
AccountData accountData = this.repository.getAccountRepository().getAccount(this.accountData.getAddress());
|
||||
if (accountData == null)
|
||||
return null;
|
||||
|
||||
return accountData.getReference();
|
||||
return this.repository.getAccountRepository().getLastReference(this.address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch last reference for account, considering unconfirmed transactions.
|
||||
* <p>
|
||||
* NOTE: <tt>repository.discardChanges()</tt> may be called during execution.
|
||||
* NOTE: a repository savepoint may be used during execution.
|
||||
*
|
||||
* @return byte[] reference, or null if no reference or account not found.
|
||||
* @throws DataException
|
||||
@ -163,7 +172,7 @@ public class Account {
|
||||
for (TransactionData transactionData : unconfirmedTransactions) {
|
||||
String address = PublicKeyAccount.getAddress(transactionData.getCreatorPublicKey());
|
||||
|
||||
if (address.equals(this.accountData.getAddress()))
|
||||
if (address.equals(this.address))
|
||||
reference = transactionData.getSignature();
|
||||
}
|
||||
|
||||
@ -182,9 +191,30 @@ public class Account {
|
||||
* @throws DataException
|
||||
*/
|
||||
public void setLastReference(byte[] reference) throws DataException {
|
||||
AccountData accountData = this.buildAccountData();
|
||||
accountData.setReference(reference);
|
||||
this.repository.getAccountRepository().setLastReference(accountData);
|
||||
}
|
||||
|
||||
this.repository.getAccountRepository().save(accountData);
|
||||
// Default groupID manipulations
|
||||
|
||||
/** Returns account's default groupID or null if account doesn't exist. */
|
||||
public Integer getDefaultGroupId() throws DataException {
|
||||
return this.repository.getAccountRepository().getDefaultGroupId(this.address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets account's default groupID and saves into repository.
|
||||
* <p>
|
||||
* Caller will need to call <tt>repository.saveChanges()</tt>.
|
||||
*
|
||||
* @param defaultGroupId
|
||||
* @throws DataException
|
||||
*/
|
||||
public void setDefaultGroupId(int defaultGroupId) throws DataException {
|
||||
AccountData accountData = this.buildAccountData();
|
||||
accountData.setDefaultGroupId(defaultGroupId);
|
||||
this.repository.getAccountRepository().setDefaultGroupId(accountData);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package org.qora.account;
|
||||
|
||||
import org.qora.crypto.Crypto;
|
||||
import org.qora.crypto.Ed25519;
|
||||
import org.qora.data.account.AccountData;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.utils.Pair;
|
||||
|
||||
@ -16,15 +15,16 @@ public class PrivateKeyAccount extends PublicKeyAccount {
|
||||
*
|
||||
* @param seed
|
||||
* byte[32] used to create private/public key pair
|
||||
* @throws IllegalArgumentException if passed invalid seed
|
||||
* @throws IllegalArgumentException
|
||||
* if passed invalid seed
|
||||
*/
|
||||
public PrivateKeyAccount(Repository repository, byte[] seed) {
|
||||
this.repository = repository;
|
||||
this.seed = seed;
|
||||
this.keyPair = Ed25519.createKeyPair(seed);
|
||||
|
||||
byte[] publicKey = keyPair.getB();
|
||||
this.accountData = new AccountData(Crypto.toAddress(publicKey), null, publicKey);
|
||||
this.publicKey = keyPair.getB();
|
||||
this.address = Crypto.toAddress(publicKey);
|
||||
}
|
||||
|
||||
public byte[] getSeed() {
|
||||
|
@ -2,25 +2,35 @@ package org.qora.account;
|
||||
|
||||
import org.qora.crypto.Crypto;
|
||||
import org.qora.crypto.Ed25519;
|
||||
import org.qora.data.account.AccountData;
|
||||
import org.qora.repository.Repository;
|
||||
|
||||
public class PublicKeyAccount extends Account {
|
||||
|
||||
protected byte[] publicKey;
|
||||
|
||||
public PublicKeyAccount(Repository repository, byte[] publicKey) {
|
||||
super(repository, Crypto.toAddress(publicKey));
|
||||
|
||||
this.accountData.setPublicKey(publicKey);
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
protected PublicKeyAccount() {
|
||||
}
|
||||
|
||||
public byte[] getPublicKey() {
|
||||
return this.accountData.getPublicKey();
|
||||
return this.publicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AccountData buildAccountData() {
|
||||
AccountData accountData = super.buildAccountData();
|
||||
accountData.setPublicKey(this.publicKey);
|
||||
return accountData;
|
||||
}
|
||||
|
||||
public boolean verify(byte[] signature, byte[] message) {
|
||||
return PublicKeyAccount.verify(this.accountData.getPublicKey(), signature, message);
|
||||
return PublicKeyAccount.verify(this.publicKey, signature, message);
|
||||
}
|
||||
|
||||
public static boolean verify(byte[] publicKey, byte[] signature, byte[] message) {
|
||||
|
@ -38,6 +38,31 @@ public class AddressesResource {
|
||||
@Context
|
||||
HttpServletRequest request;
|
||||
|
||||
@GET
|
||||
@Path("/{address}")
|
||||
@Operation(
|
||||
summary = "Return general account information for the given address",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "general account information",
|
||||
content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AccountData.class))
|
||||
)
|
||||
}
|
||||
)
|
||||
@ApiErrors({ApiError.INVALID_ADDRESS, ApiError.REPOSITORY_ISSUE})
|
||||
public AccountData getAccountInfo(@PathParam("address") String address) {
|
||||
if (!Crypto.isValidAddress(address))
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ADDRESS);
|
||||
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
return repository.getAccountRepository().getAccount(address);
|
||||
} catch (ApiException e) {
|
||||
throw e;
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/lastreference/{address}")
|
||||
@Operation(
|
||||
|
@ -38,6 +38,7 @@ import org.qora.data.group.GroupMemberData;
|
||||
import org.qora.data.transaction.AddGroupAdminTransactionData;
|
||||
import org.qora.data.transaction.CancelGroupInviteTransactionData;
|
||||
import org.qora.data.transaction.CreateGroupTransactionData;
|
||||
import org.qora.data.transaction.GroupApprovalTransactionData;
|
||||
import org.qora.data.transaction.GroupBanTransactionData;
|
||||
import org.qora.data.transaction.GroupInviteTransactionData;
|
||||
import org.qora.data.transaction.GroupKickTransactionData;
|
||||
@ -45,6 +46,7 @@ import org.qora.data.transaction.CancelGroupBanTransactionData;
|
||||
import org.qora.data.transaction.JoinGroupTransactionData;
|
||||
import org.qora.data.transaction.LeaveGroupTransactionData;
|
||||
import org.qora.data.transaction.RemoveGroupAdminTransactionData;
|
||||
import org.qora.data.transaction.SetGroupTransactionData;
|
||||
import org.qora.data.transaction.UpdateGroupTransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
@ -55,6 +57,7 @@ import org.qora.transform.TransformationException;
|
||||
import org.qora.transform.transaction.AddGroupAdminTransactionTransformer;
|
||||
import org.qora.transform.transaction.CancelGroupInviteTransactionTransformer;
|
||||
import org.qora.transform.transaction.CreateGroupTransactionTransformer;
|
||||
import org.qora.transform.transaction.GroupApprovalTransactionTransformer;
|
||||
import org.qora.transform.transaction.GroupBanTransactionTransformer;
|
||||
import org.qora.transform.transaction.GroupInviteTransactionTransformer;
|
||||
import org.qora.transform.transaction.GroupKickTransactionTransformer;
|
||||
@ -62,6 +65,7 @@ import org.qora.transform.transaction.CancelGroupBanTransactionTransformer;
|
||||
import org.qora.transform.transaction.JoinGroupTransactionTransformer;
|
||||
import org.qora.transform.transaction.LeaveGroupTransactionTransformer;
|
||||
import org.qora.transform.transaction.RemoveGroupAdminTransactionTransformer;
|
||||
import org.qora.transform.transaction.SetGroupTransactionTransformer;
|
||||
import org.qora.transform.transaction.UpdateGroupTransactionTransformer;
|
||||
import org.qora.utils.Base58;
|
||||
|
||||
@ -800,4 +804,90 @@ public class GroupsResource {
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/approval")
|
||||
@Operation(
|
||||
summary = "Build raw, unsigned, GROUP_APPROVAL transaction",
|
||||
requestBody = @RequestBody(
|
||||
required = true,
|
||||
content = @Content(
|
||||
mediaType = MediaType.APPLICATION_JSON,
|
||||
schema = @Schema(
|
||||
implementation = GroupApprovalTransactionData.class
|
||||
)
|
||||
)
|
||||
),
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "raw, unsigned, GROUP_APPROVAL transaction encoded in Base58",
|
||||
content = @Content(
|
||||
mediaType = MediaType.TEXT_PLAIN,
|
||||
schema = @Schema(
|
||||
type = "string"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
@ApiErrors({ApiError.TRANSACTION_INVALID, ApiError.TRANSFORMATION_ERROR, ApiError.REPOSITORY_ISSUE})
|
||||
public String groupApproval(GroupApprovalTransactionData transactionData) {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
Transaction transaction = Transaction.fromData(repository, transactionData);
|
||||
|
||||
ValidationResult result = transaction.isValidUnconfirmed();
|
||||
if (result != ValidationResult.OK)
|
||||
throw TransactionsResource.createTransactionInvalidException(request, result);
|
||||
|
||||
byte[] bytes = GroupApprovalTransactionTransformer.toBytes(transactionData);
|
||||
return Base58.encode(bytes);
|
||||
} catch (TransformationException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSFORMATION_ERROR, e);
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/setdefault")
|
||||
@Operation(
|
||||
summary = "Build raw, unsigned, SET_GROUP transaction",
|
||||
requestBody = @RequestBody(
|
||||
required = true,
|
||||
content = @Content(
|
||||
mediaType = MediaType.APPLICATION_JSON,
|
||||
schema = @Schema(
|
||||
implementation = SetGroupTransactionData.class
|
||||
)
|
||||
)
|
||||
),
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "raw, unsigned, SET_GROUP transaction encoded in Base58",
|
||||
content = @Content(
|
||||
mediaType = MediaType.TEXT_PLAIN,
|
||||
schema = @Schema(
|
||||
type = "string"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
@ApiErrors({ApiError.TRANSACTION_INVALID, ApiError.TRANSFORMATION_ERROR, ApiError.REPOSITORY_ISSUE})
|
||||
public String setGroup(SetGroupTransactionData transactionData) {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
Transaction transaction = Transaction.fromData(repository, transactionData);
|
||||
|
||||
ValidationResult result = transaction.isValidUnconfirmed();
|
||||
if (result != ValidationResult.OK)
|
||||
throw TransactionsResource.createTransactionInvalidException(request, result);
|
||||
|
||||
byte[] bytes = SetGroupTransactionTransformer.toBytes(transactionData);
|
||||
return Base58.encode(bytes);
|
||||
} catch (TransformationException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.TRANSFORMATION_ERROR, e);
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -225,6 +225,58 @@ public class TransactionsResource {
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/pending")
|
||||
@Operation(
|
||||
summary = "List transactions pending group approval",
|
||||
description = "Returns transactions that are pending group-admin approval",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "transactions",
|
||||
content = @Content(
|
||||
array = @ArraySchema(
|
||||
schema = @Schema(
|
||||
implementation = TransactionData.class
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
@ApiErrors({
|
||||
ApiError.REPOSITORY_ISSUE
|
||||
})
|
||||
public List<TransactionData> getPendingTransactions(@QueryParam("groupId") Integer groupId, @Parameter(
|
||||
ref = "limit"
|
||||
) @QueryParam("limit") Integer limit, @Parameter(
|
||||
ref = "offset"
|
||||
) @QueryParam("offset") Integer offset, @Parameter(
|
||||
ref = "reverse"
|
||||
) @QueryParam("reverse") Boolean reverse) {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
List<TransactionData> transactions = repository.getTransactionRepository().getUnconfirmedTransactions(null, null, reverse);
|
||||
|
||||
transactions.removeIf(transactionData -> {
|
||||
if (groupId != null && groupId != transactionData.getTxGroupId())
|
||||
return true;
|
||||
|
||||
try {
|
||||
return !Transaction.fromData(repository, transactionData).needsGroupApproval();
|
||||
} catch (DataException e) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Results slicing
|
||||
|
||||
return transactions;
|
||||
} catch (ApiException e) {
|
||||
throw e;
|
||||
} catch (DataException e) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConfirmationStatus {
|
||||
CONFIRMED,
|
||||
UNCONFIRMED,
|
||||
|
@ -13,7 +13,7 @@ import org.qora.data.transaction.DeployAtTransactionData;
|
||||
import org.qora.repository.ATRepository;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.transaction.ATTransaction;
|
||||
import org.qora.transaction.AtTransaction;
|
||||
|
||||
public class AT {
|
||||
|
||||
@ -38,7 +38,7 @@ public class AT {
|
||||
public AT(Repository repository, DeployAtTransactionData deployATTransactionData) throws DataException {
|
||||
this.repository = repository;
|
||||
|
||||
String atAddress = deployATTransactionData.getATAddress();
|
||||
String atAddress = deployATTransactionData.getAtAddress();
|
||||
int height = this.repository.getBlockRepository().getBlockchainHeight() + 1;
|
||||
byte[] creatorPublicKey = deployATTransactionData.getCreatorPublicKey();
|
||||
long creation = deployATTransactionData.getTimestamp();
|
||||
@ -126,7 +126,7 @@ public class AT {
|
||||
this.repository.getATRepository().delete(this.atData.getATAddress());
|
||||
}
|
||||
|
||||
public List<ATTransaction> run(long blockTimestamp) throws DataException {
|
||||
public List<AtTransaction> run(long blockTimestamp) throws DataException {
|
||||
String atAddress = this.atData.getATAddress();
|
||||
|
||||
QoraATAPI api = new QoraATAPI(repository, this.atData, blockTimestamp);
|
||||
|
@ -28,10 +28,11 @@ public enum BlockchainAPI {
|
||||
int sequence = timestamp.transactionSequence + 1;
|
||||
|
||||
QoraATAPI api = (QoraATAPI) state.getAPI();
|
||||
Account recipientAccount = new Account(api.repository, recipient);
|
||||
BlockRepository blockRepository = api.repository.getBlockRepository();
|
||||
|
||||
try {
|
||||
Account recipientAccount = new Account(api.repository, recipient);
|
||||
|
||||
while (height <= blockRepository.getBlockchainHeight()) {
|
||||
BlockData blockData = blockRepository.fromHeight(height);
|
||||
|
||||
|
@ -22,9 +22,10 @@ import org.qora.data.block.BlockData;
|
||||
import org.qora.data.transaction.ATTransactionData;
|
||||
import org.qora.data.transaction.MessageTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.group.Group;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.transaction.ATTransaction;
|
||||
import org.qora.transaction.AtTransaction;
|
||||
|
||||
import com.google.common.primitives.Bytes;
|
||||
|
||||
@ -42,20 +43,20 @@ public class QoraATAPI extends API {
|
||||
long blockTimestamp;
|
||||
|
||||
/** List of generated AT transactions */
|
||||
List<ATTransaction> transactions;
|
||||
List<AtTransaction> transactions;
|
||||
|
||||
// Constructors
|
||||
|
||||
public QoraATAPI(Repository repository, ATData atData, long blockTimestamp) {
|
||||
this.repository = repository;
|
||||
this.atData = atData;
|
||||
this.transactions = new ArrayList<ATTransaction>();
|
||||
this.transactions = new ArrayList<AtTransaction>();
|
||||
this.blockTimestamp = blockTimestamp;
|
||||
}
|
||||
|
||||
// Methods specific to Qora AT processing, not inherited
|
||||
|
||||
public List<ATTransaction> getTransactions() {
|
||||
public List<AtTransaction> getTransactions() {
|
||||
return this.transactions;
|
||||
}
|
||||
|
||||
@ -248,9 +249,9 @@ public class QoraATAPI extends API {
|
||||
|
||||
@Override
|
||||
public long getCurrentBalance(MachineState state) {
|
||||
Account atAccount = this.getATAccount();
|
||||
|
||||
try {
|
||||
Account atAccount = this.getATAccount();
|
||||
|
||||
return atAccount.getConfirmedBalance(Asset.QORA).unscaledValue().longValue();
|
||||
} catch (DataException e) {
|
||||
throw new RuntimeException("AT API unable to fetch AT's current balance?", e);
|
||||
@ -267,9 +268,9 @@ public class QoraATAPI extends API {
|
||||
byte[] reference = this.getLastReference();
|
||||
BigDecimal amount = BigDecimal.valueOf(unscaledAmount, 8);
|
||||
|
||||
ATTransactionData atTransactionData = new ATTransactionData(this.atData.getATAddress(), recipient.getAddress(), amount, this.atData.getAssetId(),
|
||||
new byte[0], BigDecimal.ZERO.setScale(8), timestamp, reference);
|
||||
ATTransaction atTransaction = new ATTransaction(this.repository, atTransactionData);
|
||||
ATTransactionData atTransactionData = new ATTransactionData(timestamp, Group.DEFAULT_GROUP, reference, this.atData.getATAddress(),
|
||||
recipient.getAddress(), amount, this.atData.getAssetId(), new byte[0], BigDecimal.ZERO.setScale(8));
|
||||
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
||||
|
||||
// Add to our transactions
|
||||
this.transactions.add(atTransaction);
|
||||
@ -285,9 +286,9 @@ public class QoraATAPI extends API {
|
||||
long timestamp = this.getNextTransactionTimestamp();
|
||||
byte[] reference = this.getLastReference();
|
||||
|
||||
ATTransactionData atTransactionData = new ATTransactionData(this.atData.getATAddress(), recipient.getAddress(), BigDecimal.ZERO,
|
||||
this.atData.getAssetId(), message, BigDecimal.ZERO.setScale(8), timestamp, reference);
|
||||
ATTransaction atTransaction = new ATTransaction(this.repository, atTransactionData);
|
||||
ATTransactionData atTransactionData = new ATTransactionData(timestamp, Group.DEFAULT_GROUP, reference,
|
||||
this.atData.getATAddress(), recipient.getAddress(), BigDecimal.ZERO, this.atData.getAssetId(), message, BigDecimal.ZERO.setScale(8));
|
||||
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
||||
|
||||
// Add to our transactions
|
||||
this.transactions.add(atTransaction);
|
||||
@ -311,9 +312,9 @@ public class QoraATAPI extends API {
|
||||
byte[] reference = this.getLastReference();
|
||||
BigDecimal amount = BigDecimal.valueOf(finalBalance, 8);
|
||||
|
||||
ATTransactionData atTransactionData = new ATTransactionData(this.atData.getATAddress(), creator.getAddress(), amount, this.atData.getAssetId(),
|
||||
new byte[0], BigDecimal.ZERO.setScale(8), timestamp, reference);
|
||||
ATTransaction atTransaction = new ATTransaction(this.repository, atTransactionData);
|
||||
ATTransactionData atTransactionData = new ATTransactionData(timestamp, Group.DEFAULT_GROUP, reference, this.atData.getATAddress(),
|
||||
creator.getAddress(), amount, this.atData.getAssetId(), new byte[0], BigDecimal.ZERO.setScale(8));
|
||||
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
||||
|
||||
// Add to our transactions
|
||||
this.transactions.add(atTransaction);
|
||||
@ -422,10 +423,10 @@ public class QoraATAPI extends API {
|
||||
if (!this.transactions.isEmpty())
|
||||
return this.transactions.get(this.transactions.size() - 1).getTransactionData().getSignature();
|
||||
|
||||
// No transactions yet, so look up AT's account's last reference from repository
|
||||
Account atAccount = this.getATAccount();
|
||||
|
||||
try {
|
||||
// No transactions yet, so look up AT's account's last reference from repository
|
||||
Account atAccount = this.getATAccount();
|
||||
|
||||
return atAccount.getLastReference();
|
||||
} catch (DataException e) {
|
||||
throw new RuntimeException("AT API unable to fetch AT's last reference from repository?", e);
|
||||
|
@ -28,7 +28,7 @@ import org.qora.repository.ATRepository;
|
||||
import org.qora.repository.BlockRepository;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.transaction.ATTransaction;
|
||||
import org.qora.transaction.AtTransaction;
|
||||
import org.qora.transaction.GenesisTransaction;
|
||||
import org.qora.transaction.Transaction;
|
||||
import org.qora.transform.TransformationException;
|
||||
@ -706,7 +706,7 @@ public class Block {
|
||||
* Performs various tests like checking for parent block, correct block timestamp, version, generating balance, etc.
|
||||
* <p>
|
||||
* Checks block's transactions by testing their validity then processing them.<br>
|
||||
* Hence <b>calls repository.discardChanges()</b> before returning.
|
||||
* Hence uses a repository savepoint during execution.
|
||||
*
|
||||
* @return ValidationResult.OK if block is valid, or some other ValidationResult otherwise.
|
||||
* @throws DataException
|
||||
@ -895,7 +895,7 @@ public class Block {
|
||||
throw new IllegalStateException("Attempted to execute ATs when block's local AT state data already exists");
|
||||
|
||||
// AT-Transactions generated by running ATs, to be prepended to block's transactions
|
||||
List<ATTransaction> allATTransactions = new ArrayList<ATTransaction>();
|
||||
List<AtTransaction> allATTransactions = new ArrayList<AtTransaction>();
|
||||
|
||||
this.ourAtStates = new ArrayList<ATStateData>();
|
||||
this.ourAtFees = BigDecimal.ZERO.setScale(8);
|
||||
@ -906,7 +906,7 @@ public class Block {
|
||||
// Run each AT, appends AT-Transactions and corresponding AT states, to our lists
|
||||
for (ATData atData : executableATs) {
|
||||
AT at = new AT(this.repository, atData);
|
||||
List<ATTransaction> atTransactions = at.run(this.blockData.getTimestamp());
|
||||
List<AtTransaction> atTransactions = at.run(this.blockData.getTimestamp());
|
||||
|
||||
allATTransactions.addAll(atTransactions);
|
||||
|
||||
@ -1005,7 +1005,8 @@ public class Block {
|
||||
this.repository.getBlockRepository().delete(blockTransactionData);
|
||||
|
||||
// Add to unconfirmed pile
|
||||
this.repository.getTransactionRepository().unconfirmTransaction(transaction.getTransactionData());
|
||||
// XXX WE CAN'T ADD TO UNCONFIRMED AS TRANSACTION HAS BEEN DELETED BY transaction.orphan() ABOVE
|
||||
// this.repository.getTransactionRepository().unconfirmTransaction(transaction.getTransactionData());
|
||||
|
||||
this.repository.getTransactionRepository().deleteParticipants(transaction.getTransactionData());
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.qora.data.asset.AssetData;
|
||||
import org.qora.data.block.BlockData;
|
||||
import org.qora.group.Group;
|
||||
import org.qora.repository.BlockRepository;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
@ -48,6 +49,10 @@ public class BlockChain {
|
||||
private long maxBlockTime;
|
||||
/** Maximum acceptable timestamp disagreement offset in milliseconds. */
|
||||
private long blockTimestampMargin;
|
||||
/** Whether transactions with txGroupId of NO_GROUP are allowed */
|
||||
private boolean grouplessAllowed;
|
||||
/** Default groupID when txGroupID and account's default groupID are both zero */
|
||||
private int defaultGroupId = Group.NO_GROUP;
|
||||
/** Map of which blockchain features are enabled when (height/timestamp) */
|
||||
private Map<String, Map<FeatureValueType, Long>> featureTriggers;
|
||||
|
||||
@ -101,6 +106,14 @@ public class BlockChain {
|
||||
return this.blockTimestampMargin;
|
||||
}
|
||||
|
||||
public boolean getGrouplessAllowed() {
|
||||
return this.grouplessAllowed;
|
||||
}
|
||||
|
||||
public int getDefaultGroupId() {
|
||||
return this.defaultGroupId;
|
||||
}
|
||||
|
||||
public static boolean getUseBrokenMD160ForAddresses() {
|
||||
return useBrokenMD160ForAddresses;
|
||||
}
|
||||
@ -166,6 +179,22 @@ public class BlockChain {
|
||||
GenesisBlock.fromJSON((JSONObject) genesisJson);
|
||||
|
||||
// Simple blockchain properties
|
||||
|
||||
boolean grouplessAllowed = true;
|
||||
if (json.containsKey("grouplessAllowed"))
|
||||
grouplessAllowed = (Boolean) Settings.getTypedJson(json, "grouplessAllowed", Boolean.class);
|
||||
|
||||
Integer defaultGroupId = null;
|
||||
if (json.containsKey("defaultGroupId"))
|
||||
defaultGroupId = ((Long) Settings.getTypedJson(json, "defaultGroupId", Long.class)).intValue();
|
||||
|
||||
// If groupless is not allowed the defaultGroupId needs to be set
|
||||
// XXX we could also check groupID exists, or at least created in genesis block, or in blockchain config
|
||||
if (!grouplessAllowed && (defaultGroupId == null || defaultGroupId == Group.DEFAULT_GROUP || defaultGroupId == Group.NO_GROUP)) {
|
||||
LOGGER.error("defaultGroupId must be set to valid groupID in blockchain config if groupless transactions are not allowed");
|
||||
throw new RuntimeException("defaultGroupId must be set to valid groupID in blockchain config if groupless transactions are not allowed");
|
||||
}
|
||||
|
||||
BigDecimal unitFee = Settings.getJsonBigDecimal(json, "unitFee");
|
||||
long maxBytesPerUnitFee = (Long) Settings.getTypedJson(json, "maxBytesPerUnitFee", Long.class);
|
||||
BigDecimal maxBalance = Settings.getJsonBigDecimal(json, "coinSupply");
|
||||
@ -208,6 +237,9 @@ public class BlockChain {
|
||||
instance.minBlockTime = minBlockTime;
|
||||
instance.maxBlockTime = maxBlockTime;
|
||||
instance.blockTimestampMargin = blockTimestampMargin;
|
||||
instance.grouplessAllowed = grouplessAllowed;
|
||||
if (defaultGroupId != null)
|
||||
instance.defaultGroupId = defaultGroupId;
|
||||
instance.featureTriggers = featureTriggers;
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,9 @@ public class BlockGenerator extends Thread {
|
||||
try {
|
||||
// Is new block valid yet? (Before adding unconfirmed transactions)
|
||||
if (newBlock.isValid() == ValidationResult.OK) {
|
||||
// Delete invalid transactions
|
||||
deleteInvalidTransactions(repository);
|
||||
|
||||
// Add unconfirmed transactions
|
||||
addUnconfirmedTransactions(repository, newBlock);
|
||||
|
||||
@ -131,6 +134,17 @@ public class BlockGenerator extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteInvalidTransactions(Repository repository) throws DataException {
|
||||
List<TransactionData> invalidTransactions = Transaction.getInvalidTransactions(repository);
|
||||
|
||||
// Actually delete invalid transactions from database
|
||||
for (TransactionData invalidTransactionData : invalidTransactions) {
|
||||
LOGGER.trace(String.format("Deleting invalid, unconfirmed transaction %s", Base58.encode(invalidTransactionData.getSignature())));
|
||||
repository.getTransactionRepository().delete(invalidTransactionData);
|
||||
}
|
||||
repository.saveChanges();
|
||||
}
|
||||
|
||||
private void addUnconfirmedTransactions(Repository repository, Block newBlock) throws DataException {
|
||||
// Grab all valid unconfirmed transactions (already sorted)
|
||||
List<TransactionData> unconfirmedTransactions = Transaction.getUnconfirmedTransactions(repository);
|
||||
@ -153,10 +167,17 @@ public class BlockGenerator extends Thread {
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore transactions that have not met group-admin approval threshold
|
||||
if (transaction.needsGroupApproval()) {
|
||||
unconfirmedTransactions.remove(i);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Discard last-reference changes used to aid transaction validity checks
|
||||
repository.discardChanges();
|
||||
// Discard any repository changes used to aid transaction validity checks
|
||||
// repository.discardChanges(); // XXX possibly not needed any more thanks to savepoints?
|
||||
|
||||
// Attempt to add transactions until block is full, or we run out
|
||||
// If a transaction makes the block invalid then skip it and it'll either expire or be in next block.
|
||||
|
@ -98,9 +98,9 @@ public class GenesisBlock extends Block {
|
||||
// We're into version 4 genesis block territory now
|
||||
version = 4;
|
||||
|
||||
transactions.add(new GenesisTransactionData(recipient, amount, assetId, timestamp));
|
||||
transactions.add(new GenesisTransactionData(timestamp, recipient, amount, assetId));
|
||||
} else {
|
||||
transactions.add(new GenesisTransactionData(recipient, amount, timestamp));
|
||||
transactions.add(new GenesisTransactionData(timestamp, recipient, amount));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ public class Synchronizer {
|
||||
|
||||
return true;
|
||||
} finally {
|
||||
repository.discardChanges();
|
||||
repository.discardChanges(); // Free repository locks, if any, also in case anything went wrong
|
||||
this.repository = null;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import java.math.BigDecimal;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class AccountBalanceData {
|
||||
|
||||
@ -16,9 +16,8 @@ public class AccountBalanceData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// necessary for JAX-RS serialization
|
||||
@SuppressWarnings("unused")
|
||||
private AccountBalanceData() {
|
||||
// necessary for JAXB
|
||||
protected AccountBalanceData() {
|
||||
}
|
||||
|
||||
public AccountBalanceData(String address, long assetId, BigDecimal balance) {
|
||||
|
@ -1,22 +1,35 @@
|
||||
package org.qora.data.account;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
import org.qora.group.Group;
|
||||
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class AccountData {
|
||||
|
||||
// Properties
|
||||
protected String address;
|
||||
protected byte[] reference;
|
||||
protected byte[] publicKey;
|
||||
protected int defaultGroupId;
|
||||
|
||||
// Constructors
|
||||
|
||||
public AccountData(String address, byte[] reference, byte[] publicKey) {
|
||||
// For JAXB
|
||||
protected AccountData() {
|
||||
}
|
||||
|
||||
public AccountData(String address, byte[] reference, byte[] publicKey, int defaultGroupId) {
|
||||
this.address = address;
|
||||
this.reference = reference;
|
||||
this.publicKey = publicKey;
|
||||
this.defaultGroupId = defaultGroupId;
|
||||
}
|
||||
|
||||
public AccountData(String address) {
|
||||
this(address, null, null);
|
||||
this(address, null, null, Group.DEFAULT_GROUP);
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
@ -41,6 +54,14 @@ public class AccountData {
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
public int getDefaultGroupId() {
|
||||
return this.defaultGroupId;
|
||||
}
|
||||
|
||||
public void setDefaultGroupId(int defaultGroupId) {
|
||||
this.defaultGroupId = defaultGroupId;
|
||||
}
|
||||
|
||||
// Comparison
|
||||
|
||||
@Override
|
||||
|
@ -4,6 +4,8 @@ import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import org.qora.group.Group.ApprovalThreshold;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
@ -18,6 +20,7 @@ public class GroupData {
|
||||
private long created;
|
||||
private Long updated;
|
||||
private boolean isOpen;
|
||||
private ApprovalThreshold approvalThreshold;
|
||||
/** Reference to CREATE_GROUP or UPDATE_GROUP transaction, used to rebuild group during orphaning. */
|
||||
// No need to ever expose this via API
|
||||
@XmlTransient
|
||||
@ -31,7 +34,7 @@ public class GroupData {
|
||||
}
|
||||
|
||||
/** Constructs new GroupData with nullable groupId and nullable updated [timestamp] */
|
||||
public GroupData(Integer groupId, String owner, String name, String description, long created, Long updated, boolean isOpen, byte[] reference) {
|
||||
public GroupData(Integer groupId, String owner, String name, String description, long created, Long updated, boolean isOpen, ApprovalThreshold approvalThreshold, byte[] reference) {
|
||||
this.groupId = groupId;
|
||||
this.owner = owner;
|
||||
this.groupName = name;
|
||||
@ -39,12 +42,13 @@ public class GroupData {
|
||||
this.created = created;
|
||||
this.updated = updated;
|
||||
this.isOpen = isOpen;
|
||||
this.approvalThreshold = approvalThreshold;
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
/** Constructs new GroupData with unassigned groupId */
|
||||
public GroupData(String owner, String name, String description, long created, boolean isOpen, byte[] reference) {
|
||||
this(null, owner, name, description, created, null, isOpen, reference);
|
||||
public GroupData(String owner, String name, String description, long created, boolean isOpen, ApprovalThreshold approvalThreshold, byte[] reference) {
|
||||
this(null, owner, name, description, created, null, isOpen, approvalThreshold, reference);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
@ -105,4 +109,12 @@ public class GroupData {
|
||||
this.isOpen = isOpen;
|
||||
}
|
||||
|
||||
public ApprovalThreshold getApprovalThreshold() {
|
||||
return this.approvalThreshold;
|
||||
}
|
||||
|
||||
public void setApprovalThreshold(ApprovalThreshold approvalThreshold) {
|
||||
this.approvalThreshold = approvalThreshold;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
@ -10,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class ATTransactionData extends TransactionData {
|
||||
@ -24,13 +25,18 @@ public class ATTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected ATTransactionData() {
|
||||
super(TransactionType.AT);
|
||||
}
|
||||
|
||||
public ATTransactionData(String atAddress, String recipient, BigDecimal amount, Long assetId, byte[] message, BigDecimal fee, long timestamp,
|
||||
byte[] reference, byte[] signature) {
|
||||
super(TransactionType.AT, fee, GenesisAccount.PUBLIC_KEY, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
this.atAddress = atAddress;
|
||||
this.recipient = recipient;
|
||||
@ -39,9 +45,9 @@ public class ATTransactionData extends TransactionData {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public ATTransactionData(String atAddress, String recipient, BigDecimal amount, Long assetId, byte[] message, BigDecimal fee, long timestamp,
|
||||
byte[] reference) {
|
||||
this(atAddress, recipient, amount, assetId, message, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
|
@ -10,7 +10,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class AddGroupAdminTransactionData extends TransactionData {
|
||||
@ -25,7 +25,7 @@ public class AddGroupAdminTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected AddGroupAdminTransactionData() {
|
||||
super(TransactionType.ADD_GROUP_ADMIN);
|
||||
}
|
||||
@ -34,8 +34,8 @@ public class AddGroupAdminTransactionData extends TransactionData {
|
||||
this.creatorPublicKey = this.ownerPublicKey;
|
||||
}
|
||||
|
||||
public AddGroupAdminTransactionData(byte[] ownerPublicKey, int groupId, String member, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.ADD_GROUP_ADMIN, fee, ownerPublicKey, timestamp, reference, signature);
|
||||
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);
|
||||
|
||||
this.ownerPublicKey = ownerPublicKey;
|
||||
this.groupId = groupId;
|
||||
|
@ -3,6 +3,7 @@ package org.qora.data.transaction;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
@ -11,7 +12,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class ArbitraryTransactionData extends TransactionData {
|
||||
@ -32,17 +33,22 @@ public class ArbitraryTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected ArbitraryTransactionData() {
|
||||
super(TransactionType.ARBITRARY);
|
||||
}
|
||||
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.senderPublicKey;
|
||||
}
|
||||
|
||||
/** Reconstructing a V3 arbitrary transaction with signature */
|
||||
public ArbitraryTransactionData(int version, byte[] senderPublicKey, int service, byte[] data, DataType dataType, List<PaymentData> payments,
|
||||
BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.ARBITRARY, fee, senderPublicKey, timestamp, reference, signature);
|
||||
public ArbitraryTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, int version, int service,
|
||||
byte[] data, DataType dataType, List<PaymentData> payments, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.ARBITRARY, timestamp, txGroupId, reference, senderPublicKey, fee, signature);
|
||||
|
||||
this.version = version;
|
||||
this.senderPublicKey = senderPublicKey;
|
||||
this.version = version;
|
||||
this.service = service;
|
||||
this.data = data;
|
||||
this.dataType = dataType;
|
||||
@ -50,33 +56,33 @@ public class ArbitraryTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
/** Constructing a new V3 arbitrary transaction without signature */
|
||||
public ArbitraryTransactionData(int version, byte[] senderPublicKey, int service, byte[] data, DataType dataType, List<PaymentData> payments,
|
||||
BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(version, senderPublicKey, service, data, dataType, payments, fee, timestamp, reference, null);
|
||||
public ArbitraryTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, int version, int service,
|
||||
byte[] data, DataType dataType, List<PaymentData> payments, BigDecimal fee) {
|
||||
this(timestamp, txGroupId, reference, senderPublicKey, version, service, data, dataType, payments, fee, null);
|
||||
}
|
||||
|
||||
/** Reconstructing a V1 arbitrary transaction with signature */
|
||||
public ArbitraryTransactionData(int version, byte[] senderPublicKey, int service, byte[] data, DataType dataType, BigDecimal fee, long timestamp,
|
||||
byte[] reference, byte[] signature) {
|
||||
this(version, senderPublicKey, service, data, dataType, null, fee, timestamp, reference, 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 */
|
||||
public ArbitraryTransactionData(int version, byte[] senderPublicKey, int service, byte[] data, DataType dataType, BigDecimal fee, long timestamp,
|
||||
byte[] reference) {
|
||||
this(version, senderPublicKey, service, data, dataType, null, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
|
||||
public int getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public byte[] getSenderPublicKey() {
|
||||
return this.senderPublicKey;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public int getService() {
|
||||
return this.service;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
@ -11,7 +12,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class BuyNameTransactionData extends TransactionData {
|
||||
@ -36,14 +37,18 @@ public class BuyNameTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected BuyNameTransactionData() {
|
||||
super(TransactionType.BUY_NAME);
|
||||
}
|
||||
|
||||
public BuyNameTransactionData(byte[] buyerPublicKey, String name, BigDecimal amount, String seller, byte[] nameReference, BigDecimal fee, long timestamp,
|
||||
byte[] reference, byte[] signature) {
|
||||
super(TransactionType.BUY_NAME, fee, buyerPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.buyerPublicKey;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
this.buyerPublicKey = buyerPublicKey;
|
||||
this.name = name;
|
||||
@ -52,18 +57,18 @@ public class BuyNameTransactionData extends TransactionData {
|
||||
this.nameReference = nameReference;
|
||||
}
|
||||
|
||||
public BuyNameTransactionData(byte[] buyerPublicKey, String name, BigDecimal amount, String seller, BigDecimal fee, long timestamp, byte[] reference,
|
||||
byte[] signature) {
|
||||
this(buyerPublicKey, name, amount, seller, null, fee, timestamp, reference, signature);
|
||||
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(byte[] buyerPublicKey, String name, BigDecimal amount, String seller, byte[] nameReference, BigDecimal fee, long timestamp,
|
||||
byte[] reference) {
|
||||
this(buyerPublicKey, name, amount, seller, nameReference, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
public BuyNameTransactionData(byte[] buyerPublicKey, String name, BigDecimal amount, String seller, BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(buyerPublicKey, name, amount, seller, null, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -11,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class CancelAssetOrderTransactionData extends TransactionData {
|
||||
@ -22,19 +22,19 @@ public class CancelAssetOrderTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected CancelAssetOrderTransactionData() {
|
||||
super(TransactionType.CANCEL_ASSET_ORDER);
|
||||
}
|
||||
|
||||
public CancelAssetOrderTransactionData(byte[] creatorPublicKey, byte[] orderId, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(Transaction.TransactionType.CANCEL_ASSET_ORDER, fee, creatorPublicKey, timestamp, reference, signature);
|
||||
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);
|
||||
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public CancelAssetOrderTransactionData(byte[] creatorPublicKey, byte[] orderId, BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(creatorPublicKey, orderId, fee, timestamp, reference, null);
|
||||
public CancelAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, byte[] orderId, BigDecimal fee) {
|
||||
this(timestamp, txGroupId, reference, creatorPublicKey, orderId, fee, null);
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
|
@ -11,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class CancelGroupBanTransactionData extends TransactionData {
|
||||
@ -31,7 +31,7 @@ public class CancelGroupBanTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected CancelGroupBanTransactionData() {
|
||||
super(TransactionType.CANCEL_GROUP_BAN);
|
||||
}
|
||||
@ -40,8 +40,8 @@ public class CancelGroupBanTransactionData extends TransactionData {
|
||||
this.creatorPublicKey = this.adminPublicKey;
|
||||
}
|
||||
|
||||
public CancelGroupBanTransactionData(byte[] adminPublicKey, int groupId, String member, byte[] banReference, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.CANCEL_GROUP_BAN, fee, adminPublicKey, timestamp, reference, signature);
|
||||
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);
|
||||
|
||||
this.adminPublicKey = adminPublicKey;
|
||||
this.groupId = groupId;
|
||||
@ -50,8 +50,8 @@ public class CancelGroupBanTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
/** Constructor typically used after deserialization */
|
||||
public CancelGroupBanTransactionData(byte[] adminPublicKey, int groupId, String member, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
this(adminPublicKey, groupId, member, null, fee, timestamp, reference, signature);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -11,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class CancelGroupInviteTransactionData extends TransactionData {
|
||||
@ -31,7 +31,7 @@ public class CancelGroupInviteTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected CancelGroupInviteTransactionData() {
|
||||
super(TransactionType.CANCEL_GROUP_INVITE);
|
||||
}
|
||||
@ -40,8 +40,8 @@ public class CancelGroupInviteTransactionData extends TransactionData {
|
||||
this.creatorPublicKey = this.adminPublicKey;
|
||||
}
|
||||
|
||||
public CancelGroupInviteTransactionData(byte[] adminPublicKey, int groupId, String invitee, byte[] inviteReference, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.CANCEL_GROUP_INVITE, fee, adminPublicKey, timestamp, reference, signature);
|
||||
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);
|
||||
|
||||
this.adminPublicKey = adminPublicKey;
|
||||
this.groupId = groupId;
|
||||
@ -50,8 +50,8 @@ public class CancelGroupInviteTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
/** Constructor typically used after deserialization */
|
||||
public CancelGroupInviteTransactionData(byte[] adminPublicKey, int groupId, String invitee, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
this(adminPublicKey, groupId, invitee, null, fee, timestamp, reference, signature);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
@ -9,7 +10,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class CancelSellNameTransactionData extends TransactionData {
|
||||
@ -22,20 +23,24 @@ public class CancelSellNameTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected CancelSellNameTransactionData() {
|
||||
super(TransactionType.CANCEL_SELL_NAME);
|
||||
}
|
||||
|
||||
public CancelSellNameTransactionData(byte[] ownerPublicKey, String name, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.CANCEL_SELL_NAME, fee, ownerPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
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);
|
||||
|
||||
this.ownerPublicKey = ownerPublicKey;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public CancelSellNameTransactionData(byte[] ownerPublicKey, String name, BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(ownerPublicKey, name, fee, timestamp, reference, null);
|
||||
public CancelSellNameTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, String name, BigDecimal fee) {
|
||||
this(timestamp, txGroupId, reference, ownerPublicKey, name, fee, null);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -10,7 +10,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class CreateAssetOrderTransactionData extends TransactionData {
|
||||
@ -27,14 +27,14 @@ public class CreateAssetOrderTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected CreateAssetOrderTransactionData() {
|
||||
super(TransactionType.CREATE_ASSET_ORDER);
|
||||
}
|
||||
|
||||
public CreateAssetOrderTransactionData(byte[] creatorPublicKey, long haveAssetId, long wantAssetId, BigDecimal amount, BigDecimal price, BigDecimal fee,
|
||||
long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.CREATE_ASSET_ORDER, fee, creatorPublicKey, timestamp, reference, signature);
|
||||
public CreateAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, long haveAssetId, long wantAssetId,
|
||||
BigDecimal amount, BigDecimal price, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.CREATE_ASSET_ORDER, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
|
||||
|
||||
this.haveAssetId = haveAssetId;
|
||||
this.wantAssetId = wantAssetId;
|
||||
@ -42,9 +42,9 @@ public class CreateAssetOrderTransactionData extends TransactionData {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public CreateAssetOrderTransactionData(byte[] creatorPublicKey, long haveAssetId, long wantAssetId, BigDecimal amount, BigDecimal price, BigDecimal fee,
|
||||
long timestamp, byte[] reference) {
|
||||
this(creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
|
@ -6,12 +6,13 @@ import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
import org.qora.group.Group.ApprovalThreshold;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.media.Schema.AccessMode;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(
|
||||
allOf = {
|
||||
@ -47,23 +48,28 @@ public class CreateGroupTransactionData extends TransactionData {
|
||||
example = "true"
|
||||
)
|
||||
private boolean isOpen;
|
||||
@Schema(
|
||||
description = "how many group admins are required to approve group member transactions"
|
||||
)
|
||||
private ApprovalThreshold approvalThreshold;
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected CreateGroupTransactionData() {
|
||||
super(TransactionType.CREATE_GROUP);
|
||||
}
|
||||
|
||||
public CreateGroupTransactionData(byte[] creatorPublicKey, String owner, String groupName, String description, boolean isOpen, Integer groupId,
|
||||
BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.CREATE_GROUP, fee, creatorPublicKey, timestamp, reference, signature);
|
||||
public CreateGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String owner, String groupName, String description,
|
||||
boolean isOpen, ApprovalThreshold approvalThreshold, Integer groupId, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.CREATE_GROUP, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
|
||||
|
||||
this.creatorPublicKey = creatorPublicKey;
|
||||
this.owner = owner;
|
||||
this.groupName = groupName;
|
||||
this.description = description;
|
||||
this.isOpen = isOpen;
|
||||
this.approvalThreshold = approvalThreshold;
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
@ -85,6 +91,10 @@ public class CreateGroupTransactionData extends TransactionData {
|
||||
return this.isOpen;
|
||||
}
|
||||
|
||||
public ApprovalThreshold getApprovalThreshold() {
|
||||
return this.approvalThreshold;
|
||||
}
|
||||
|
||||
public Integer getGroupId() {
|
||||
return this.groupId;
|
||||
}
|
||||
|
@ -8,10 +8,11 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
import org.qora.data.voting.PollOptionData;
|
||||
import org.qora.transaction.Transaction;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class CreatePollTransactionData extends TransactionData {
|
||||
@ -24,13 +25,14 @@ public class CreatePollTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected CreatePollTransactionData() {
|
||||
super(TransactionType.CREATE_POLL);
|
||||
}
|
||||
|
||||
public CreatePollTransactionData(byte[] creatorPublicKey, String owner, String pollName, String description, List<PollOptionData> pollOptions,
|
||||
BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(Transaction.TransactionType.CREATE_POLL, fee, creatorPublicKey, timestamp, reference, signature);
|
||||
public CreatePollTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String owner,
|
||||
String pollName, String description, List<PollOptionData> pollOptions, BigDecimal fee, byte[] signature) {
|
||||
super(Transaction.TransactionType.CREATE_POLL, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
|
||||
|
||||
this.owner = owner;
|
||||
this.pollName = pollName;
|
||||
@ -38,9 +40,9 @@ public class CreatePollTransactionData extends TransactionData {
|
||||
this.pollOptions = pollOptions;
|
||||
}
|
||||
|
||||
public CreatePollTransactionData(byte[] creatorPublicKey, String owner, String pollName, String description, List<PollOptionData> pollOptions,
|
||||
BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(creatorPublicKey, owner, pollName, description, pollOptions, fee, timestamp, reference, null);
|
||||
public CreatePollTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, String owner,
|
||||
String pollName, String description, List<PollOptionData> pollOptions, BigDecimal fee) {
|
||||
this(timestamp, txGroupId, reference, creatorPublicKey, owner, pollName, description, pollOptions, fee, null);
|
||||
}
|
||||
|
||||
// Getters/setters
|
||||
|
@ -9,7 +9,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class DeployAtTransactionData extends TransactionData {
|
||||
@ -17,41 +17,42 @@ public class DeployAtTransactionData extends TransactionData {
|
||||
// Properties
|
||||
private String name;
|
||||
private String description;
|
||||
private String ATType;
|
||||
private String aTType;
|
||||
private String tags;
|
||||
private byte[] creationBytes;
|
||||
private BigDecimal amount;
|
||||
private long assetId;
|
||||
private String ATAddress;
|
||||
private String aTAddress;
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
protected DeployAtTransactionData() {
|
||||
super(TransactionType.DEPLOY_AT);
|
||||
}
|
||||
|
||||
public DeployAtTransactionData(String ATAddress, byte[] creatorPublicKey, String name, String description, String ATType, String tags, byte[] creationBytes,
|
||||
BigDecimal amount, long assetId, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.DEPLOY_AT, fee, creatorPublicKey, timestamp, reference, signature);
|
||||
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);
|
||||
|
||||
this.aTAddress = aTAddress;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.ATType = ATType;
|
||||
this.aTType = aTType;
|
||||
this.tags = tags;
|
||||
this.creationBytes = creationBytes;
|
||||
this.amount = amount;
|
||||
this.assetId = assetId;
|
||||
this.creationBytes = creationBytes;
|
||||
this.ATAddress = ATAddress;
|
||||
}
|
||||
|
||||
public DeployAtTransactionData(byte[] creatorPublicKey, String name, String description, String ATType, String tags, byte[] creationBytes,
|
||||
BigDecimal amount, long assetId, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
this(null, creatorPublicKey, name, description, ATType, tags, creationBytes, amount, assetId, fee, timestamp, reference, signature);
|
||||
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);
|
||||
}
|
||||
|
||||
public DeployAtTransactionData(byte[] creatorPublicKey, String name, String description, String ATType, String tags, byte[] creationBytes,
|
||||
BigDecimal amount, long assetId, BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(null, creatorPublicKey, name, description, ATType, tags, creationBytes, amount, assetId, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
@ -64,8 +65,8 @@ public class DeployAtTransactionData extends TransactionData {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public String getATType() {
|
||||
return this.ATType;
|
||||
public String getAtType() {
|
||||
return this.aTType;
|
||||
}
|
||||
|
||||
public String getTags() {
|
||||
@ -84,12 +85,12 @@ public class DeployAtTransactionData extends TransactionData {
|
||||
return this.assetId;
|
||||
}
|
||||
|
||||
public String getATAddress() {
|
||||
return this.ATAddress;
|
||||
public String getAtAddress() {
|
||||
return this.aTAddress;
|
||||
}
|
||||
|
||||
public void setATAddress(String ATAddress) {
|
||||
this.ATAddress = ATAddress;
|
||||
public void setAtAddress(String AtAddress) {
|
||||
this.aTAddress = AtAddress;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(
|
||||
allOf = {
|
||||
@ -27,29 +27,30 @@ public class GenesisTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected GenesisTransactionData() {
|
||||
super(TransactionType.GENESIS);
|
||||
}
|
||||
|
||||
public GenesisTransactionData(String recipient, BigDecimal amount, long assetId, long timestamp, byte[] signature) {
|
||||
// Zero fee
|
||||
super(TransactionType.GENESIS, BigDecimal.ZERO, GenesisAccount.PUBLIC_KEY, timestamp, null, signature);
|
||||
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);
|
||||
|
||||
this.recipient = recipient;
|
||||
this.amount = amount;
|
||||
this.assetId = assetId;
|
||||
}
|
||||
|
||||
public GenesisTransactionData(String recipient, BigDecimal amount, long timestamp, byte[] signature) {
|
||||
this(recipient, amount, Asset.QORA, timestamp, signature);
|
||||
public GenesisTransactionData(long timestamp, String recipient, BigDecimal amount, byte[] signature) {
|
||||
this(timestamp, recipient, amount, Asset.QORA, signature);
|
||||
}
|
||||
|
||||
public GenesisTransactionData(String recipient, BigDecimal amount, long assetId, long timestamp) {
|
||||
this(recipient, amount, assetId, timestamp, null);
|
||||
public GenesisTransactionData(long timestamp, String recipient, BigDecimal amount, long assetId) {
|
||||
this(timestamp, recipient, amount, assetId, null);
|
||||
}
|
||||
|
||||
public GenesisTransactionData(String recipient, BigDecimal amount, long timestamp) {
|
||||
this(recipient, amount, Asset.QORA, timestamp, null);
|
||||
public GenesisTransactionData(long timestamp, String recipient, BigDecimal amount) {
|
||||
this(timestamp, recipient, amount, Asset.QORA, null);
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
|
@ -0,0 +1,95 @@
|
||||
package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(
|
||||
allOf = {
|
||||
TransactionData.class
|
||||
}
|
||||
)
|
||||
public class GroupApprovalTransactionData extends TransactionData {
|
||||
|
||||
// Properties
|
||||
@Schema(
|
||||
description = "admin's public key",
|
||||
example = "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP"
|
||||
)
|
||||
private byte[] adminPublicKey;
|
||||
@Schema(
|
||||
description = "transaction pending approval"
|
||||
)
|
||||
private byte[] pendingSignature;
|
||||
@Schema(
|
||||
description = "approval decision",
|
||||
example = "true"
|
||||
)
|
||||
private boolean approval;
|
||||
/** Reference to prior GROUP_APPROVAL transaction, used to rebuild approval status during orphaning. */
|
||||
// For internal use when orphaning
|
||||
@XmlTransient
|
||||
@Schema(
|
||||
hidden = true
|
||||
)
|
||||
private byte[] priorReference;
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAXB
|
||||
protected GroupApprovalTransactionData() {
|
||||
super(TransactionType.GROUP_APPROVAL);
|
||||
}
|
||||
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.adminPublicKey;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
this.adminPublicKey = adminPublicKey;
|
||||
this.pendingSignature = pendingSignature;
|
||||
this.approval = approval;
|
||||
this.priorReference = priorReference;
|
||||
}
|
||||
|
||||
/** Constructor typically used after deserialization */
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
||||
public byte[] getAdminPublicKey() {
|
||||
return this.adminPublicKey;
|
||||
}
|
||||
|
||||
public byte[] getPendingSignature() {
|
||||
return this.pendingSignature;
|
||||
}
|
||||
|
||||
public boolean getApproval() {
|
||||
return this.approval;
|
||||
}
|
||||
|
||||
public byte[] getPriorReference() {
|
||||
return this.priorReference;
|
||||
}
|
||||
|
||||
public void setPriorReference(byte[] priorReference) {
|
||||
this.priorReference = priorReference;
|
||||
}
|
||||
|
||||
}
|
@ -11,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(
|
||||
allOf = {
|
||||
@ -61,7 +61,7 @@ public class GroupBanTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected GroupBanTransactionData() {
|
||||
super(TransactionType.GROUP_BAN);
|
||||
}
|
||||
@ -70,9 +70,9 @@ public class GroupBanTransactionData extends TransactionData {
|
||||
this.creatorPublicKey = this.adminPublicKey;
|
||||
}
|
||||
|
||||
public GroupBanTransactionData(byte[] adminPublicKey, int groupId, String member, String reason, int timeToLive, byte[] memberReference,
|
||||
byte[] adminReference, byte[] joinInviteReference, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.GROUP_BAN, fee, adminPublicKey, timestamp, reference, signature);
|
||||
public GroupBanTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member,
|
||||
String reason, int timeToLive, byte[] memberReference, byte[] adminReference, byte[] joinInviteReference, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.GROUP_BAN, timestamp, txGroupId, reference, adminPublicKey, fee, signature);
|
||||
|
||||
this.adminPublicKey = adminPublicKey;
|
||||
this.groupId = groupId;
|
||||
@ -85,9 +85,9 @@ public class GroupBanTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
/** Constructor typically used after deserialization */
|
||||
public GroupBanTransactionData(byte[] adminPublicKey, int groupId, String offender, String reason, int timeToLive, BigDecimal fee, long timestamp,
|
||||
byte[] reference, byte[] signature) {
|
||||
this(adminPublicKey, groupId, offender, reason, timeToLive, null, null, null, fee, timestamp, reference, signature);
|
||||
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, fee, signature);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -11,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class GroupInviteTransactionData extends TransactionData {
|
||||
@ -33,7 +33,7 @@ public class GroupInviteTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected GroupInviteTransactionData() {
|
||||
super(TransactionType.GROUP_INVITE);
|
||||
}
|
||||
@ -42,8 +42,8 @@ public class GroupInviteTransactionData extends TransactionData {
|
||||
this.creatorPublicKey = this.adminPublicKey;
|
||||
}
|
||||
|
||||
public GroupInviteTransactionData(byte[] adminPublicKey, int groupId, String invitee, int timeToLive, byte[] joinReference, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.GROUP_INVITE, fee, adminPublicKey, timestamp, reference, signature);
|
||||
public GroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, int timeToLive, byte[] joinReference, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.GROUP_INVITE, timestamp, txGroupId, reference, adminPublicKey, fee, signature);
|
||||
|
||||
this.adminPublicKey = adminPublicKey;
|
||||
this.groupId = groupId;
|
||||
@ -53,8 +53,8 @@ public class GroupInviteTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
/** Constructor typically used after deserialization */
|
||||
public GroupInviteTransactionData(byte[] adminPublicKey, int groupId, String invitee, int timeToLive, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
this(adminPublicKey, groupId, invitee, timeToLive, null, fee, timestamp, reference, signature);
|
||||
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, fee, signature);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -11,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(
|
||||
allOf = {
|
||||
@ -58,7 +58,7 @@ public class GroupKickTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected GroupKickTransactionData() {
|
||||
super(TransactionType.GROUP_KICK);
|
||||
}
|
||||
@ -67,9 +67,9 @@ public class GroupKickTransactionData extends TransactionData {
|
||||
this.creatorPublicKey = this.adminPublicKey;
|
||||
}
|
||||
|
||||
public GroupKickTransactionData(byte[] adminPublicKey, int groupId, String member, String reason, byte[] memberReference, byte[] adminReference,
|
||||
byte[] joinReference, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.GROUP_KICK, fee, adminPublicKey, timestamp, reference, signature);
|
||||
public GroupKickTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member,
|
||||
String reason, byte[] memberReference, byte[] adminReference, byte[] joinReference, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.GROUP_KICK, timestamp, txGroupId, reference, adminPublicKey, fee, signature);
|
||||
|
||||
this.adminPublicKey = adminPublicKey;
|
||||
this.groupId = groupId;
|
||||
@ -81,9 +81,9 @@ public class GroupKickTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
/** Constructor typically used after deserialization */
|
||||
public GroupKickTransactionData(byte[] adminPublicKey, int groupId, String member, String reason, BigDecimal fee, long timestamp, byte[] reference,
|
||||
byte[] signature) {
|
||||
this(adminPublicKey, groupId, member, reason, null, null, null, fee, timestamp, reference, signature);
|
||||
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, fee, signature);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
@ -10,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.media.Schema.AccessMode;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class IssueAssetTransactionData extends TransactionData {
|
||||
@ -34,14 +35,18 @@ public class IssueAssetTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected IssueAssetTransactionData() {
|
||||
super(TransactionType.ISSUE_ASSET);
|
||||
}
|
||||
|
||||
public IssueAssetTransactionData(Long assetId, byte[] issuerPublicKey, String owner, String assetName, String description, long quantity,
|
||||
boolean isDivisible, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.ISSUE_ASSET, fee, issuerPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.issuerPublicKey;
|
||||
}
|
||||
|
||||
public IssueAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] issuerPublicKey, Long assetId, String owner,
|
||||
String assetName, String description, long quantity, boolean isDivisible, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.ISSUE_ASSET, timestamp, txGroupId, reference, issuerPublicKey, fee, signature);
|
||||
|
||||
this.assetId = assetId;
|
||||
this.issuerPublicKey = issuerPublicKey;
|
||||
@ -52,14 +57,14 @@ public class IssueAssetTransactionData extends TransactionData {
|
||||
this.isDivisible = isDivisible;
|
||||
}
|
||||
|
||||
public IssueAssetTransactionData(byte[] issuerPublicKey, String owner, String assetName, String description, long quantity, boolean isDivisible,
|
||||
BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
this(null, issuerPublicKey, owner, assetName, description, quantity, isDivisible, fee, timestamp, reference, signature);
|
||||
public IssueAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] issuerPublicKey, String owner, String assetName,
|
||||
String description, long quantity, boolean isDivisible, BigDecimal fee, byte[] signature) {
|
||||
this(timestamp, txGroupId, reference, issuerPublicKey, null, owner, assetName, description, quantity, isDivisible, fee, signature);
|
||||
}
|
||||
|
||||
public IssueAssetTransactionData(byte[] issuerPublicKey, String owner, String assetName, String description, long quantity, boolean isDivisible,
|
||||
BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(null, issuerPublicKey, owner, assetName, description, quantity, isDivisible, fee, timestamp, reference, null);
|
||||
public IssueAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] issuerPublicKey, String owner, String assetName,
|
||||
String description, long quantity, boolean isDivisible, BigDecimal fee) {
|
||||
this(timestamp, txGroupId, reference, issuerPublicKey, null, owner, assetName, description, quantity, isDivisible, fee, null);
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
|
@ -11,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class JoinGroupTransactionData extends TransactionData {
|
||||
@ -29,7 +29,7 @@ public class JoinGroupTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected JoinGroupTransactionData() {
|
||||
super(TransactionType.JOIN_GROUP);
|
||||
}
|
||||
@ -38,8 +38,8 @@ public class JoinGroupTransactionData extends TransactionData {
|
||||
this.creatorPublicKey = this.joinerPublicKey;
|
||||
}
|
||||
|
||||
public JoinGroupTransactionData(byte[] joinerPublicKey, int groupId, byte[] inviteReference, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.JOIN_GROUP, fee, joinerPublicKey, timestamp, reference, signature);
|
||||
public JoinGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] joinerPublicKey, int groupId, byte[] inviteReference, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.JOIN_GROUP, timestamp, txGroupId, reference, joinerPublicKey, fee, signature);
|
||||
|
||||
this.joinerPublicKey = joinerPublicKey;
|
||||
this.groupId = groupId;
|
||||
@ -47,8 +47,8 @@ public class JoinGroupTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
/** Constructor typically used after deserialization */
|
||||
public JoinGroupTransactionData(byte[] joinerPublicKey, int groupId, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
this(joinerPublicKey, groupId, null, fee, timestamp, reference, signature);
|
||||
public JoinGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] joinerPublicKey, int groupId, BigDecimal fee, byte[] signature) {
|
||||
this(timestamp, txGroupId, reference, joinerPublicKey, groupId, null, fee, signature);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -11,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class LeaveGroupTransactionData extends TransactionData {
|
||||
@ -34,7 +34,7 @@ public class LeaveGroupTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected LeaveGroupTransactionData() {
|
||||
super(TransactionType.LEAVE_GROUP);
|
||||
}
|
||||
@ -43,8 +43,8 @@ public class LeaveGroupTransactionData extends TransactionData {
|
||||
this.creatorPublicKey = this.leaverPublicKey;
|
||||
}
|
||||
|
||||
public LeaveGroupTransactionData(byte[] leaverPublicKey, int groupId, byte[] memberReference, byte[] adminReference, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.LEAVE_GROUP, fee, leaverPublicKey, timestamp, reference, signature);
|
||||
public LeaveGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] leaverPublicKey, int groupId, byte[] memberReference, byte[] adminReference, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.LEAVE_GROUP, timestamp, txGroupId, reference, leaverPublicKey, fee, signature);
|
||||
|
||||
this.leaverPublicKey = leaverPublicKey;
|
||||
this.groupId = groupId;
|
||||
@ -53,8 +53,8 @@ public class LeaveGroupTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
/** Constructor typically used after deserialization */
|
||||
public LeaveGroupTransactionData(byte[] leaverPublicKey, int groupId, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
this(leaverPublicKey, groupId, null, null, fee, timestamp, reference, signature);
|
||||
public LeaveGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] leaverPublicKey, int groupId, BigDecimal fee, byte[] signature) {
|
||||
this(timestamp, txGroupId, reference, leaverPublicKey, groupId, null, null, fee, signature);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
@ -10,14 +11,14 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class MessageTransactionData extends TransactionData {
|
||||
|
||||
// Properties
|
||||
private int version;
|
||||
private byte[] senderPublicKey;
|
||||
private int version;
|
||||
private String recipient;
|
||||
private Long assetId;
|
||||
private BigDecimal amount;
|
||||
@ -27,16 +28,21 @@ public class MessageTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected MessageTransactionData() {
|
||||
super(TransactionType.MESSAGE);
|
||||
}
|
||||
|
||||
public MessageTransactionData(int version, byte[] senderPublicKey, String recipient, Long assetId, BigDecimal amount, byte[] data, boolean isText,
|
||||
boolean isEncrypted, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.MESSAGE, fee, senderPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.senderPublicKey;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
this.version = version;
|
||||
this.senderPublicKey = senderPublicKey;
|
||||
this.version = version;
|
||||
this.recipient = recipient;
|
||||
|
||||
if (assetId != null)
|
||||
@ -50,21 +56,21 @@ public class MessageTransactionData extends TransactionData {
|
||||
this.isEncrypted = isEncrypted;
|
||||
}
|
||||
|
||||
public MessageTransactionData(int version, byte[] senderPublicKey, String recipient, Long assetId, BigDecimal amount, byte[] data, boolean isText,
|
||||
boolean isEncrypted, BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(version, senderPublicKey, recipient, assetId, amount, data, isText, isEncrypted, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
|
||||
public int getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public byte[] getSenderPublicKey() {
|
||||
return this.senderPublicKey;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public String getRecipient() {
|
||||
return this.recipient;
|
||||
}
|
||||
|
@ -3,15 +3,17 @@ package org.qora.data.transaction;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
import org.qora.data.PaymentData;
|
||||
import org.qora.transaction.Transaction;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class MultiPaymentTransactionData extends TransactionData {
|
||||
@ -22,19 +24,24 @@ public class MultiPaymentTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected MultiPaymentTransactionData() {
|
||||
super(TransactionType.MULTI_PAYMENT);
|
||||
}
|
||||
|
||||
public MultiPaymentTransactionData(byte[] senderPublicKey, List<PaymentData> payments, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(Transaction.TransactionType.MULTI_PAYMENT, fee, senderPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.senderPublicKey;
|
||||
}
|
||||
|
||||
public MultiPaymentTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, List<PaymentData> payments, BigDecimal fee, byte[] signature) {
|
||||
super(Transaction.TransactionType.MULTI_PAYMENT, timestamp, txGroupId, reference, senderPublicKey, fee, signature);
|
||||
|
||||
this.senderPublicKey = senderPublicKey;
|
||||
this.payments = payments;
|
||||
}
|
||||
|
||||
public MultiPaymentTransactionData(byte[] senderPublicKey, List<PaymentData> payments, BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(senderPublicKey, payments, fee, timestamp, reference, null);
|
||||
public MultiPaymentTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, List<PaymentData> payments, BigDecimal fee) {
|
||||
this(timestamp, txGroupId, reference, senderPublicKey, payments, fee, null);
|
||||
}
|
||||
|
||||
// Getters/setters
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
@ -10,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema( allOf = { TransactionData.class } )
|
||||
public class PaymentTransactionData extends TransactionData {
|
||||
@ -29,22 +30,26 @@ public class PaymentTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected PaymentTransactionData() {
|
||||
super(TransactionType.PAYMENT);
|
||||
}
|
||||
|
||||
public PaymentTransactionData(byte[] senderPublicKey, String recipient, BigDecimal amount, BigDecimal fee, long timestamp, byte[] reference,
|
||||
byte[] signature) {
|
||||
super(TransactionType.PAYMENT, fee, senderPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.senderPublicKey;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
this.senderPublicKey = senderPublicKey;
|
||||
this.recipient = recipient;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public PaymentTransactionData(byte[] senderPublicKey, String recipient, BigDecimal amount, BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(senderPublicKey, recipient, amount, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
@ -9,7 +10,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class RegisterNameTransactionData extends TransactionData {
|
||||
@ -26,14 +27,18 @@ public class RegisterNameTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected RegisterNameTransactionData() {
|
||||
super(TransactionType.REGISTER_NAME);
|
||||
}
|
||||
|
||||
public RegisterNameTransactionData(byte[] registrantPublicKey, String owner, String name, String data, BigDecimal fee, long timestamp, byte[] reference,
|
||||
byte[] signature) {
|
||||
super(TransactionType.REGISTER_NAME, fee, registrantPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.registrantPublicKey;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
this.registrantPublicKey = registrantPublicKey;
|
||||
this.owner = owner;
|
||||
@ -41,8 +46,8 @@ public class RegisterNameTransactionData extends TransactionData {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public RegisterNameTransactionData(byte[] registrantPublicKey, String owner, String name, String data, BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(registrantPublicKey, owner, name, data, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -11,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class RemoveGroupAdminTransactionData extends TransactionData {
|
||||
@ -31,7 +31,7 @@ public class RemoveGroupAdminTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected RemoveGroupAdminTransactionData() {
|
||||
super(TransactionType.REMOVE_GROUP_ADMIN);
|
||||
}
|
||||
@ -40,8 +40,8 @@ public class RemoveGroupAdminTransactionData extends TransactionData {
|
||||
this.creatorPublicKey = this.ownerPublicKey;
|
||||
}
|
||||
|
||||
public RemoveGroupAdminTransactionData(byte[] ownerPublicKey, int groupId, String admin, byte[] adminReference, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.REMOVE_GROUP_ADMIN, fee, ownerPublicKey, timestamp, reference, signature);
|
||||
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);
|
||||
|
||||
this.ownerPublicKey = ownerPublicKey;
|
||||
this.groupId = groupId;
|
||||
@ -50,8 +50,8 @@ public class RemoveGroupAdminTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
/** Constructor typically used after deserialization */
|
||||
public RemoveGroupAdminTransactionData(byte[] ownerPublicKey, int groupId, String admin, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
this(ownerPublicKey, groupId, admin, null, fee, timestamp, reference, signature);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
@ -10,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class SellNameTransactionData extends TransactionData {
|
||||
@ -29,21 +30,25 @@ public class SellNameTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected SellNameTransactionData() {
|
||||
super(TransactionType.SELL_NAME);
|
||||
}
|
||||
|
||||
public SellNameTransactionData(byte[] ownerPublicKey, String name, BigDecimal amount, BigDecimal fee, long timestamp, byte[] reference, byte[] signature) {
|
||||
super(TransactionType.SELL_NAME, fee, ownerPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
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);
|
||||
|
||||
this.ownerPublicKey = ownerPublicKey;
|
||||
this.name = name;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public SellNameTransactionData(byte[] ownerPublicKey, String name, BigDecimal amount, BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(ownerPublicKey, name, amount, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -0,0 +1,86 @@
|
||||
package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(
|
||||
allOf = {
|
||||
TransactionData.class
|
||||
}
|
||||
)
|
||||
public class SetGroupTransactionData extends TransactionData {
|
||||
|
||||
// Properties
|
||||
@Schema(
|
||||
description = "account's new default groupID",
|
||||
example = "true"
|
||||
)
|
||||
private int defaultGroupId;
|
||||
/** Reference to previous defaultGroupId, used during orphaning. */
|
||||
// For internal use when orphaning
|
||||
@XmlTransient
|
||||
@Schema(
|
||||
hidden = true
|
||||
)
|
||||
private Integer previousDefaultGroupId;
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAXB
|
||||
protected SetGroupTransactionData() {
|
||||
super(TransactionType.SET_GROUP);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
||||
public int getDefaultGroupId() {
|
||||
return this.defaultGroupId;
|
||||
}
|
||||
|
||||
public Integer getPreviousDefaultGroupId() {
|
||||
return this.previousDefaultGroupId;
|
||||
}
|
||||
|
||||
public void setPreviousDefaultGroupId(int previousDefaultGroupId) {
|
||||
this.previousDefaultGroupId = previousDefaultGroupId;
|
||||
}
|
||||
|
||||
// Re-expose to JAXB
|
||||
|
||||
@Override
|
||||
@XmlElement
|
||||
public byte[] getCreatorPublicKey() {
|
||||
return super.getCreatorPublicKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
@XmlElement
|
||||
public void setCreatorPublicKey(byte[] creatorPublicKey) {
|
||||
super.setCreatorPublicKey(creatorPublicKey);
|
||||
}
|
||||
|
||||
}
|
@ -10,9 +10,6 @@ import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
// XXX are this still needed? see below
|
||||
// import org.eclipse.persistence.oxm.annotations.XmlClassExtractor;
|
||||
// import org.qora.api.TransactionClassExtractor;
|
||||
import org.qora.crypto.Crypto;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
@ -27,8 +24,6 @@ import io.swagger.v3.oas.annotations.media.Schema.AccessMode;
|
||||
* then chances are that class is missing a no-argument constructor!
|
||||
*/
|
||||
|
||||
// XXX is this still in use?
|
||||
// @XmlClassExtractor(TransactionClassExtractor.class)
|
||||
@XmlSeeAlso({GenesisTransactionData.class, PaymentTransactionData.class, RegisterNameTransactionData.class, UpdateNameTransactionData.class,
|
||||
SellNameTransactionData.class, CancelSellNameTransactionData.class, BuyNameTransactionData.class,
|
||||
CreatePollTransactionData.class, VoteOnPollTransactionData.class, ArbitraryTransactionData.class,
|
||||
@ -39,9 +34,10 @@ import io.swagger.v3.oas.annotations.media.Schema.AccessMode;
|
||||
AddGroupAdminTransactionData.class, RemoveGroupAdminTransactionData.class,
|
||||
GroupBanTransactionData.class, CancelGroupBanTransactionData.class,
|
||||
GroupKickTransactionData.class, GroupInviteTransactionData.class,
|
||||
JoinGroupTransactionData.class, LeaveGroupTransactionData.class
|
||||
JoinGroupTransactionData.class, LeaveGroupTransactionData.class,
|
||||
GroupApprovalTransactionData.class, SetGroupTransactionData.class
|
||||
})
|
||||
//All properties to be converted to JSON via JAX-RS
|
||||
//All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public abstract class TransactionData {
|
||||
|
||||
@ -59,6 +55,8 @@ public abstract class TransactionData {
|
||||
protected BigDecimal fee;
|
||||
@Schema(accessMode = AccessMode.READ_ONLY, description = "signature for transaction's raw bytes, using sender's private key", example = "real_transaction_signature_in_base58")
|
||||
protected byte[] signature;
|
||||
@Schema(description = "groupID for this transaction")
|
||||
protected int txGroupId;
|
||||
|
||||
// For JAX-RS use
|
||||
@Schema(accessMode = AccessMode.READ_ONLY, hidden = true, description = "height of block containing transaction")
|
||||
@ -66,26 +64,27 @@ public abstract class TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected TransactionData() {
|
||||
}
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected TransactionData(TransactionType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public TransactionData(TransactionType type, BigDecimal fee, byte[] creatorPublicKey, long timestamp, byte[] reference, byte[] signature) {
|
||||
this.fee = fee;
|
||||
public TransactionData(TransactionType type, long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) {
|
||||
this.type = type;
|
||||
this.creatorPublicKey = creatorPublicKey;
|
||||
this.timestamp = timestamp;
|
||||
this.txGroupId = txGroupId;
|
||||
this.reference = reference;
|
||||
this.creatorPublicKey = creatorPublicKey;
|
||||
this.fee = fee;
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public TransactionData(TransactionType type, BigDecimal fee, byte[] creatorPublicKey, long timestamp, byte[] reference) {
|
||||
this(type, fee, creatorPublicKey, timestamp, reference, null);
|
||||
public TransactionData(TransactionType type, long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee) {
|
||||
this(type, timestamp, txGroupId, reference, creatorPublicKey, fee, null);
|
||||
}
|
||||
|
||||
// Getters/setters
|
||||
@ -94,18 +93,27 @@ public abstract class TransactionData {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public byte[] getCreatorPublicKey() {
|
||||
return this.creatorPublicKey;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return this.timestamp;
|
||||
}
|
||||
|
||||
public int getTxGroupId() {
|
||||
return this.txGroupId;
|
||||
}
|
||||
|
||||
public byte[] getReference() {
|
||||
return this.reference;
|
||||
}
|
||||
|
||||
public byte[] getCreatorPublicKey() {
|
||||
return this.creatorPublicKey;
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public void setCreatorPublicKey(byte[] creatorPublicKey) {
|
||||
this.creatorPublicKey = creatorPublicKey;
|
||||
}
|
||||
|
||||
public BigDecimal getFee() {
|
||||
return this.fee;
|
||||
}
|
||||
@ -125,11 +133,6 @@ public abstract class TransactionData {
|
||||
return Crypto.toAddress(this.creatorPublicKey);
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public void setCreatorPublicKey(byte[] creatorPublicKey) {
|
||||
this.creatorPublicKey = creatorPublicKey;
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public void setBlockHeight(int blockHeight) {
|
||||
this.blockHeight = blockHeight;
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
@ -9,7 +10,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class TransferAssetTransactionData extends TransactionData {
|
||||
@ -22,13 +23,18 @@ public class TransferAssetTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected TransferAssetTransactionData() {
|
||||
super(TransactionType.TRANSFER_ASSET);
|
||||
}
|
||||
|
||||
public TransferAssetTransactionData(byte[] senderPublicKey, String recipient, BigDecimal amount, long assetId, BigDecimal fee, long timestamp,
|
||||
byte[] reference, byte[] signature) {
|
||||
super(TransactionType.TRANSFER_ASSET, fee, senderPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.senderPublicKey;
|
||||
}
|
||||
|
||||
public TransferAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
|
||||
long assetId, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.TRANSFER_ASSET, timestamp, txGroupId, reference, senderPublicKey, fee, signature);
|
||||
|
||||
this.senderPublicKey = senderPublicKey;
|
||||
this.recipient = recipient;
|
||||
@ -36,9 +42,9 @@ public class TransferAssetTransactionData extends TransactionData {
|
||||
this.assetId = assetId;
|
||||
}
|
||||
|
||||
public TransferAssetTransactionData(byte[] senderPublicKey, String recipient, BigDecimal amount, long assetId, BigDecimal fee, long timestamp,
|
||||
byte[] reference) {
|
||||
this(senderPublicKey, recipient, amount, assetId, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters/setters
|
||||
|
@ -7,35 +7,61 @@ import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import org.qora.group.Group.ApprovalThreshold;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
@Schema(
|
||||
allOf = {
|
||||
TransactionData.class
|
||||
}
|
||||
)
|
||||
public class UpdateGroupTransactionData extends TransactionData {
|
||||
|
||||
// Properties
|
||||
@Schema(description = "owner's public key", example = "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP")
|
||||
@Schema(
|
||||
description = "owner's public key",
|
||||
example = "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP"
|
||||
)
|
||||
private byte[] ownerPublicKey;
|
||||
@Schema(description = "new owner's address", example = "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v")
|
||||
@Schema(
|
||||
description = "new owner's address",
|
||||
example = "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v"
|
||||
)
|
||||
private String newOwner;
|
||||
@Schema(description = "which group to update", example = "my-group")
|
||||
@Schema(
|
||||
description = "which group to update",
|
||||
example = "my-group"
|
||||
)
|
||||
private int groupId;
|
||||
@Schema(description = "replacement group description", example = "my group for accounts I like")
|
||||
@Schema(
|
||||
description = "replacement group description",
|
||||
example = "my group for accounts I like"
|
||||
)
|
||||
private String newDescription;
|
||||
@Schema(description = "new group join policy", example = "true")
|
||||
@Schema(
|
||||
description = "new group join policy",
|
||||
example = "true"
|
||||
)
|
||||
private boolean newIsOpen;
|
||||
@Schema(
|
||||
description = "new group member transaction approval threshold"
|
||||
)
|
||||
private ApprovalThreshold newApprovalThreshold;
|
||||
/** Reference to CREATE_GROUP or UPDATE_GROUP transaction, used to rebuild group during orphaning. */
|
||||
// For internal use when orphaning
|
||||
@XmlTransient
|
||||
@Schema(hidden = true)
|
||||
@Schema(
|
||||
hidden = true
|
||||
)
|
||||
private byte[] groupReference;
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected UpdateGroupTransactionData() {
|
||||
super(TransactionType.UPDATE_GROUP);
|
||||
}
|
||||
@ -44,22 +70,23 @@ public class UpdateGroupTransactionData extends TransactionData {
|
||||
this.creatorPublicKey = this.ownerPublicKey;
|
||||
}
|
||||
|
||||
public UpdateGroupTransactionData(byte[] ownerPublicKey, int groupId, String newOwner, String newDescription, boolean newIsOpen, byte[] groupReference, BigDecimal fee, long timestamp,
|
||||
byte[] reference, byte[] signature) {
|
||||
super(TransactionType.UPDATE_GROUP, fee, ownerPublicKey, timestamp, reference, signature);
|
||||
public UpdateGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId,
|
||||
String newOwner, String newDescription, boolean newIsOpen, ApprovalThreshold newApprovalThreshold, byte[] groupReference, BigDecimal fee, byte[] signature) {
|
||||
super(TransactionType.UPDATE_GROUP, timestamp, txGroupId, reference, ownerPublicKey, fee, signature);
|
||||
|
||||
this.ownerPublicKey = ownerPublicKey;
|
||||
this.newOwner = newOwner;
|
||||
this.groupId = groupId;
|
||||
this.newDescription = newDescription;
|
||||
this.newIsOpen = newIsOpen;
|
||||
this.newApprovalThreshold = newApprovalThreshold;
|
||||
this.groupReference = groupReference;
|
||||
}
|
||||
|
||||
/** Constructor typically used after deserialization */
|
||||
public UpdateGroupTransactionData(byte[] ownerPublicKey, int groupId, String newOwner, String newDescription, boolean newIsOpen, BigDecimal fee, long timestamp, byte[] reference,
|
||||
byte[] signature) {
|
||||
this(ownerPublicKey, groupId, newOwner, newDescription, newIsOpen, null, fee, timestamp, reference, signature);
|
||||
public UpdateGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] ownerPublicKey, int groupId,
|
||||
String newOwner, String newDescription, boolean newIsOpen, ApprovalThreshold newApprovalThreshold, BigDecimal fee, byte[] signature) {
|
||||
this(timestamp, txGroupId, reference, ownerPublicKey, groupId, newOwner, newDescription, newIsOpen, newApprovalThreshold, null, fee, signature);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
@ -84,6 +111,10 @@ public class UpdateGroupTransactionData extends TransactionData {
|
||||
return this.newIsOpen;
|
||||
}
|
||||
|
||||
public ApprovalThreshold getNewApprovalThreshold() {
|
||||
return this.newApprovalThreshold;
|
||||
}
|
||||
|
||||
public byte[] getGroupReference() {
|
||||
return this.groupReference;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
@ -10,7 +11,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class UpdateNameTransactionData extends TransactionData {
|
||||
@ -31,14 +32,18 @@ public class UpdateNameTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected UpdateNameTransactionData() {
|
||||
super(TransactionType.UPDATE_NAME);
|
||||
}
|
||||
|
||||
public UpdateNameTransactionData(byte[] ownerPublicKey, String newOwner, String name, String newData, byte[] nameReference, BigDecimal fee, long timestamp,
|
||||
byte[] reference, byte[] signature) {
|
||||
super(TransactionType.UPDATE_NAME, fee, ownerPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.ownerPublicKey;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
this.ownerPublicKey = ownerPublicKey;
|
||||
this.newOwner = newOwner;
|
||||
@ -47,14 +52,14 @@ public class UpdateNameTransactionData extends TransactionData {
|
||||
this.nameReference = nameReference;
|
||||
}
|
||||
|
||||
public UpdateNameTransactionData(byte[] ownerPublicKey, String newOwner, String name, String newData, BigDecimal fee, long timestamp, byte[] reference,
|
||||
byte[] signature) {
|
||||
this(ownerPublicKey, newOwner, name, newData, null, fee, timestamp, reference, signature);
|
||||
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);
|
||||
}
|
||||
|
||||
public UpdateNameTransactionData(byte[] ownerPublicKey, String newOwner, String name, String newData, byte[] nameReference, BigDecimal fee, long timestamp,
|
||||
byte[] reference) {
|
||||
this(ownerPublicKey, newOwner, name, newData, nameReference, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -2,6 +2,7 @@ package org.qora.data.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
@ -9,7 +10,7 @@ import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
// All properties to be converted to JSON via JAX-RS
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Schema(allOf = { TransactionData.class })
|
||||
public class VoteOnPollTransactionData extends TransactionData {
|
||||
@ -22,13 +23,18 @@ public class VoteOnPollTransactionData extends TransactionData {
|
||||
|
||||
// Constructors
|
||||
|
||||
// For JAX-RS
|
||||
// For JAXB
|
||||
protected VoteOnPollTransactionData() {
|
||||
super(TransactionType.VOTE_ON_POLL);
|
||||
}
|
||||
|
||||
public VoteOnPollTransactionData(byte[] voterPublicKey, String pollName, int optionIndex, Integer previousOptionIndex, BigDecimal fee, long timestamp,
|
||||
byte[] reference, byte[] signature) {
|
||||
super(TransactionType.VOTE_ON_POLL, fee, voterPublicKey, timestamp, reference, signature);
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
this.creatorPublicKey = this.voterPublicKey;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
this.voterPublicKey = voterPublicKey;
|
||||
this.pollName = pollName;
|
||||
@ -36,13 +42,13 @@ public class VoteOnPollTransactionData extends TransactionData {
|
||||
this.previousOptionIndex = previousOptionIndex;
|
||||
}
|
||||
|
||||
public VoteOnPollTransactionData(byte[] voterPublicKey, String pollName, int optionIndex, BigDecimal fee, long timestamp, byte[] reference,
|
||||
byte[] signature) {
|
||||
this(voterPublicKey, pollName, optionIndex, null, fee, timestamp, reference, signature);
|
||||
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);
|
||||
}
|
||||
|
||||
public VoteOnPollTransactionData(byte[] voterPublicKey, String pollName, int optionIndex, BigDecimal fee, long timestamp, byte[] reference) {
|
||||
this(voterPublicKey, pollName, optionIndex, null, fee, timestamp, reference, null);
|
||||
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);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
|
@ -1,6 +1,10 @@
|
||||
package org.qora.group;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.qora.account.Account;
|
||||
import org.qora.account.PublicKeyAccount;
|
||||
@ -28,12 +32,68 @@ import org.qora.repository.Repository;
|
||||
|
||||
public class Group {
|
||||
|
||||
/** Group-admin quora threshold for approving transactions */
|
||||
public enum ApprovalThreshold {
|
||||
// NOTE: value needs to fit into byte
|
||||
NONE(0, false),
|
||||
ONE(1, false),
|
||||
PCT20(20, true),
|
||||
PCT40(40, true),
|
||||
PCT60(60, true),
|
||||
PCT80(80, true),
|
||||
PCT100(100, true);
|
||||
|
||||
public final int value;
|
||||
public final boolean isPercentage;
|
||||
|
||||
private final static Map<Integer, ApprovalThreshold> map = stream(ApprovalThreshold.values()).collect(toMap(threshold -> threshold.value, threshold -> threshold));
|
||||
|
||||
ApprovalThreshold(int value, boolean isPercentage) {
|
||||
this.value = value;
|
||||
this.isPercentage = isPercentage;
|
||||
}
|
||||
|
||||
public static ApprovalThreshold valueOf(int value) {
|
||||
return map.get(value);
|
||||
}
|
||||
|
||||
private boolean meetsTheshold(int currentApprovals, int totalAdmins) {
|
||||
if (!this.isPercentage)
|
||||
return currentApprovals >= this.value;
|
||||
|
||||
return currentApprovals >= (totalAdmins * 100 / this.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether transaction need approval.
|
||||
*
|
||||
* @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 needsApproval(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
|
||||
private Repository repository;
|
||||
private GroupRepository groupRepository;
|
||||
private GroupData groupData;
|
||||
|
||||
// Useful constants
|
||||
public static final int NO_GROUP = -1;
|
||||
public static final int DEFAULT_GROUP = 0;
|
||||
|
||||
public static final int MAX_NAME_SIZE = 32;
|
||||
public static final int MAX_DESCRIPTION_SIZE = 128;
|
||||
/** Max size of kick/ban reason */
|
||||
@ -53,7 +113,7 @@ public class Group {
|
||||
|
||||
this.groupData = new GroupData(createGroupTransactionData.getOwner(), createGroupTransactionData.getGroupName(),
|
||||
createGroupTransactionData.getDescription(), createGroupTransactionData.getTimestamp(), createGroupTransactionData.getIsOpen(),
|
||||
createGroupTransactionData.getSignature());
|
||||
createGroupTransactionData.getApprovalThreshold(), createGroupTransactionData.getSignature());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,6 +313,7 @@ public class Group {
|
||||
this.groupData.setOwner(updateGroupTransactionData.getNewOwner());
|
||||
this.groupData.setDescription(updateGroupTransactionData.getNewDescription());
|
||||
this.groupData.setIsOpen(updateGroupTransactionData.getNewIsOpen());
|
||||
this.groupData.setApprovalThreshold(updateGroupTransactionData.getNewApprovalThreshold());
|
||||
this.groupData.setUpdated(updateGroupTransactionData.getTimestamp());
|
||||
|
||||
// Save updated group data
|
||||
@ -311,6 +372,7 @@ public class Group {
|
||||
this.groupData.setOwner(previousCreateGroupTransactionData.getOwner());
|
||||
this.groupData.setDescription(previousCreateGroupTransactionData.getDescription());
|
||||
this.groupData.setIsOpen(previousCreateGroupTransactionData.getIsOpen());
|
||||
this.groupData.setApprovalThreshold(previousCreateGroupTransactionData.getApprovalThreshold());
|
||||
this.groupData.setUpdated(null);
|
||||
break;
|
||||
|
||||
@ -319,6 +381,7 @@ public class Group {
|
||||
this.groupData.setOwner(previousUpdateGroupTransactionData.getNewOwner());
|
||||
this.groupData.setDescription(previousUpdateGroupTransactionData.getNewDescription());
|
||||
this.groupData.setIsOpen(previousUpdateGroupTransactionData.getNewIsOpen());
|
||||
this.groupData.setApprovalThreshold(previousUpdateGroupTransactionData.getNewApprovalThreshold());
|
||||
this.groupData.setUpdated(previousUpdateGroupTransactionData.getTimestamp());
|
||||
break;
|
||||
|
||||
|
@ -9,11 +9,35 @@ public interface AccountRepository {
|
||||
|
||||
// General account
|
||||
|
||||
public void create(AccountData accountData) throws DataException;
|
||||
|
||||
/** Returns all general information about account, e.g. public key, last reference, default group ID. */
|
||||
public AccountData getAccount(String address) throws DataException;
|
||||
|
||||
public void save(AccountData accountData) throws DataException;
|
||||
/** Returns account's last reference or null if not set or account not found. */
|
||||
public byte[] getLastReference(String address) throws DataException;
|
||||
|
||||
/** Returns account's default groupID or null if account not found. */
|
||||
public Integer getDefaultGroupId(String address) throws DataException;
|
||||
|
||||
/**
|
||||
* Ensures at least minimal account info in repository.
|
||||
* <p>
|
||||
* Saves account address, and public key if present.
|
||||
*/
|
||||
public void ensureAccount(AccountData accountData) throws DataException;
|
||||
|
||||
/**
|
||||
* Saves account's last reference, and public key if present, in repository.
|
||||
* <p>
|
||||
* Note: ignores other fields like default group ID.
|
||||
*/
|
||||
public void setLastReference(AccountData accountData) throws DataException;
|
||||
|
||||
/**
|
||||
* Saves account's default groupID, and public key if present, in repository.
|
||||
* <p>
|
||||
* Note: ignores other fields like last reference.
|
||||
*/
|
||||
public void setDefaultGroupId(AccountData accountData) throws DataException;
|
||||
|
||||
public void delete(String address) throws DataException;
|
||||
|
||||
|
@ -3,6 +3,7 @@ package org.qora.repository;
|
||||
import java.util.List;
|
||||
|
||||
import org.qora.api.resource.TransactionsResource.ConfirmationStatus;
|
||||
import org.qora.data.transaction.GroupApprovalTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
|
||||
@ -46,6 +47,20 @@ public interface TransactionRepository {
|
||||
public List<TransactionData> getAssetTransactions(int assetId, ConfirmationStatus confirmationStatus, Integer limit, Integer offset, Boolean reverse)
|
||||
throws DataException;
|
||||
|
||||
/** Returns number of approvals for transaction with given signature. */
|
||||
public int countTransactionApprovals(int txGroupId, byte[] signature) throws DataException;
|
||||
|
||||
/**
|
||||
* Returns list of latest approval decisions per admin for given pending transaction signature.
|
||||
*
|
||||
* @param signature
|
||||
* @param adminPublicKey
|
||||
* restrict results to decision by this admin, pass null for all admins' results
|
||||
* @return
|
||||
* @throws DataException
|
||||
*/
|
||||
public List<GroupApprovalTransactionData> getLatestApprovals(byte[] pendingSignature, byte[] adminPublicKey) throws DataException;
|
||||
|
||||
/**
|
||||
* Returns whether transaction is confirmed or not.
|
||||
*
|
||||
|
@ -22,7 +22,48 @@ public class HSQLDBAccountRepository implements AccountRepository {
|
||||
// General account
|
||||
|
||||
@Override
|
||||
public void create(AccountData accountData) throws DataException {
|
||||
public AccountData getAccount(String address) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT reference, public_key, default_group_id FROM Accounts WHERE account = ?", address)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
byte[] reference = resultSet.getBytes(1);
|
||||
byte[] publicKey = resultSet.getBytes(2);
|
||||
int defaultGroupId = resultSet.getInt(3);
|
||||
|
||||
return new AccountData(address, reference, publicKey, defaultGroupId);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch account info from repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getLastReference(String address) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT reference FROM Accounts WHERE account = ?", address)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
return resultSet.getBytes(1);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch account's last reference from repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getDefaultGroupId(String address) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT default_group_id FROM Accounts WHERE account = ?", address)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
// Column is NOT NULL so this should never implicitly convert to 0
|
||||
return resultSet.getInt(1);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch account's default groupID from repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ensureAccount(AccountData accountData) throws DataException {
|
||||
HSQLDBSaver saveHelper = new HSQLDBSaver("Accounts");
|
||||
|
||||
saveHelper.bind("account", accountData.getAddress());
|
||||
@ -34,35 +75,41 @@ public class HSQLDBAccountRepository implements AccountRepository {
|
||||
try {
|
||||
saveHelper.execute(this.repository);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to create account in repository", e);
|
||||
throw new DataException("Unable to ensure minimal account in repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountData getAccount(String address) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT reference, public_key FROM Accounts WHERE account = ?", address)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
byte[] reference = resultSet.getBytes(1);
|
||||
byte[] publicKey = resultSet.getBytes(2);
|
||||
|
||||
return new AccountData(address, reference, publicKey);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch account info from repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(AccountData accountData) throws DataException {
|
||||
public void setLastReference(AccountData accountData) throws DataException {
|
||||
HSQLDBSaver saveHelper = new HSQLDBSaver("Accounts");
|
||||
|
||||
saveHelper.bind("account", accountData.getAddress()).bind("reference", accountData.getReference()).bind("public_key", accountData.getPublicKey());
|
||||
saveHelper.bind("account", accountData.getAddress()).bind("reference", accountData.getReference());
|
||||
|
||||
byte[] publicKey = accountData.getPublicKey();
|
||||
if (publicKey != null)
|
||||
saveHelper.bind("public_key", publicKey);
|
||||
|
||||
try {
|
||||
saveHelper.execute(this.repository);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to save account info into repository", e);
|
||||
throw new DataException("Unable to save account's last reference into repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultGroupId(AccountData accountData) throws DataException {
|
||||
HSQLDBSaver saveHelper = new HSQLDBSaver("Accounts");
|
||||
|
||||
saveHelper.bind("account", accountData.getAddress()).bind("default_group_id", accountData.getDefaultGroupId());
|
||||
|
||||
byte[] publicKey = accountData.getPublicKey();
|
||||
if (publicKey != null)
|
||||
saveHelper.bind("public_key", publicKey);
|
||||
|
||||
try {
|
||||
saveHelper.execute(this.repository);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to save account's default group ID into repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,13 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class HSQLDBDatabaseUpdates {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(HSQLDBDatabaseUpdates.class);
|
||||
|
||||
/**
|
||||
* Apply any incremental changes to database schema.
|
||||
*
|
||||
@ -526,6 +531,33 @@ public class HSQLDBDatabaseUpdates {
|
||||
stmt.execute("ALTER TABLE PeersTEMP RENAME TO Peers");
|
||||
break;
|
||||
|
||||
case 33:
|
||||
// Add groupID to all transactions - groupID 0 is default, which means groupless/no-group
|
||||
stmt.execute("ALTER TABLE Transactions ADD COLUMN tx_group_id GroupID NOT NULL DEFAULT 0");
|
||||
stmt.execute("CREATE INDEX TransactionGroupIndex ON Transactions (tx_group_id)");
|
||||
|
||||
// Adding approval to group-based transactions
|
||||
// Default approval threshold is 100% for existing groups but probably of no effect in production
|
||||
stmt.execute("ALTER TABLE Groups ADD COLUMN approval_threshold TINYINT NOT NULL DEFAULT 100 BEFORE reference");
|
||||
stmt.execute("ALTER TABLE CreateGroupTransactions ADD COLUMN approval_threshold TINYINT NOT NULL DEFAULT 100 BEFORE group_id");
|
||||
stmt.execute("ALTER TABLE UpdateGroupTransactions ADD COLUMN new_approval_threshold TINYINT NOT NULL DEFAULT 100 BEFORE group_reference");
|
||||
|
||||
// Approval transactions themselves
|
||||
// "pending_signature" contains signature of pending transaction requiring approval
|
||||
// "prior_reference" contains signature of previous approval transaction for orphaning purposes
|
||||
stmt.execute("CREATE TABLE GroupApprovalTransactions (signature Signature, admin QoraPublicKey NOT NULL, pending_signature Signature NOT NULL, approval BOOLEAN NOT NULL, "
|
||||
+ "prior_reference Signature, PRIMARY KEY (signature), FOREIGN KEY (signature) REFERENCES Transactions (signature) ON DELETE CASCADE)");
|
||||
|
||||
// Accounts have a default groupID to be used if transaction's txGroupId is 0
|
||||
stmt.execute("ALTER TABLE Accounts add default_group_id GroupID NOT NULL DEFAULT 0");
|
||||
break;
|
||||
|
||||
case 34:
|
||||
// SET_GROUP transaction support
|
||||
stmt.execute("CREATE TABLE SetGroupTransactions (signature Signature, default_group_id GroupID NOT NULL, previous_default_group_id GroupID, "
|
||||
+ "PRIMARY KEY (signature), FOREIGN KEY (signature) REFERENCES Transactions (signature) ON DELETE CASCADE)");
|
||||
break;
|
||||
|
||||
default:
|
||||
// nothing to do
|
||||
return false;
|
||||
@ -533,6 +565,7 @@ public class HSQLDBDatabaseUpdates {
|
||||
}
|
||||
|
||||
// database was updated
|
||||
LOGGER.info(String.format("HSQLDB repository updated to version %d", databaseVersion + 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ import org.qora.data.group.GroupData;
|
||||
import org.qora.data.group.GroupInviteData;
|
||||
import org.qora.data.group.GroupJoinRequestData;
|
||||
import org.qora.data.group.GroupMemberData;
|
||||
import org.qora.group.Group.ApprovalThreshold;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.GroupRepository;
|
||||
|
||||
@ -29,7 +30,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
@Override
|
||||
public GroupData fromGroupId(int groupId) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT group_name, owner, description, created, updated, reference, is_open FROM Groups WHERE group_id = ?", groupId)) {
|
||||
.checkedExecute("SELECT group_name, owner, description, created, updated, reference, is_open, approval_threshold FROM Groups WHERE group_id = ?", groupId)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
@ -45,7 +46,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
byte[] reference = resultSet.getBytes(6);
|
||||
boolean isOpen = resultSet.getBoolean(7);
|
||||
|
||||
return new GroupData(groupId, owner, groupName, description, created, updated, isOpen, reference);
|
||||
ApprovalThreshold approvalThreshold = ApprovalThreshold.valueOf(resultSet.getInt(8));
|
||||
|
||||
return new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, reference);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch group info from repository", e);
|
||||
}
|
||||
@ -54,7 +57,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
@Override
|
||||
public GroupData fromGroupName(String groupName) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT group_id, owner, description, created, updated, reference, is_open FROM Groups WHERE group_name = ?", groupName)) {
|
||||
.checkedExecute("SELECT group_id, owner, description, created, updated, reference, is_open, approval_threshold FROM Groups WHERE group_name = ?", groupName)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
@ -70,7 +73,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
byte[] reference = resultSet.getBytes(6);
|
||||
boolean isOpen = resultSet.getBoolean(7);
|
||||
|
||||
return new GroupData(groupId, owner, groupName, description, created, updated, isOpen, reference);
|
||||
ApprovalThreshold approvalThreshold = ApprovalThreshold.valueOf(resultSet.getInt(8));
|
||||
|
||||
return new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, reference);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch group info from repository", e);
|
||||
}
|
||||
@ -96,7 +101,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
|
||||
@Override
|
||||
public List<GroupData> getAllGroups(Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open FROM Groups ORDER BY group_name";
|
||||
String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open, approval_threshold FROM Groups ORDER BY group_name";
|
||||
if (reverse != null && reverse)
|
||||
sql += " DESC";
|
||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||
@ -121,7 +126,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
byte[] reference = resultSet.getBytes(7);
|
||||
boolean isOpen = resultSet.getBoolean(8);
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, reference));
|
||||
ApprovalThreshold approvalThreshold = ApprovalThreshold.valueOf(resultSet.getInt(9));
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, reference));
|
||||
} while (resultSet.next());
|
||||
|
||||
return groups;
|
||||
@ -132,7 +139,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
|
||||
@Override
|
||||
public List<GroupData> getGroupsByOwner(String owner, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
String sql = "SELECT group_id, group_name, description, created, updated, reference, is_open FROM Groups WHERE owner = ? ORDER BY group_name";
|
||||
String sql = "SELECT group_id, group_name, description, created, updated, reference, is_open, approval_threshold FROM Groups WHERE owner = ? ORDER BY group_name";
|
||||
if (reverse != null && reverse)
|
||||
sql += " DESC";
|
||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||
@ -156,7 +163,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
byte[] reference = resultSet.getBytes(6);
|
||||
boolean isOpen = resultSet.getBoolean(7);
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, reference));
|
||||
ApprovalThreshold approvalThreshold = ApprovalThreshold.valueOf(resultSet.getInt(8));
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, reference));
|
||||
} while (resultSet.next());
|
||||
|
||||
return groups;
|
||||
@ -167,7 +176,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
|
||||
@Override
|
||||
public List<GroupData> getGroupsWithMember(String member, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open FROM Groups JOIN GroupMembers USING (group_id) WHERE address = ? ORDER BY group_name";
|
||||
String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open, approval_threshold FROM Groups JOIN GroupMembers USING (group_id) WHERE address = ? ORDER BY group_name";
|
||||
if (reverse != null && reverse)
|
||||
sql += " DESC";
|
||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||
@ -192,7 +201,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
byte[] reference = resultSet.getBytes(7);
|
||||
boolean isOpen = resultSet.getBoolean(8);
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, reference));
|
||||
ApprovalThreshold approvalThreshold = ApprovalThreshold.valueOf(resultSet.getInt(9));
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, reference));
|
||||
} while (resultSet.next());
|
||||
|
||||
return groups;
|
||||
@ -211,7 +222,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
|
||||
saveHelper.bind("group_id", groupData.getGroupId()).bind("owner", groupData.getOwner()).bind("group_name", groupData.getGroupName())
|
||||
.bind("description", groupData.getDescription()).bind("created", new Timestamp(groupData.getCreated())).bind("updated", updatedTimestamp)
|
||||
.bind("reference", groupData.getReference()).bind("is_open", groupData.getIsOpen());
|
||||
.bind("reference", groupData.getReference()).bind("is_open", groupData.getIsOpen()).bind("approval_threshold", groupData.getApprovalThreshold().value);
|
||||
|
||||
try {
|
||||
saveHelper.execute(this.repository);
|
||||
|
@ -7,8 +7,8 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Savepoint;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@ -36,13 +36,13 @@ public class HSQLDBRepository implements Repository {
|
||||
public static final TimeZone UTC = TimeZone.getTimeZone("UTC");
|
||||
|
||||
protected Connection connection;
|
||||
protected List<Savepoint> savepoints;
|
||||
protected Deque<Savepoint> savepoints;
|
||||
protected boolean debugState = false;
|
||||
|
||||
// NB: no visibility modifier so only callable from within same package
|
||||
HSQLDBRepository(Connection connection) {
|
||||
this.connection = connection;
|
||||
this.savepoints = new ArrayList<>();
|
||||
this.savepoints = new ArrayDeque<>(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -116,7 +116,7 @@ public class HSQLDBRepository implements Repository {
|
||||
public void setSavepoint() throws DataException {
|
||||
try {
|
||||
Savepoint savepoint = this.connection.setSavepoint();
|
||||
this.savepoints.add(savepoint);
|
||||
this.savepoints.push(savepoint);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("savepoint error", e);
|
||||
}
|
||||
@ -127,8 +127,7 @@ public class HSQLDBRepository implements Repository {
|
||||
if (this.savepoints.isEmpty())
|
||||
throw new DataException("no savepoint to rollback");
|
||||
|
||||
Savepoint savepoint = this.savepoints.get(0);
|
||||
this.savepoints.remove(0);
|
||||
Savepoint savepoint = this.savepoints.pop();
|
||||
|
||||
try {
|
||||
this.connection.rollback(savepoint);
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBAddGroupAdminTransactionRepository extends HSQLDBTransactionR
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +24,7 @@ public class HSQLDBAddGroupAdminTransactionRepository extends HSQLDBTransactionR
|
||||
int groupId = resultSet.getInt(1);
|
||||
String member = resultSet.getString(2);
|
||||
|
||||
return new AddGroupAdminTransactionData(creatorPublicKey, groupId, member, fee, timestamp, reference, signature);
|
||||
return new AddGroupAdminTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, member, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch add group admin transaction from repository", e);
|
||||
}
|
||||
|
@ -19,21 +19,20 @@ public class HSQLDBArbitraryTransactionRepository extends HSQLDBTransactionRepos
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT sender, version, service, data_hash from ArbitraryTransactions WHERE signature = ?",
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT version, service, data_hash from ArbitraryTransactions WHERE signature = ?",
|
||||
signature)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
byte[] senderPublicKey = resultSet.getBytes(1);
|
||||
int version = resultSet.getInt(2);
|
||||
int service = resultSet.getInt(3);
|
||||
byte[] dataHash = resultSet.getBytes(4);
|
||||
int version = resultSet.getInt(1);
|
||||
int service = resultSet.getInt(2);
|
||||
byte[] dataHash = resultSet.getBytes(3);
|
||||
|
||||
List<PaymentData> payments = this.getPaymentsFromSignature(signature);
|
||||
|
||||
return new ArbitraryTransactionData(version, senderPublicKey, service, dataHash, DataType.DATA_HASH, payments, fee, timestamp, reference,
|
||||
signature);
|
||||
return new ArbitraryTransactionData(timestamp, txGroupId, reference, creatorPublicKey, version, service, dataHash, DataType.DATA_HASH, payments,
|
||||
fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch arbitrary transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBAtTransactionRepository extends HSQLDBTransactionRepository {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +37,7 @@ public class HSQLDBAtTransactionRepository extends HSQLDBTransactionRepository {
|
||||
if (resultSet.wasNull())
|
||||
message = null;
|
||||
|
||||
return new ATTransactionData(atAddress, recipient, amount, assetId, message, fee, timestamp, reference, signature);
|
||||
return new ATTransactionData(timestamp, txGroupId, reference, atAddress, recipient, amount, assetId, message, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch AT transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBBuyNameTransactionRepository extends HSQLDBTransactionReposit
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] buyerPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +27,7 @@ public class HSQLDBBuyNameTransactionRepository extends HSQLDBTransactionReposit
|
||||
String seller = resultSet.getString(3);
|
||||
byte[] nameReference = resultSet.getBytes(4);
|
||||
|
||||
return new BuyNameTransactionData(buyerPublicKey, name, amount, seller, nameReference, fee, timestamp, reference, signature);
|
||||
return new BuyNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, name, amount, seller, nameReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch buy name transaction from repository", e);
|
||||
}
|
||||
|
@ -16,14 +16,14 @@ public class HSQLDBCancelAssetOrderTransactionRepository extends HSQLDBTransacti
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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(creatorPublicKey, assetOrderId, fee, timestamp, reference, signature);
|
||||
return new CancelAssetOrderTransactionData(timestamp, txGroupId, reference, creatorPublicKey, assetOrderId, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch cancel order transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBCancelGroupBanTransactionRepository extends HSQLDBTransaction
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +26,7 @@ public class HSQLDBCancelGroupBanTransactionRepository extends HSQLDBTransaction
|
||||
String member = resultSet.getString(2);
|
||||
byte[] banReference = resultSet.getBytes(3);
|
||||
|
||||
return new CancelGroupBanTransactionData(creatorPublicKey, groupId, member, banReference, fee, timestamp, reference, signature);
|
||||
return new CancelGroupBanTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, member, banReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch group unban transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBCancelGroupInviteTransactionRepository extends HSQLDBTransact
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +26,7 @@ public class HSQLDBCancelGroupInviteTransactionRepository extends HSQLDBTransact
|
||||
String invitee = resultSet.getString(2);
|
||||
byte[] inviteReference = resultSet.getBytes(3);
|
||||
|
||||
return new CancelGroupInviteTransactionData(creatorPublicKey, groupId, invitee, inviteReference, fee, timestamp, reference, signature);
|
||||
return new CancelGroupInviteTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, invitee, inviteReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch cancel group invite transaction from repository", e);
|
||||
}
|
||||
|
@ -16,14 +16,14 @@ public class HSQLDBCancelSellNameTransactionRepository extends HSQLDBTransaction
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] ownerPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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(ownerPublicKey, name, fee, timestamp, reference, signature);
|
||||
return new CancelSellNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, name, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch cancel sell name transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBCreateAssetOrderTransactionRepository extends HSQLDBTransacti
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT have_asset_id, amount, want_asset_id, price FROM CreateAssetOrderTransactions WHERE signature = ?", signature)) {
|
||||
if (resultSet == null)
|
||||
@ -27,7 +27,7 @@ public class HSQLDBCreateAssetOrderTransactionRepository extends HSQLDBTransacti
|
||||
long wantAssetId = resultSet.getLong(3);
|
||||
BigDecimal price = resultSet.getBigDecimal(4);
|
||||
|
||||
return new CreateAssetOrderTransactionData(creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, timestamp, reference, signature);
|
||||
return new CreateAssetOrderTransactionData(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch create order transaction from repository", e);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import java.sql.SQLException;
|
||||
|
||||
import org.qora.data.transaction.CreateGroupTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.group.Group.ApprovalThreshold;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.hsqldb.HSQLDBRepository;
|
||||
import org.qora.repository.hsqldb.HSQLDBSaver;
|
||||
@ -16,9 +17,9 @@ public class HSQLDBCreateGroupTransactionRepository extends HSQLDBTransactionRep
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT owner, group_name, description, is_open, group_id FROM CreateGroupTransactions WHERE signature = ?", signature)) {
|
||||
.checkedExecute("SELECT owner, group_name, description, is_open, approval_threshold, group_id FROM CreateGroupTransactions WHERE signature = ?", signature)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
@ -27,11 +28,14 @@ public class HSQLDBCreateGroupTransactionRepository extends HSQLDBTransactionRep
|
||||
String description = resultSet.getString(3);
|
||||
boolean isOpen = resultSet.getBoolean(4);
|
||||
|
||||
Integer groupId = resultSet.getInt(5);
|
||||
ApprovalThreshold approvalThreshold = ApprovalThreshold.valueOf(resultSet.getInt(5));
|
||||
|
||||
Integer groupId = resultSet.getInt(6);
|
||||
if (resultSet.wasNull())
|
||||
groupId = null;
|
||||
|
||||
return new CreateGroupTransactionData(creatorPublicKey, owner, groupName, description, isOpen, groupId, fee, timestamp, reference, signature);
|
||||
return new CreateGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, owner, groupName, description, isOpen, approvalThreshold,
|
||||
groupId, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch create group transaction from repository", e);
|
||||
}
|
||||
@ -46,6 +50,7 @@ public class HSQLDBCreateGroupTransactionRepository extends HSQLDBTransactionRep
|
||||
saveHelper.bind("signature", createGroupTransactionData.getSignature()).bind("creator", createGroupTransactionData.getCreatorPublicKey())
|
||||
.bind("owner", createGroupTransactionData.getOwner()).bind("group_name", createGroupTransactionData.getGroupName())
|
||||
.bind("description", createGroupTransactionData.getDescription()).bind("is_open", createGroupTransactionData.getIsOpen())
|
||||
.bind("approval_threshold", createGroupTransactionData.getApprovalThreshold().value)
|
||||
.bind("group_id", createGroupTransactionData.getGroupId());
|
||||
|
||||
try {
|
||||
|
@ -19,7 +19,7 @@ public class HSQLDBCreatePollTransactionRepository extends HSQLDBTransactionRepo
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +43,7 @@ public class HSQLDBCreatePollTransactionRepository extends HSQLDBTransactionRepo
|
||||
pollOptions.add(new PollOptionData(optionName));
|
||||
} while (optionsResultSet.next());
|
||||
|
||||
return new CreatePollTransactionData(creatorPublicKey, owner, pollName, description, pollOptions, fee, timestamp, reference, signature);
|
||||
return new CreatePollTransactionData(timestamp, txGroupId, reference, creatorPublicKey, owner, pollName, description, pollOptions, fee, signature);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch create poll transaction from repository", e);
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBDeployAtTransactionRepository extends HSQLDBTransactionReposi
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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)) {
|
||||
@ -25,19 +25,19 @@ public class HSQLDBDeployAtTransactionRepository extends HSQLDBTransactionReposi
|
||||
|
||||
String name = resultSet.getString(1);
|
||||
String description = resultSet.getString(2);
|
||||
String ATType = resultSet.getString(3);
|
||||
String atType = resultSet.getString(3);
|
||||
String tags = resultSet.getString(4);
|
||||
byte[] creationBytes = resultSet.getBytes(5);
|
||||
BigDecimal amount = resultSet.getBigDecimal(6).setScale(8);
|
||||
long assetId = resultSet.getLong(7);
|
||||
|
||||
// Special null-checking for AT address
|
||||
String ATAddress = resultSet.getString(8);
|
||||
String atAddress = resultSet.getString(8);
|
||||
if (resultSet.wasNull())
|
||||
ATAddress = null;
|
||||
atAddress = null;
|
||||
|
||||
return new DeployAtTransactionData(ATAddress, creatorPublicKey, name, description, ATType, tags, creationBytes, amount, assetId, fee, timestamp,
|
||||
reference, signature);
|
||||
return new DeployAtTransactionData(timestamp, txGroupId, reference, creatorPublicKey, atAddress, name, description, atType, tags, creationBytes, amount,
|
||||
assetId, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch deploy AT transaction from repository", e);
|
||||
}
|
||||
@ -51,9 +51,9 @@ public class HSQLDBDeployAtTransactionRepository extends HSQLDBTransactionReposi
|
||||
|
||||
saveHelper.bind("signature", deployATTransactionData.getSignature()).bind("creator", deployATTransactionData.getCreatorPublicKey())
|
||||
.bind("AT_name", deployATTransactionData.getName()).bind("description", deployATTransactionData.getDescription())
|
||||
.bind("AT_type", deployATTransactionData.getATType()).bind("AT_tags", deployATTransactionData.getTags())
|
||||
.bind("AT_type", deployATTransactionData.getAtType()).bind("AT_tags", deployATTransactionData.getTags())
|
||||
.bind("creation_bytes", deployATTransactionData.getCreationBytes()).bind("amount", deployATTransactionData.getAmount())
|
||||
.bind("asset_id", deployATTransactionData.getAssetId()).bind("AT_address", deployATTransactionData.getATAddress());
|
||||
.bind("asset_id", deployATTransactionData.getAssetId()).bind("AT_address", deployATTransactionData.getAtAddress());
|
||||
|
||||
try {
|
||||
saveHelper.execute(this.repository);
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBGenesisTransactionRepository extends HSQLDBTransactionReposit
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT recipient, amount, asset_id FROM GenesisTransactions WHERE signature = ?",
|
||||
signature)) {
|
||||
if (resultSet == null)
|
||||
@ -26,7 +26,7 @@ public class HSQLDBGenesisTransactionRepository extends HSQLDBTransactionReposit
|
||||
BigDecimal amount = resultSet.getBigDecimal(2).setScale(8);
|
||||
long assetId = resultSet.getLong(3);
|
||||
|
||||
return new GenesisTransactionData(recipient, amount, assetId, timestamp, signature);
|
||||
return new GenesisTransactionData(timestamp, recipient, amount, assetId, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch genesis transaction from repository", e);
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
package org.qora.repository.hsqldb.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.qora.data.transaction.GroupApprovalTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.hsqldb.HSQLDBRepository;
|
||||
import org.qora.repository.hsqldb.HSQLDBSaver;
|
||||
|
||||
public class HSQLDBGroupApprovalTransactionRepository extends HSQLDBTransactionRepository {
|
||||
|
||||
public HSQLDBGroupApprovalTransactionRepository(HSQLDBRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT pending_signature, approval, prior_reference FROM GroupApprovalTransactions WHERE signature = ?", signature)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
byte[] pendingSignature = resultSet.getBytes(1);
|
||||
boolean approval = resultSet.getBoolean(2);
|
||||
byte[] priorReference = resultSet.getBytes(3);
|
||||
|
||||
return new GroupApprovalTransactionData(timestamp, txGroupId, reference, creatorPublicKey, pendingSignature, approval, priorReference, fee,
|
||||
signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch group approval transaction from repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(TransactionData transactionData) throws DataException {
|
||||
GroupApprovalTransactionData groupApprovalTransactionData = (GroupApprovalTransactionData) transactionData;
|
||||
|
||||
HSQLDBSaver saveHelper = new HSQLDBSaver("GroupApprovalTransactions");
|
||||
|
||||
saveHelper.bind("signature", groupApprovalTransactionData.getSignature()).bind("admin", groupApprovalTransactionData.getAdminPublicKey())
|
||||
.bind("pending_signature", groupApprovalTransactionData.getPendingSignature()).bind("approval", groupApprovalTransactionData.getApproval())
|
||||
.bind("prior_reference", groupApprovalTransactionData.getPriorReference());
|
||||
|
||||
try {
|
||||
saveHelper.execute(this.repository);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to save group approval transaction into repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -16,7 +16,7 @@ public class HSQLDBGroupBanTransactionRepository extends HSQLDBTransactionReposi
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 FROM GroupBanTransactions WHERE signature = ?",
|
||||
signature)) {
|
||||
@ -31,8 +31,8 @@ public class HSQLDBGroupBanTransactionRepository extends HSQLDBTransactionReposi
|
||||
byte[] adminReference = resultSet.getBytes(6);
|
||||
byte[] joinInviteReference = resultSet.getBytes(7);
|
||||
|
||||
return new GroupBanTransactionData(creatorPublicKey, groupId, offender, reason, timeToLive, memberReference, adminReference, joinInviteReference,
|
||||
fee, timestamp, reference, signature);
|
||||
return new GroupBanTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, offender, reason, timeToLive,
|
||||
memberReference, adminReference, joinInviteReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch group ban transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBGroupInviteTransactionRepository extends HSQLDBTransactionRep
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT group_id, invitee, time_to_live, join_reference FROM GroupInviteTransactions WHERE signature = ?", signature)) {
|
||||
if (resultSet == null)
|
||||
@ -27,7 +27,7 @@ public class HSQLDBGroupInviteTransactionRepository extends HSQLDBTransactionRep
|
||||
int timeToLive = resultSet.getInt(3);
|
||||
byte[] joinReference = resultSet.getBytes(4);
|
||||
|
||||
return new GroupInviteTransactionData(creatorPublicKey, groupId, invitee, timeToLive, joinReference, fee, timestamp, reference, signature);
|
||||
return new GroupInviteTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, invitee, timeToLive, joinReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch group invite transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBGroupKickTransactionRepository extends HSQLDBTransactionRepos
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(
|
||||
"SELECT group_id, address, reason, member_reference, admin_reference, join_reference FROM GroupKickTransactions WHERE signature = ?",
|
||||
signature)) {
|
||||
@ -30,8 +30,8 @@ public class HSQLDBGroupKickTransactionRepository extends HSQLDBTransactionRepos
|
||||
byte[] adminReference = resultSet.getBytes(5);
|
||||
byte[] joinReference = resultSet.getBytes(6);
|
||||
|
||||
return new GroupKickTransactionData(creatorPublicKey, groupId, member, reason, memberReference, adminReference, joinReference, fee, timestamp,
|
||||
reference, signature);
|
||||
return new GroupKickTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, member, reason, memberReference, adminReference,
|
||||
joinReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch group kick transaction from repository", e);
|
||||
}
|
||||
|
@ -16,26 +16,25 @@ public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepo
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(
|
||||
"SELECT issuer, owner, asset_name, description, quantity, is_divisible, asset_id FROM IssueAssetTransactions WHERE signature = ?", signature)) {
|
||||
"SELECT owner, asset_name, description, quantity, is_divisible, asset_id FROM IssueAssetTransactions WHERE signature = ?", signature)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
byte[] issuerPublicKey = resultSet.getBytes(1);
|
||||
String owner = resultSet.getString(2);
|
||||
String assetName = resultSet.getString(3);
|
||||
String description = resultSet.getString(4);
|
||||
long quantity = resultSet.getLong(5);
|
||||
boolean isDivisible = resultSet.getBoolean(6);
|
||||
String owner = resultSet.getString(1);
|
||||
String assetName = resultSet.getString(2);
|
||||
String description = resultSet.getString(3);
|
||||
long quantity = resultSet.getLong(4);
|
||||
boolean isDivisible = resultSet.getBoolean(5);
|
||||
|
||||
// Special null-checking for asset ID
|
||||
Long assetId = resultSet.getLong(7);
|
||||
Long assetId = resultSet.getLong(6);
|
||||
if (resultSet.wasNull())
|
||||
assetId = null;
|
||||
|
||||
return new IssueAssetTransactionData(assetId, issuerPublicKey, owner, assetName, description, quantity, isDivisible, fee, timestamp, reference,
|
||||
signature);
|
||||
return new IssueAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, assetId, owner, assetName, description, quantity, isDivisible,
|
||||
fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch issue asset transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBJoinGroupTransactionRepository extends HSQLDBTransactionRepos
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT group_id, invite_reference FROM JoinGroupTransactions WHERE signature = ?",
|
||||
signature)) {
|
||||
if (resultSet == null)
|
||||
@ -25,7 +25,7 @@ public class HSQLDBJoinGroupTransactionRepository extends HSQLDBTransactionRepos
|
||||
int groupId = resultSet.getInt(1);
|
||||
byte[] inviteReference = resultSet.getBytes(2);
|
||||
|
||||
return new JoinGroupTransactionData(creatorPublicKey, groupId, inviteReference, fee, timestamp, reference, signature);
|
||||
return new JoinGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, inviteReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch join group transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBLeaveGroupTransactionRepository extends HSQLDBTransactionRepo
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT group_id, member_reference, admin_reference FROM LeaveGroupTransactions WHERE signature = ?", signature)) {
|
||||
if (resultSet == null)
|
||||
@ -26,7 +26,7 @@ public class HSQLDBLeaveGroupTransactionRepository extends HSQLDBTransactionRepo
|
||||
byte[] memberReference = resultSet.getBytes(2);
|
||||
byte[] adminReference = resultSet.getBytes(3);
|
||||
|
||||
return new LeaveGroupTransactionData(creatorPublicKey, groupId, memberReference, adminReference, fee, timestamp, reference, signature);
|
||||
return new LeaveGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, memberReference, adminReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch leave group transaction from repository", e);
|
||||
}
|
||||
|
@ -16,28 +16,27 @@ public class HSQLDBMessageTransactionRepository extends HSQLDBTransactionReposit
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(
|
||||
"SELECT version, sender, recipient, is_text, is_encrypted, amount, asset_id, data FROM MessageTransactions WHERE signature = ?", signature)) {
|
||||
"SELECT version, recipient, is_text, is_encrypted, amount, asset_id, data FROM MessageTransactions WHERE signature = ?", signature)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
int version = resultSet.getInt(1);
|
||||
byte[] senderPublicKey = resultSet.getBytes(2);
|
||||
String recipient = resultSet.getString(3);
|
||||
boolean isText = resultSet.getBoolean(4);
|
||||
boolean isEncrypted = resultSet.getBoolean(5);
|
||||
BigDecimal amount = resultSet.getBigDecimal(6);
|
||||
String recipient = resultSet.getString(2);
|
||||
boolean isText = resultSet.getBoolean(3);
|
||||
boolean isEncrypted = resultSet.getBoolean(4);
|
||||
BigDecimal amount = resultSet.getBigDecimal(5);
|
||||
|
||||
// Special null-checking for asset ID
|
||||
Long assetId = resultSet.getLong(7);
|
||||
Long assetId = resultSet.getLong(6);
|
||||
if (resultSet.wasNull())
|
||||
assetId = null;
|
||||
|
||||
byte[] data = resultSet.getBytes(8);
|
||||
byte[] data = resultSet.getBytes(7);
|
||||
|
||||
return new MessageTransactionData(version, senderPublicKey, recipient, assetId, amount, data, isText, isEncrypted, fee, timestamp, reference,
|
||||
signature);
|
||||
return new MessageTransactionData(timestamp, txGroupId, reference, creatorPublicKey, version, recipient, assetId, amount, data, isText, isEncrypted,
|
||||
fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch message transaction from repository", e);
|
||||
}
|
||||
|
@ -18,16 +18,14 @@ public class HSQLDBMultiPaymentTransactionRepository extends HSQLDBTransactionRe
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT sender from MultiPaymentTransactions WHERE signature = ?", signature)) {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT TRUE from MultiPaymentTransactions WHERE signature = ?", signature)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
byte[] senderPublicKey = resultSet.getBytes(1);
|
||||
|
||||
List<PaymentData> payments = this.getPaymentsFromSignature(signature);
|
||||
|
||||
return new MultiPaymentTransactionData(senderPublicKey, payments, fee, timestamp, reference, signature);
|
||||
return new MultiPaymentTransactionData(timestamp, txGroupId, reference, creatorPublicKey, payments, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch multi-payment transaction from repository", e);
|
||||
}
|
||||
|
@ -16,16 +16,15 @@ public class HSQLDBPaymentTransactionRepository extends HSQLDBTransactionReposit
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT sender, recipient, amount FROM PaymentTransactions WHERE signature = ?", signature)) {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT recipient, amount FROM PaymentTransactions WHERE signature = ?", signature)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
byte[] senderPublicKey = resultSet.getBytes(1);
|
||||
String recipient = resultSet.getString(2);
|
||||
BigDecimal amount = resultSet.getBigDecimal(3);
|
||||
String recipient = resultSet.getString(1);
|
||||
BigDecimal amount = resultSet.getBigDecimal(2);
|
||||
|
||||
return new PaymentTransactionData(senderPublicKey, recipient, amount, fee, timestamp, reference, signature);
|
||||
return new PaymentTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch payment transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBRegisterNameTransactionRepository extends HSQLDBTransactionRe
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] registrantPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +25,7 @@ public class HSQLDBRegisterNameTransactionRepository extends HSQLDBTransactionRe
|
||||
String name = resultSet.getString(2);
|
||||
String data = resultSet.getString(3);
|
||||
|
||||
return new RegisterNameTransactionData(registrantPublicKey, owner, name, data, fee, timestamp, reference, signature);
|
||||
return new RegisterNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, owner, name, data, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch register name transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBRemoveGroupAdminTransactionRepository extends HSQLDBTransacti
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +26,7 @@ public class HSQLDBRemoveGroupAdminTransactionRepository extends HSQLDBTransacti
|
||||
String admin = resultSet.getString(2);
|
||||
byte[] adminReference = resultSet.getBytes(3);
|
||||
|
||||
return new RemoveGroupAdminTransactionData(creatorPublicKey, groupId, admin, adminReference, fee, timestamp, reference, signature);
|
||||
return new RemoveGroupAdminTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, admin, adminReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch remove group admin transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBSellNameTransactionRepository extends HSQLDBTransactionReposi
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] ownerPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +24,7 @@ public class HSQLDBSellNameTransactionRepository extends HSQLDBTransactionReposi
|
||||
String name = resultSet.getString(1);
|
||||
BigDecimal amount = resultSet.getBigDecimal(2);
|
||||
|
||||
return new SellNameTransactionData(ownerPublicKey, name, amount, fee, timestamp, reference, signature);
|
||||
return new SellNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, name, amount, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch sell name transaction from repository", e);
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
package org.qora.repository.hsqldb.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.qora.data.transaction.SetGroupTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.hsqldb.HSQLDBRepository;
|
||||
import org.qora.repository.hsqldb.HSQLDBSaver;
|
||||
|
||||
public class HSQLDBSetGroupTransactionRepository extends HSQLDBTransactionRepository {
|
||||
|
||||
public HSQLDBSetGroupTransactionRepository(HSQLDBRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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)
|
||||
return null;
|
||||
|
||||
int defaultGroupId = resultSet.getInt(1);
|
||||
Integer previousDefaultGroupId = resultSet.getInt(2);
|
||||
if (resultSet.wasNull())
|
||||
previousDefaultGroupId = null;
|
||||
|
||||
return new SetGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, defaultGroupId, previousDefaultGroupId, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch set group transaction from repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(TransactionData transactionData) throws DataException {
|
||||
SetGroupTransactionData setGroupTransactionData = (SetGroupTransactionData) transactionData;
|
||||
|
||||
HSQLDBSaver saveHelper = new HSQLDBSaver("SetGroupTransactions");
|
||||
|
||||
saveHelper.bind("signature", setGroupTransactionData.getSignature()).bind("default_group_id", setGroupTransactionData.getDefaultGroupId())
|
||||
.bind("previous_default_group_id", setGroupTransactionData.getPreviousDefaultGroupId());
|
||||
|
||||
try {
|
||||
saveHelper.execute(this.repository);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to save set group transaction into repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -17,6 +17,7 @@ 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.transaction.GroupApprovalTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.TransactionRepository;
|
||||
@ -60,8 +61,8 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
}
|
||||
|
||||
try {
|
||||
subclassInfo.fromBaseMethod = subclassInfo.clazz.getDeclaredMethod("fromBase", byte[].class, byte[].class, byte[].class, long.class,
|
||||
BigDecimal.class);
|
||||
// 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);
|
||||
} catch (IllegalArgumentException | SecurityException | NoSuchMethodException e) {
|
||||
LOGGER.debug(String.format("HSQLDBTransactionRepository subclass's \"fromBase\" method not found for transaction type \"%s\"", txType.name()));
|
||||
}
|
||||
@ -110,7 +111,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 FROM Transactions WHERE signature = ?",
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT type, reference, creator, creation, fee, tx_group_id FROM Transactions WHERE signature = ?",
|
||||
signature)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
@ -120,8 +121,9 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
byte[] creatorPublicKey = resultSet.getBytes(3);
|
||||
long timestamp = resultSet.getTimestamp(4, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
|
||||
BigDecimal fee = resultSet.getBigDecimal(5).setScale(8);
|
||||
int txGroupId = resultSet.getInt(6);
|
||||
|
||||
TransactionData transactionData = this.fromBase(type, signature, reference, creatorPublicKey, timestamp, fee);
|
||||
TransactionData transactionData = this.fromBase(type, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
|
||||
return maybeIncludeBlockHeight(transactionData);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch transaction from repository", e);
|
||||
@ -130,7 +132,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 FROM Transactions WHERE reference = ?",
|
||||
try (ResultSet resultSet = this.repository.checkedExecute("SELECT type, signature, creator, creation, fee, tx_group_id FROM Transactions WHERE reference = ?",
|
||||
reference)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
@ -140,8 +142,9 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
byte[] creatorPublicKey = resultSet.getBytes(3);
|
||||
long timestamp = resultSet.getTimestamp(4, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
|
||||
BigDecimal fee = resultSet.getBigDecimal(5).setScale(8);
|
||||
int txGroupId = resultSet.getInt(6);
|
||||
|
||||
TransactionData transactionData = this.fromBase(type, signature, reference, creatorPublicKey, timestamp, fee);
|
||||
TransactionData transactionData = this.fromBase(type, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
|
||||
return maybeIncludeBlockHeight(transactionData);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch transaction from repository", e);
|
||||
@ -172,14 +175,15 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private TransactionData fromBase(TransactionType type, byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee)
|
||||
private TransactionData fromBase(TransactionType type, long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 {
|
||||
return (TransactionData) subclassInfos[type.value].fromBaseMethod.invoke(txRepository, signature, reference, creatorPublicKey, timestamp, fee);
|
||||
// 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);
|
||||
} catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
|
||||
throw new DataException("Unsupported transaction type [" + type.name() + "] during fetch from HSQLDB repository");
|
||||
}
|
||||
@ -484,6 +488,77 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
// 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";
|
||||
|
||||
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<GroupApprovalTransactionData> 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<GroupApprovalTransactionData> approvals = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, bindArgs)) {
|
||||
if (resultSet == null)
|
||||
return approvals;
|
||||
|
||||
do {
|
||||
byte[] signature = resultSet.getBytes(1);
|
||||
|
||||
approvals.add((GroupApprovalTransactionData) this.fromSignature(signature));
|
||||
} while (resultSet.next());
|
||||
|
||||
return approvals;
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch latest transaction group-admin approvals from repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfirmed(byte[] signature) throws DataException {
|
||||
try {
|
||||
@ -553,7 +628,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
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("fee", transactionData.getFee()).bind("milestone_block", null).bind("tx_group_id", transactionData.getTxGroupId());
|
||||
try {
|
||||
saver.execute(this.repository);
|
||||
} catch (SQLException e) {
|
||||
|
@ -16,18 +16,17 @@ public class HSQLDBTransferAssetTransactionRepository extends HSQLDBTransactionR
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT sender, recipient, asset_id, amount FROM TransferAssetTransactions WHERE signature = ?", signature)) {
|
||||
.checkedExecute("SELECT recipient, asset_id, amount FROM TransferAssetTransactions WHERE signature = ?", signature)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
byte[] senderPublicKey = resultSet.getBytes(1);
|
||||
String recipient = resultSet.getString(2);
|
||||
long assetId = resultSet.getLong(3);
|
||||
BigDecimal amount = resultSet.getBigDecimal(4);
|
||||
String recipient = resultSet.getString(1);
|
||||
long assetId = resultSet.getLong(2);
|
||||
BigDecimal amount = resultSet.getBigDecimal(3);
|
||||
|
||||
return new TransferAssetTransactionData(senderPublicKey, recipient, amount, assetId, fee, timestamp, reference, signature);
|
||||
return new TransferAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, assetId, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch transfer asset transaction from repository", e);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.qora.data.transaction.UpdateGroupTransactionData;
|
||||
import org.qora.group.Group.ApprovalThreshold;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.hsqldb.HSQLDBRepository;
|
||||
@ -16,9 +17,10 @@ public class HSQLDBUpdateGroupTransactionRepository extends HSQLDBTransactionRep
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(
|
||||
"SELECT group_id, new_owner, new_description, new_is_open, group_reference FROM UpdateGroupTransactions WHERE signature = ?", signature)) {
|
||||
"SELECT group_id, new_owner, new_description, new_is_open, new_approval_threshold, group_reference FROM UpdateGroupTransactions WHERE signature = ?",
|
||||
signature)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
@ -26,10 +28,11 @@ public class HSQLDBUpdateGroupTransactionRepository extends HSQLDBTransactionRep
|
||||
String newOwner = resultSet.getString(2);
|
||||
String newDescription = resultSet.getString(3);
|
||||
boolean newIsOpen = resultSet.getBoolean(4);
|
||||
byte[] groupReference = resultSet.getBytes(5);
|
||||
ApprovalThreshold newApprovalThreshold = ApprovalThreshold.valueOf(resultSet.getInt(5));
|
||||
byte[] groupReference = resultSet.getBytes(6);
|
||||
|
||||
return new UpdateGroupTransactionData(creatorPublicKey, groupId, newOwner, newDescription, newIsOpen, groupReference, fee, timestamp, reference,
|
||||
signature);
|
||||
return new UpdateGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, newOwner, newDescription, newIsOpen,
|
||||
newApprovalThreshold, groupReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch update group transaction from repository", e);
|
||||
}
|
||||
@ -44,6 +47,7 @@ public class HSQLDBUpdateGroupTransactionRepository extends HSQLDBTransactionRep
|
||||
saveHelper.bind("signature", updateGroupTransactionData.getSignature()).bind("owner", updateGroupTransactionData.getOwnerPublicKey())
|
||||
.bind("group_id", updateGroupTransactionData.getGroupId()).bind("new_owner", updateGroupTransactionData.getNewOwner())
|
||||
.bind("new_description", updateGroupTransactionData.getNewDescription()).bind("new_is_open", updateGroupTransactionData.getNewIsOpen())
|
||||
.bind("new_approval_threshold", updateGroupTransactionData.getNewApprovalThreshold().value)
|
||||
.bind("group_reference", updateGroupTransactionData.getGroupReference());
|
||||
|
||||
try {
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBUpdateNameTransactionRepository extends HSQLDBTransactionRepo
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] ownerPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +27,7 @@ public class HSQLDBUpdateNameTransactionRepository extends HSQLDBTransactionRepo
|
||||
String newData = resultSet.getString(3);
|
||||
byte[] nameReference = resultSet.getBytes(4);
|
||||
|
||||
return new UpdateNameTransactionData(ownerPublicKey, newOwner, name, newData, nameReference, fee, timestamp, reference, signature);
|
||||
return new UpdateNameTransactionData(timestamp, txGroupId, reference, creatorPublicKey, newOwner, name, newData, nameReference, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch update name transaction from repository", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class HSQLDBVoteOnPollTransactionRepository extends HSQLDBTransactionRepo
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
TransactionData fromBase(byte[] signature, byte[] reference, byte[] creatorPublicKey, long timestamp, BigDecimal fee) throws DataException {
|
||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, 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 +30,7 @@ public class HSQLDBVoteOnPollTransactionRepository extends HSQLDBTransactionRepo
|
||||
if (resultSet.wasNull())
|
||||
previousOptionIndex = null;
|
||||
|
||||
return new VoteOnPollTransactionData(creatorPublicKey, pollName, optionIndex, previousOptionIndex, fee, timestamp, reference, signature);
|
||||
return new VoteOnPollTransactionData(timestamp, txGroupId, reference, creatorPublicKey, pollName, optionIndex, previousOptionIndex, fee, signature);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch vote on poll transaction from repository", e);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class Settings {
|
||||
private static Settings instance;
|
||||
private String userpath = "";
|
||||
private boolean useBitcoinTestNet = false;
|
||||
private boolean wipeUnconfirmedOnStart = true;
|
||||
private boolean wipeUnconfirmedOnStart = false;
|
||||
private String blockchainConfigPath = "blockchain.json";
|
||||
/** Maximum number of unconfirmed transactions allowed per account */
|
||||
private int maxUnconfirmedPerAccount = 100;
|
||||
|
@ -84,6 +84,10 @@ public class AddGroupAdminTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != addGroupAdminTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account owner = getOwner();
|
||||
|
||||
// Check transaction's public key matches group's current owner
|
||||
|
@ -19,7 +19,7 @@ import org.qora.transform.transaction.AtTransactionTransformer;
|
||||
|
||||
import com.google.common.primitives.Bytes;
|
||||
|
||||
public class ATTransaction extends Transaction {
|
||||
public class AtTransaction extends Transaction {
|
||||
|
||||
// Properties
|
||||
private ATTransactionData atTransactionData;
|
||||
@ -29,7 +29,7 @@ public class ATTransaction extends Transaction {
|
||||
|
||||
// Constructors
|
||||
|
||||
public ATTransaction(Repository repository, TransactionData transactionData) {
|
||||
public AtTransaction(Repository repository, TransactionData transactionData) {
|
||||
super(repository, transactionData);
|
||||
|
||||
this.atTransactionData = (ATTransactionData) this.transactionData;
|
@ -84,6 +84,10 @@ public class CancelGroupBanTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != groupUnbanTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Can't unban if not an admin
|
||||
|
@ -84,6 +84,10 @@ public class CancelGroupInviteTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != cancelGroupInviteTransactionData.getGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Check admin is actually an admin
|
||||
|
@ -74,6 +74,10 @@ public class CreateGroupTransaction extends Transaction {
|
||||
if (!Crypto.isValidAddress(createGroupTransactionData.getOwner()))
|
||||
return ValidationResult.INVALID_ADDRESS;
|
||||
|
||||
// Check approval threshold is valid
|
||||
if (createGroupTransactionData.getApprovalThreshold() == null)
|
||||
return ValidationResult.INVALID_GROUP_APPROVAL_THRESHOLD;
|
||||
|
||||
// Check group name size bounds
|
||||
int groupNameLength = Utf8.encodedLength(createGroupTransactionData.getGroupName());
|
||||
if (groupNameLength < 1 || groupNameLength > Group.MAX_NAME_SIZE)
|
||||
|
@ -86,7 +86,7 @@ public class DeployAtTransaction extends Transaction {
|
||||
|
||||
/** Make sure deployATTransactionData has an ATAddress */
|
||||
private void ensureATAddress() throws DataException {
|
||||
if (this.deployATTransactionData.getATAddress() != null)
|
||||
if (this.deployATTransactionData.getAtAddress() != null)
|
||||
return;
|
||||
|
||||
int blockHeight = this.getHeight();
|
||||
@ -112,7 +112,7 @@ public class DeployAtTransaction extends Transaction {
|
||||
|
||||
String atAddress = Crypto.toATAddress(byteBuffer.array());
|
||||
|
||||
this.deployATTransactionData.setATAddress(atAddress);
|
||||
this.deployATTransactionData.setAtAddress(atAddress);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new DataException("Unable to generate AT account from Deploy AT transaction data", e);
|
||||
}
|
||||
@ -123,7 +123,7 @@ public class DeployAtTransaction extends Transaction {
|
||||
public Account getATAccount() throws DataException {
|
||||
ensureATAddress();
|
||||
|
||||
return new Account(this.repository, this.deployATTransactionData.getATAddress());
|
||||
return new Account(this.repository, this.deployATTransactionData.getAtAddress());
|
||||
}
|
||||
|
||||
// Processing
|
||||
@ -144,7 +144,7 @@ public class DeployAtTransaction extends Transaction {
|
||||
return ValidationResult.INVALID_DESCRIPTION_LENGTH;
|
||||
|
||||
// Check AT-type size bounds
|
||||
int ATTypeLength = Utf8.encodedLength(deployATTransactionData.getATType());
|
||||
int ATTypeLength = Utf8.encodedLength(deployATTransactionData.getAtType());
|
||||
if (ATTypeLength < 1 || ATTypeLength > MAX_AT_TYPE_SIZE)
|
||||
return ValidationResult.INVALID_AT_TYPE_LENGTH;
|
||||
|
||||
@ -257,7 +257,7 @@ public class DeployAtTransaction extends Transaction {
|
||||
creator.setLastReference(deployATTransactionData.getReference());
|
||||
|
||||
// Delete AT's account (and hence its balance)
|
||||
this.repository.getAccountRepository().delete(this.deployATTransactionData.getATAddress());
|
||||
this.repository.getAccountRepository().delete(this.deployATTransactionData.getAtAddress());
|
||||
}
|
||||
|
||||
}
|
||||
|
136
src/main/java/org/qora/transaction/GroupApprovalTransaction.java
Normal file
136
src/main/java/org/qora/transaction/GroupApprovalTransaction.java
Normal file
@ -0,0 +1,136 @@
|
||||
package org.qora.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.qora.account.Account;
|
||||
import org.qora.account.PublicKeyAccount;
|
||||
import org.qora.asset.Asset;
|
||||
import org.qora.data.transaction.GroupApprovalTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
|
||||
public class GroupApprovalTransaction extends Transaction {
|
||||
|
||||
// Properties
|
||||
private GroupApprovalTransactionData groupApprovalTransactionData;
|
||||
|
||||
// Constructors
|
||||
|
||||
public GroupApprovalTransaction(Repository repository, TransactionData transactionData) {
|
||||
super(repository, transactionData);
|
||||
|
||||
this.groupApprovalTransactionData = (GroupApprovalTransactionData) this.transactionData;
|
||||
}
|
||||
|
||||
// More information
|
||||
|
||||
@Override
|
||||
public List<Account> getRecipientAccounts() throws DataException {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvolved(Account account) throws DataException {
|
||||
String address = account.getAddress();
|
||||
|
||||
if (address.equals(this.getAdmin().getAddress()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getAmount(Account account) throws DataException {
|
||||
String address = account.getAddress();
|
||||
BigDecimal amount = BigDecimal.ZERO.setScale(8);
|
||||
|
||||
if (address.equals(this.getAdmin().getAddress()))
|
||||
amount = amount.subtract(this.transactionData.getFee());
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// Navigation
|
||||
|
||||
public Account getAdmin() throws DataException {
|
||||
return new PublicKeyAccount(this.repository, this.groupApprovalTransactionData.getAdminPublicKey());
|
||||
}
|
||||
|
||||
// Processing
|
||||
|
||||
@Override
|
||||
public ValidationResult isValid() throws DataException {
|
||||
// Grab pending transaction's data
|
||||
TransactionData pendingTransactionData = this.repository.getTransactionRepository().fromSignature(groupApprovalTransactionData.getPendingSignature());
|
||||
if (pendingTransactionData == null)
|
||||
return ValidationResult.TRANSACTION_UNKNOWN;
|
||||
|
||||
// Check pending transaction is not already in a block
|
||||
if (this.repository.getTransactionRepository().getHeightFromSignature(groupApprovalTransactionData.getPendingSignature()) != 0)
|
||||
return ValidationResult.TRANSACTION_ALREADY_CONFIRMED;
|
||||
|
||||
// Check pending transaction's groupID matches our transaction's groupID
|
||||
int effectiveTxGroupId = this.getEffectiveGroupId();
|
||||
if (effectiveTxGroupId != pendingTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Can't cast approval decision if not an admin
|
||||
if (!this.repository.getGroupRepository().adminExists(groupApprovalTransactionData.getTxGroupId(), admin.getAddress()))
|
||||
return ValidationResult.NOT_GROUP_ADMIN;
|
||||
|
||||
// Check fee is positive
|
||||
if (groupApprovalTransactionData.getFee().compareTo(BigDecimal.ZERO) <= 0)
|
||||
return ValidationResult.NEGATIVE_FEE;
|
||||
|
||||
// Check reference
|
||||
if (!Arrays.equals(admin.getLastReference(), groupApprovalTransactionData.getReference()))
|
||||
return ValidationResult.INVALID_REFERENCE;
|
||||
|
||||
// Check creator has enough funds
|
||||
if (admin.getConfirmedBalance(Asset.QORA).compareTo(groupApprovalTransactionData.getFee()) < 0)
|
||||
return ValidationResult.NO_BALANCE;
|
||||
|
||||
return ValidationResult.OK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process() throws DataException {
|
||||
// Find previous approval decision (if any) by this admin for pending transaction
|
||||
List<GroupApprovalTransactionData> approvals = this.repository.getTransactionRepository().getLatestApprovals(groupApprovalTransactionData.getPendingSignature(), groupApprovalTransactionData.getAdminPublicKey());
|
||||
|
||||
if (!approvals.isEmpty())
|
||||
groupApprovalTransactionData.setPriorReference(approvals.get(0).getSignature());
|
||||
|
||||
// Save this transaction with updated prior reference to transaction that can help restore state
|
||||
this.repository.getTransactionRepository().save(groupApprovalTransactionData);
|
||||
|
||||
// Update admin's balance
|
||||
Account admin = getAdmin();
|
||||
admin.setConfirmedBalance(Asset.QORA, admin.getConfirmedBalance(Asset.QORA).subtract(groupApprovalTransactionData.getFee()));
|
||||
|
||||
// Update admin's reference
|
||||
admin.setLastReference(groupApprovalTransactionData.getSignature());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void orphan() throws DataException {
|
||||
// Revert?
|
||||
|
||||
// Delete this transaction itself
|
||||
this.repository.getTransactionRepository().delete(groupApprovalTransactionData);
|
||||
|
||||
// Update admin's balance
|
||||
Account admin = getAdmin();
|
||||
admin.setConfirmedBalance(Asset.QORA, admin.getConfirmedBalance(Asset.QORA).add(groupApprovalTransactionData.getFee()));
|
||||
|
||||
// Update admin's reference
|
||||
admin.setLastReference(groupApprovalTransactionData.getReference());
|
||||
}
|
||||
|
||||
}
|
@ -84,6 +84,10 @@ public class GroupBanTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != groupBanTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Can't ban if not an admin
|
||||
|
@ -88,6 +88,11 @@ public class GroupInviteTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
int effectiveTxGroupId = this.getEffectiveGroupId();
|
||||
if (effectiveTxGroupId != groupInviteTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Can't invite if not an admin
|
||||
|
@ -87,6 +87,10 @@ public class GroupKickTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != groupKickTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Can't kick if not an admin
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user