diff --git a/src/main/java/org/qora/account/Account.java b/src/main/java/org/qora/account/Account.java index 28e8b2b1..17c0cf37 100644 --- a/src/main/java/org/qora/account/Account.java +++ b/src/main/java/org/qora/account/Account.java @@ -233,4 +233,11 @@ public class Account { this.repository.getAccountRepository().setLevel(accountData); } + public void setInitialLevel(int level) throws DataException { + AccountData accountData = this.buildAccountData(); + accountData.setLevel(level); + accountData.setInitialLevel(level); + this.repository.getAccountRepository().setInitialLevel(accountData); + } + } diff --git a/src/main/java/org/qora/api/resource/AddressesResource.java b/src/main/java/org/qora/api/resource/AddressesResource.java index 92eb4f0b..d3783501 100644 --- a/src/main/java/org/qora/api/resource/AddressesResource.java +++ b/src/main/java/org/qora/api/resource/AddressesResource.java @@ -207,7 +207,7 @@ public class AddressesResource { try (final Repository repository = RepositoryManager.getRepository()) { Account account = new Account(repository, address); - return account.getConfirmedBalance(Asset.QORA); + return account.getConfirmedBalance(Asset.QORT); } catch (ApiException e) { throw e; } catch (DataException e) { diff --git a/src/main/java/org/qora/api/resource/AssetsResource.java b/src/main/java/org/qora/api/resource/AssetsResource.java index 6e698493..6b3577bf 100644 --- a/src/main/java/org/qora/api/resource/AssetsResource.java +++ b/src/main/java/org/qora/api/resource/AssetsResource.java @@ -318,14 +318,14 @@ public class AssetsResource { ) @QueryParam("reverse") Boolean reverse) { try (final Repository repository = RepositoryManager.getRepository()) { if (assetIds.isEmpty()) - assetIds = Collections.singletonList(Asset.QORA); + assetIds = Collections.singletonList(Asset.QORT); else for (long assetId : assetIds) if (!repository.getAssetRepository().assetExists(assetId)) throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ASSET_ID); if (otherAssetIds.isEmpty()) - otherAssetIds = Collections.singletonList(Asset.QORA); + otherAssetIds = Collections.singletonList(Asset.QORT); else for (long assetId : otherAssetIds) if (!repository.getAssetRepository().assetExists(assetId)) diff --git a/src/main/java/org/qora/asset/Asset.java b/src/main/java/org/qora/asset/Asset.java index cae5fe01..5afbd122 100644 --- a/src/main/java/org/qora/asset/Asset.java +++ b/src/main/java/org/qora/asset/Asset.java @@ -10,9 +10,12 @@ import org.qora.repository.Repository; public class Asset { /** - * QORA coins are just another asset but with fixed assetId of zero. + * QORT coins are just another asset but with fixed assetId of zero. */ - public static final long QORA = 0L; + public static final long QORT = 0L; + + /** Hard-coded asset representing legacy QORA held in old QORA1 blockchain. */ + public static final long LEGACY_QORA = 1L; // Other useful constants @@ -41,6 +44,7 @@ public class Asset { this.assetData = new AssetData(issueAssetTransactionData.getOwner(), issueAssetTransactionData.getAssetName(), issueAssetTransactionData.getDescription(), issueAssetTransactionData.getQuantity(), issueAssetTransactionData.getIsDivisible(), issueAssetTransactionData.getData(), + issueAssetTransactionData.getIsUnspendable(), issueAssetTransactionData.getTxGroupId(), issueAssetTransactionData.getSignature()); } diff --git a/src/main/java/org/qora/at/AT.java b/src/main/java/org/qora/at/AT.java index e8ec2425..2051f215 100644 --- a/src/main/java/org/qora/at/AT.java +++ b/src/main/java/org/qora/at/AT.java @@ -97,7 +97,7 @@ public class AT { boolean isFrozen = false; Long frozenBalance = null; - this.atData = new ATData(atAddress, creatorPublicKey, creation, version, Asset.QORA, codeBytes, isSleeping, sleepUntilHeight, isFinished, + this.atData = new ATData(atAddress, creatorPublicKey, creation, version, Asset.QORT, codeBytes, isSleeping, sleepUntilHeight, isFinished, hadFatalError, isFrozen, frozenBalance); this.atStateData = new ATStateData(atAddress, height, creation, null, null, BigDecimal.ZERO.setScale(8)); diff --git a/src/main/java/org/qora/at/QoraATAPI.java b/src/main/java/org/qora/at/QoraATAPI.java index f0cdd69f..dd923083 100644 --- a/src/main/java/org/qora/at/QoraATAPI.java +++ b/src/main/java/org/qora/at/QoraATAPI.java @@ -254,7 +254,7 @@ public class QoraATAPI extends API { try { Account atAccount = this.getATAccount(); - return atAccount.getConfirmedBalance(Asset.QORA).unscaledValue().longValue(); + return atAccount.getConfirmedBalance(Asset.QORT).unscaledValue().longValue(); } catch (DataException e) { throw new RuntimeException("AT API unable to fetch AT's current balance?", e); } diff --git a/src/main/java/org/qora/block/Block.java b/src/main/java/org/qora/block/Block.java index 852818b9..0e01bb2d 100644 --- a/src/main/java/org/qora/block/Block.java +++ b/src/main/java/org/qora/block/Block.java @@ -26,6 +26,7 @@ import org.qora.block.BlockChain.BlockTimingByHeight; import org.qora.block.BlockChain.ShareByLevel; import org.qora.controller.Controller; import org.qora.crypto.Crypto; +import org.qora.data.account.AccountBalanceData; import org.qora.data.account.ProxyForgerData; import org.qora.data.at.ATData; import org.qora.data.at.ATStateData; @@ -1193,7 +1194,7 @@ public class Block { Account atAccount = new Account(this.repository, atState.getATAddress()); // Subtract AT-generated fees from AT accounts - atAccount.setConfirmedBalance(Asset.QORA, atAccount.getConfirmedBalance(Asset.QORA).subtract(atState.getFees())); + atAccount.setConfirmedBalance(Asset.QORT, atAccount.getConfirmedBalance(Asset.QORT).subtract(atState.getFees())); atRepository.save(atState); } @@ -1341,7 +1342,7 @@ public class Block { Account atAccount = new Account(this.repository, atState.getATAddress()); // Return AT-generated fees to AT accounts - atAccount.setConfirmedBalance(Asset.QORA, atAccount.getConfirmedBalance(Asset.QORA).add(atState.getFees())); + atAccount.setConfirmedBalance(Asset.QORT, atAccount.getConfirmedBalance(Asset.QORT).add(atState.getFees())); } // Delete ATStateData for this height @@ -1359,6 +1360,7 @@ public class Block { final boolean isFounder; final int level; final int shareBin; + final BigDecimal qoraAmount; final Account recipientAccount; AccountInfo(Repository repository, int accountIndex, List sharesByLevel) throws DataException { @@ -1367,6 +1369,12 @@ public class Block { this.forgerAccount = new PublicKeyAccount(repository, this.proxyForgerData.getForgerPublicKey()); this.recipientAccount = new Account(repository, this.proxyForgerData.getRecipient()); + AccountBalanceData qoraBalanceData = repository.getAccountRepository().getBalance(this.forgerAccount.getAddress(), Asset.LEGACY_QORA); + if (qoraBalanceData != null && qoraBalanceData.getBalance() != null && qoraBalanceData.getBalance().compareTo(BigDecimal.ZERO) > 0) + this.qoraAmount = qoraBalanceData.getBalance(); + else + this.qoraAmount = null; + if (this.forgerAccount.isFounder()) { this.isFounder = true; this.level = 0; @@ -1395,17 +1403,17 @@ public class Block { if (forgerAccount.getAddress().equals(recipientAccount.getAddress())) { // forger & recipient the same - simpler case LOGGER.trace(() -> String.format("Forger/recipient account %s share: %s", forgerAccount.getAddress(), accountAmount.toPlainString())); - forgerAccount.setConfirmedBalance(Asset.QORA, forgerAccount.getConfirmedBalance(Asset.QORA).add(accountAmount)); + forgerAccount.setConfirmedBalance(Asset.QORT, forgerAccount.getConfirmedBalance(Asset.QORT).add(accountAmount)); } else { // forger & recipient different - extra work needed BigDecimal recipientAmount = accountAmount.multiply(this.proxyForgerData.getShare()).divide(ONE_HUNDRED, RoundingMode.DOWN); BigDecimal forgerAmount = accountAmount.subtract(recipientAmount); LOGGER.trace(() -> String.format("Forger account %s share: %s", forgerAccount.getAddress(), forgerAmount.toPlainString())); - forgerAccount.setConfirmedBalance(Asset.QORA, forgerAccount.getConfirmedBalance(Asset.QORA).add(forgerAmount)); + forgerAccount.setConfirmedBalance(Asset.QORT, forgerAccount.getConfirmedBalance(Asset.QORT).add(forgerAmount)); LOGGER.trace(() -> String.format("Recipient account %s share: %s", recipientAccount.getAddress(), recipientAmount.toPlainString())); - recipientAccount.setConfirmedBalance(Asset.QORA, recipientAccount.getConfirmedBalance(Asset.QORA).add(recipientAmount)); + recipientAccount.setConfirmedBalance(Asset.QORT, recipientAccount.getConfirmedBalance(Asset.QORT).add(recipientAmount)); } } } @@ -1445,6 +1453,34 @@ public class Block { } } + // Distribute share across legacy QORA holders + BigDecimal qoraHoldersAmount = BlockChain.getInstance().getQoraHoldersShare().multiply(totalAmount).setScale(8, RoundingMode.DOWN); + LOGGER.trace(() -> String.format("Legacy QORA holders share of %s: %s", totalAmount.toPlainString(), qoraHoldersAmount.toPlainString())); + + List qoraHolderAccounts = new ArrayList<>(); + BigDecimal totalQoraHeld = BigDecimal.ZERO; + for (int i = 0; i < expandedAccounts.size(); ++i) { + AccountInfo accountInfo = expandedAccounts.get(i); + if (accountInfo.qoraAmount == null) + continue; + + qoraHolderAccounts.add(accountInfo); + totalQoraHeld = totalQoraHeld.add(accountInfo.qoraAmount); + } + + final BigDecimal finalTotalQoraHeld = totalQoraHeld; + LOGGER.trace(() -> String.format("Total legacy QORA held: %s", finalTotalQoraHeld.toPlainString())); + + for (int h = 0; h < qoraHolderAccounts.size(); ++h) { + AccountInfo accountInfo = qoraHolderAccounts.get(h); + final BigDecimal holderAmount = qoraHoldersAmount.multiply(totalQoraHeld).divide(accountInfo.qoraAmount, RoundingMode.DOWN); + LOGGER.trace(() -> String.format("Forger account %s has %s / %s QORA so share: %s", + accountInfo.forgerAccount.getAddress(), accountInfo.qoraAmount, finalTotalQoraHeld, holderAmount.toPlainString())); + + accountInfo.distribute(holderAmount); + sharedAmount = sharedAmount.add(holderAmount); + } + // Spread remainder across founder accounts BigDecimal foundersAmount = totalAmount.subtract(sharedAmount); LOGGER.debug(String.format("Shared %s of %s, remaining %s to founders", sharedAmount.toPlainString(), totalAmount.toPlainString(), foundersAmount.toPlainString())); diff --git a/src/main/java/org/qora/block/BlockChain.java b/src/main/java/org/qora/block/BlockChain.java index 1d744be2..3faa3dff 100644 --- a/src/main/java/org/qora/block/BlockChain.java +++ b/src/main/java/org/qora/block/BlockChain.java @@ -106,6 +106,9 @@ public class BlockChain { } List sharesByLevel; + /** Share of block reward/fees to legacy QORA coin holders */ + BigDecimal qoraHoldersShare; + /** Block times by block height */ public static class BlockTimingByHeight { public int height; @@ -284,6 +287,10 @@ public class BlockChain { return this.sharesByLevel; } + public BigDecimal getQoraHoldersShare() { + return this.qoraHoldersShare; + } + public List getForgingTiers() { return this.forgingTiers; } @@ -368,6 +375,9 @@ public class BlockChain { if (this.sharesByLevel == null) Settings.throwValidationError("No \"sharesByLevel\" entry found in blockchain config"); + if (this.qoraHoldersShare == null) + Settings.throwValidationError("No \"qoraHoldersShare\" entry found in blockchain config"); + if (this.blockTimingsByHeight == null) Settings.throwValidationError("No \"blockTimingsByHeight\" entry found in blockchain config"); diff --git a/src/main/java/org/qora/block/GenesisBlock.java b/src/main/java/org/qora/block/GenesisBlock.java index 7a9c723a..770d8eba 100644 --- a/src/main/java/org/qora/block/GenesisBlock.java +++ b/src/main/java/org/qora/block/GenesisBlock.java @@ -118,7 +118,7 @@ public class GenesisBlock extends Block { IssueAssetTransactionData issueAssetTransactionData = (IssueAssetTransactionData) transactionData; return new AssetData(issueAssetTransactionData.getOwner(), issueAssetTransactionData.getAssetName(), issueAssetTransactionData.getDescription(), - issueAssetTransactionData.getQuantity(), issueAssetTransactionData.getIsDivisible(), "", Group.NO_GROUP, issueAssetTransactionData.getReference()); + issueAssetTransactionData.getQuantity(), issueAssetTransactionData.getIsDivisible(), "", false, Group.NO_GROUP, issueAssetTransactionData.getReference()); }).collect(Collectors.toList()); } diff --git a/src/main/java/org/qora/data/account/AccountData.java b/src/main/java/org/qora/data/account/AccountData.java index 2d21806f..fd3d89d8 100644 --- a/src/main/java/org/qora/data/account/AccountData.java +++ b/src/main/java/org/qora/data/account/AccountData.java @@ -16,6 +16,7 @@ public class AccountData { protected int defaultGroupId; protected int flags; protected String forgingEnabler; + protected int initialLevel; protected int level; // Constructors @@ -24,18 +25,19 @@ public class AccountData { protected AccountData() { } - public AccountData(String address, byte[] reference, byte[] publicKey, int defaultGroupId, int flags, String forgingEnabler, int level) { + public AccountData(String address, byte[] reference, byte[] publicKey, int defaultGroupId, int flags, String forgingEnabler, int initialLevel, int level) { this.address = address; this.reference = reference; this.publicKey = publicKey; this.defaultGroupId = defaultGroupId; this.flags = flags; this.forgingEnabler = forgingEnabler; + this.initialLevel = initialLevel; this.level = level; } public AccountData(String address) { - this(address, null, null, Group.NO_GROUP, 0, null, 0); + this(address, null, null, Group.NO_GROUP, 0, null, 0, 0); } // Getters/Setters @@ -84,6 +86,14 @@ public class AccountData { this.forgingEnabler = forgingEnabler; } + public int getInitialLevel() { + return this.initialLevel; + } + + public void setInitialLevel(int level) { + this.initialLevel = level; + } + public int getLevel() { return this.level; } diff --git a/src/main/java/org/qora/data/asset/AssetData.java b/src/main/java/org/qora/data/asset/AssetData.java index 341d8243..f38859da 100644 --- a/src/main/java/org/qora/data/asset/AssetData.java +++ b/src/main/java/org/qora/data/asset/AssetData.java @@ -18,6 +18,7 @@ public class AssetData { private long quantity; private boolean isDivisible; private String data; + private boolean isUnspendable; private int creationGroupId; // No need to expose this via API @XmlTransient @@ -31,7 +32,7 @@ public class AssetData { } // NOTE: key is Long, not long, because it can be null if asset ID/key not yet assigned. - public AssetData(Long assetId, String owner, String name, String description, long quantity, boolean isDivisible, String data, int creationGroupId, byte[] reference) { + public AssetData(Long assetId, String owner, String name, String description, long quantity, boolean isDivisible, String data, boolean isUnspendable, int creationGroupId, byte[] reference) { this.assetId = assetId; this.owner = owner; this.name = name; @@ -39,13 +40,14 @@ public class AssetData { this.quantity = quantity; this.isDivisible = isDivisible; this.data = data; + this.isUnspendable = isUnspendable; this.creationGroupId = creationGroupId; this.reference = reference; } // New asset with unassigned assetId - public AssetData(String owner, String name, String description, long quantity, boolean isDivisible, String data, int creationGroupId, byte[] reference) { - this(null, owner, name, description, quantity, isDivisible, data, creationGroupId, reference); + public AssetData(String owner, String name, String description, long quantity, boolean isDivisible, String data, boolean isUnspendable, int creationGroupId, byte[] reference) { + this(null, owner, name, description, quantity, isDivisible, data, isUnspendable, creationGroupId, reference); } // Getters/Setters @@ -94,6 +96,10 @@ public class AssetData { this.data = data; } + public boolean getIsUnspendable() { + return this.isUnspendable; + } + public int getCreationGroupId() { return this.creationGroupId; } diff --git a/src/main/java/org/qora/data/transaction/GenesisTransactionData.java b/src/main/java/org/qora/data/transaction/GenesisTransactionData.java index f938f572..83302b5e 100644 --- a/src/main/java/org/qora/data/transaction/GenesisTransactionData.java +++ b/src/main/java/org/qora/data/transaction/GenesisTransactionData.java @@ -47,7 +47,7 @@ public class GenesisTransactionData extends TransactionData { /** From repository (V1, where asset locked to QORA) */ public GenesisTransactionData(BaseTransactionData baseTransactionData, String recipient, BigDecimal amount) { - this(baseTransactionData, recipient, amount, Asset.QORA); + this(baseTransactionData, recipient, amount, Asset.QORT); } // Getters/Setters diff --git a/src/main/java/org/qora/data/transaction/IssueAssetTransactionData.java b/src/main/java/org/qora/data/transaction/IssueAssetTransactionData.java index 37bf80ba..1f6c0d94 100644 --- a/src/main/java/org/qora/data/transaction/IssueAssetTransactionData.java +++ b/src/main/java/org/qora/data/transaction/IssueAssetTransactionData.java @@ -37,6 +37,8 @@ public class IssueAssetTransactionData extends TransactionData { private boolean isDivisible; @Schema(description = "non-human-readable asset-related data, typically JSON", example = "{\"logo\": \"data:image/jpeg;base64,/9j/4AAQSkZJRgA==\"}") private String data; + @Schema(description = "whether non-owner holders of asset are barred from using asset", example = "false") + private boolean isUnspendable; // Constructors @@ -59,7 +61,7 @@ public class IssueAssetTransactionData extends TransactionData { /** From repository */ public IssueAssetTransactionData(BaseTransactionData baseTransactionData, - Long assetId, String owner, String assetName, String description, long quantity, boolean isDivisible, String data) { + Long assetId, String owner, String assetName, String description, long quantity, boolean isDivisible, String data, boolean isUnspendable) { super(TransactionType.ISSUE_ASSET, baseTransactionData); this.assetId = assetId; @@ -70,11 +72,13 @@ public class IssueAssetTransactionData extends TransactionData { this.quantity = quantity; this.isDivisible = isDivisible; this.data = data; + this.isUnspendable = isUnspendable; } /** From network/API */ - public IssueAssetTransactionData(BaseTransactionData baseTransactionData, String owner, String assetName, String description, long quantity, boolean isDivisible, String data) { - this(baseTransactionData, null, owner, assetName, description, quantity, isDivisible, data); + public IssueAssetTransactionData(BaseTransactionData baseTransactionData, String owner, String assetName, String description, + long quantity, boolean isDivisible, String data, boolean isUnspendable) { + this(baseTransactionData, null, owner, assetName, description, quantity, isDivisible, data, isUnspendable); } // Getters/Setters @@ -119,4 +123,8 @@ public class IssueAssetTransactionData extends TransactionData { return this.data; } + public boolean getIsUnspendable() { + return this.isUnspendable; + } + } diff --git a/src/main/java/org/qora/data/transaction/MessageTransactionData.java b/src/main/java/org/qora/data/transaction/MessageTransactionData.java index 1a00fbfa..db5f3e08 100644 --- a/src/main/java/org/qora/data/transaction/MessageTransactionData.java +++ b/src/main/java/org/qora/data/transaction/MessageTransactionData.java @@ -48,7 +48,7 @@ public class MessageTransactionData extends TransactionData { if (assetId != null) this.assetId = assetId; else - this.assetId = Asset.QORA; + this.assetId = Asset.QORT; this.amount = amount; this.data = data; diff --git a/src/main/java/org/qora/naming/Name.java b/src/main/java/org/qora/naming/Name.java index 5ffbf01a..2741258c 100644 --- a/src/main/java/org/qora/naming/Name.java +++ b/src/main/java/org/qora/naming/Name.java @@ -158,13 +158,13 @@ public class Name { // Update seller's balance Account seller = new Account(this.repository, this.nameData.getOwner()); - seller.setConfirmedBalance(Asset.QORA, seller.getConfirmedBalance(Asset.QORA).add(buyNameTransactionData.getAmount())); + seller.setConfirmedBalance(Asset.QORT, seller.getConfirmedBalance(Asset.QORT).add(buyNameTransactionData.getAmount())); // Set new owner Account buyer = new PublicKeyAccount(this.repository, buyNameTransactionData.getBuyerPublicKey()); this.nameData.setOwner(buyer.getAddress()); // Update buyer's balance - buyer.setConfirmedBalance(Asset.QORA, buyer.getConfirmedBalance(Asset.QORA).subtract(buyNameTransactionData.getAmount())); + buyer.setConfirmedBalance(Asset.QORT, buyer.getConfirmedBalance(Asset.QORT).subtract(buyNameTransactionData.getAmount())); // Update reference in transaction data buyNameTransactionData.setNameReference(this.nameData.getReference()); @@ -189,14 +189,14 @@ public class Name { // Revert buyer's balance Account buyer = new PublicKeyAccount(this.repository, buyNameTransactionData.getBuyerPublicKey()); - buyer.setConfirmedBalance(Asset.QORA, buyer.getConfirmedBalance(Asset.QORA).add(buyNameTransactionData.getAmount())); + buyer.setConfirmedBalance(Asset.QORT, buyer.getConfirmedBalance(Asset.QORT).add(buyNameTransactionData.getAmount())); // Previous Name's owner and/or data taken from referenced transaction this.revert(); // Revert seller's balance Account seller = new Account(this.repository, this.nameData.getOwner()); - seller.setConfirmedBalance(Asset.QORA, seller.getConfirmedBalance(Asset.QORA).subtract(buyNameTransactionData.getAmount())); + seller.setConfirmedBalance(Asset.QORT, seller.getConfirmedBalance(Asset.QORT).subtract(buyNameTransactionData.getAmount())); // Save reverted name data this.repository.getNameRepository().save(this.nameData); diff --git a/src/main/java/org/qora/payment/Payment.java b/src/main/java/org/qora/payment/Payment.java index ee40dfa2..5c506e4e 100644 --- a/src/main/java/org/qora/payment/Payment.java +++ b/src/main/java/org/qora/payment/Payment.java @@ -47,7 +47,10 @@ public class Payment { // Total up payment amounts by assetId Map amountsByAssetId = new HashMap(); // Add transaction fee to start with - amountsByAssetId.put(Asset.QORA, fee); + amountsByAssetId.put(Asset.QORT, fee); + + // Grab sender info + Account sender = new PublicKeyAccount(this.repository, senderPublicKey); // Check payments, and calculate amount total by assetId for (PaymentData paymentData : payments) { @@ -82,6 +85,10 @@ public class Payment { if (assetData == null) return ValidationResult.ASSET_DOES_NOT_EXIST; + // Do not allow non-owner asset holders to use asset + if (assetData.getIsUnspendable() && !assetData.getOwner().equals(sender.getAddress())) + return ValidationResult.ASSET_NOT_SPENDABLE; + // If we're sending to an AT then assetId must match AT's assetId if (atData != null && atData.getAssetId() != paymentData.getAssetId()) return ValidationResult.ASSET_DOES_NOT_MATCH_AT; @@ -95,7 +102,6 @@ public class Payment { } // Check sender has enough of each asset - Account sender = new PublicKeyAccount(this.repository, senderPublicKey); for (Entry pair : amountsByAssetId.entrySet()) if (sender.getConfirmedBalance(pair.getKey()).compareTo(pair.getValue()) < 0) return ValidationResult.NO_BALANCE; @@ -177,7 +183,7 @@ public class Payment { Account sender = new PublicKeyAccount(this.repository, senderPublicKey); // Update sender's balance due to fee - sender.setConfirmedBalance(Asset.QORA, sender.getConfirmedBalance(Asset.QORA).subtract(fee)); + sender.setConfirmedBalance(Asset.QORT, sender.getConfirmedBalance(Asset.QORT).subtract(fee)); // Update sender's reference sender.setLastReference(signature); @@ -189,7 +195,7 @@ public class Payment { long assetId = paymentData.getAssetId(); // For QORA amounts only: if recipient has no reference yet, then this is their starting reference - if ((alwaysInitializeRecipientReference || assetId == Asset.QORA) && recipient.getLastReference() == null) + if ((alwaysInitializeRecipientReference || assetId == Asset.QORT) && recipient.getLastReference() == null) recipient.setLastReference(signature); } } @@ -230,7 +236,7 @@ public class Payment { Account sender = new PublicKeyAccount(this.repository, senderPublicKey); // Update sender's balance due to fee - sender.setConfirmedBalance(Asset.QORA, sender.getConfirmedBalance(Asset.QORA).add(fee)); + sender.setConfirmedBalance(Asset.QORT, sender.getConfirmedBalance(Asset.QORT).add(fee)); // Update sender's reference sender.setLastReference(reference); @@ -244,7 +250,7 @@ public class Payment { * For QORA amounts only: If recipient's last reference is this transaction's signature, then they can't have made any transactions of their own * (which would have changed their last reference) thus this is their first reference so remove it. */ - if ((alwaysUninitializeRecipientReference || assetId == Asset.QORA) && Arrays.equals(recipient.getLastReference(), signature)) + if ((alwaysUninitializeRecipientReference || assetId == Asset.QORT) && Arrays.equals(recipient.getLastReference(), signature)) recipient.setLastReference(null); } } diff --git a/src/main/java/org/qora/repository/AccountRepository.java b/src/main/java/org/qora/repository/AccountRepository.java index 01937b5a..730b5b03 100644 --- a/src/main/java/org/qora/repository/AccountRepository.java +++ b/src/main/java/org/qora/repository/AccountRepository.java @@ -67,6 +67,13 @@ public interface AccountRepository { */ public void setLevel(AccountData accountData) throws DataException; + /** + * Saves account's initial & current level, and public key if present, in repository. + *

+ * Note: ignores other fields like last reference, default groupID. + */ + public void setInitialLevel(AccountData accountData) throws DataException; + /** * Saves account's forging enabler, and public key if present, in repository. *

diff --git a/src/main/java/org/qora/repository/hsqldb/HSQLDBAccountRepository.java b/src/main/java/org/qora/repository/hsqldb/HSQLDBAccountRepository.java index a2dc6237..c748541d 100644 --- a/src/main/java/org/qora/repository/hsqldb/HSQLDBAccountRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/HSQLDBAccountRepository.java @@ -26,7 +26,7 @@ public class HSQLDBAccountRepository implements AccountRepository { @Override public AccountData getAccount(String address) throws DataException { - String sql = "SELECT reference, public_key, default_group_id, flags, forging_enabler, level FROM Accounts WHERE account = ?"; + String sql = "SELECT reference, public_key, default_group_id, flags, forging_enabler, initial_level, level FROM Accounts WHERE account = ?"; try (ResultSet resultSet = this.repository.checkedExecute(sql, address)) { if (resultSet == null) @@ -37,9 +37,10 @@ public class HSQLDBAccountRepository implements AccountRepository { int defaultGroupId = resultSet.getInt(3); int flags = resultSet.getInt(4); String forgingEnabler = resultSet.getString(5); - int level = resultSet.getInt(6); + int initialLevel = resultSet.getInt(6); + int level = resultSet.getInt(7); - return new AccountData(address, reference, publicKey, defaultGroupId, flags, forgingEnabler, level); + return new AccountData(address, reference, publicKey, defaultGroupId, flags, forgingEnabler, initialLevel, level); } catch (SQLException e) { throw new DataException("Unable to fetch account info from repository", e); } @@ -216,6 +217,24 @@ public class HSQLDBAccountRepository implements AccountRepository { } } + @Override + public void setInitialLevel(AccountData accountData) throws DataException { + HSQLDBSaver saveHelper = new HSQLDBSaver("Accounts"); + + saveHelper.bind("account", accountData.getAddress()).bind("level", accountData.getLevel()) + .bind("initial_level", accountData.getInitialLevel()); + + 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 initial level into repository", e); + } + } + @Override public void setForgingEnabler(AccountData accountData) throws DataException { HSQLDBSaver saveHelper = new HSQLDBSaver("Accounts"); diff --git a/src/main/java/org/qora/repository/hsqldb/HSQLDBAssetRepository.java b/src/main/java/org/qora/repository/hsqldb/HSQLDBAssetRepository.java index aa011587..d48d6a91 100644 --- a/src/main/java/org/qora/repository/hsqldb/HSQLDBAssetRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/HSQLDBAssetRepository.java @@ -28,7 +28,7 @@ public class HSQLDBAssetRepository implements AssetRepository { @Override public AssetData fromAssetId(long assetId) throws DataException { - String sql = "SELECT owner, asset_name, description, quantity, is_divisible, data, creation_group_id, reference FROM Assets WHERE asset_id = ?"; + String sql = "SELECT owner, asset_name, description, quantity, is_divisible, data, is_unspendable, creation_group_id, reference FROM Assets WHERE asset_id = ?"; try (ResultSet resultSet = this.repository.checkedExecute(sql, assetId)) { if (resultSet == null) @@ -40,11 +40,12 @@ public class HSQLDBAssetRepository implements AssetRepository { long quantity = resultSet.getLong(4); boolean isDivisible = resultSet.getBoolean(5); String data = resultSet.getString(6); - int creationGroupId = resultSet.getInt(7); - byte[] reference = resultSet.getBytes(8); + boolean isUnspendable = resultSet.getBoolean(7); + int creationGroupId = resultSet.getInt(8); + byte[] reference = resultSet.getBytes(9); - return new AssetData(assetId, owner, assetName, description, quantity, isDivisible, data, creationGroupId, - reference); + return new AssetData(assetId, owner, assetName, description, quantity, isDivisible, data, isUnspendable, + creationGroupId, reference); } catch (SQLException e) { throw new DataException("Unable to fetch asset from repository", e); } @@ -52,7 +53,7 @@ public class HSQLDBAssetRepository implements AssetRepository { @Override public AssetData fromAssetName(String assetName) throws DataException { - String sql = "SELECT owner, asset_id, description, quantity, is_divisible, data, creation_group_id, reference FROM Assets WHERE asset_name = ?"; + String sql = "SELECT owner, asset_id, description, quantity, is_divisible, data, is_unspendable, creation_group_id, reference FROM Assets WHERE asset_name = ?"; try (ResultSet resultSet = this.repository.checkedExecute(sql, assetName)) { if (resultSet == null) @@ -64,11 +65,12 @@ public class HSQLDBAssetRepository implements AssetRepository { long quantity = resultSet.getLong(4); boolean isDivisible = resultSet.getBoolean(5); String data = resultSet.getString(6); - int creationGroupId = resultSet.getInt(7); - byte[] reference = resultSet.getBytes(8); + boolean isUnspendable = resultSet.getBoolean(7); + int creationGroupId = resultSet.getInt(8); + byte[] reference = resultSet.getBytes(9); - return new AssetData(assetId, owner, assetName, description, quantity, isDivisible, data, creationGroupId, - reference); + return new AssetData(assetId, owner, assetName, description, quantity, isDivisible, data, isUnspendable, + creationGroupId, reference); } catch (SQLException e) { throw new DataException("Unable to fetch asset from repository", e); } @@ -95,7 +97,8 @@ public class HSQLDBAssetRepository implements AssetRepository { @Override public List getAllAssets(Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(256); - sql.append("SELECT asset_id, owner, asset_name, description, quantity, is_divisible, data, creation_group_id, reference FROM Assets ORDER BY asset_id"); + sql.append("SELECT asset_id, owner, asset_name, description, quantity, is_divisible, data, is_unspendable, creation_group_id, reference " + + "FROM Assets ORDER BY asset_id"); if (reverse != null && reverse) sql.append(" DESC"); @@ -115,11 +118,12 @@ public class HSQLDBAssetRepository implements AssetRepository { long quantity = resultSet.getLong(5); boolean isDivisible = resultSet.getBoolean(6); String data = resultSet.getString(7); + boolean isUnspendable = resultSet.getBoolean(7); int creationGroupId = resultSet.getInt(8); byte[] reference = resultSet.getBytes(9); assets.add(new AssetData(assetId, owner, assetName, description, quantity, isDivisible, data, - creationGroupId, reference)); + isUnspendable,creationGroupId, reference)); } while (resultSet.next()); return assets; @@ -159,8 +163,8 @@ public class HSQLDBAssetRepository implements AssetRepository { saveHelper.bind("asset_id", assetData.getAssetId()).bind("owner", assetData.getOwner()) .bind("asset_name", assetData.getName()).bind("description", assetData.getDescription()) .bind("quantity", assetData.getQuantity()).bind("is_divisible", assetData.getIsDivisible()) - .bind("data", assetData.getData()).bind("creation_group_id", assetData.getCreationGroupId()) - .bind("reference", assetData.getReference()); + .bind("data", assetData.getData()).bind("is_unspendable", assetData.getIsUnspendable()) + .bind("creation_group_id", assetData.getCreationGroupId()).bind("reference", assetData.getReference()); try { saveHelper.execute(this.repository); diff --git a/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java index 698b241a..61ba018c 100644 --- a/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -778,10 +778,11 @@ public class HSQLDBDatabaseUpdates { case 54: // Account 'level' + stmt.execute("ALTER TABLE Accounts ADD COLUMN initial_level TINYINT NOT NULL DEFAULT 0"); stmt.execute("ALTER TABLE Accounts ADD COLUMN level TINYINT NOT NULL DEFAULT 0"); // Corresponding transaction to set level stmt.execute("CREATE TABLE AccountLevelTransactions (signature Signature, creator QoraPublicKey NOT NULL, target QoraAddress NOT NULL, level INT NOT NULL, " - + "previous_level INT, PRIMARY KEY (signature), FOREIGN KEY (signature) REFERENCES Transactions (signature) ON DELETE CASCADE)"); + + "PRIMARY KEY (signature), FOREIGN KEY (signature) REFERENCES Transactions (signature) ON DELETE CASCADE)"); break; case 55: @@ -792,6 +793,12 @@ public class HSQLDBDatabaseUpdates { stmt.execute("ALTER TABLE Blocks ADD COLUMN online_accounts_signatures BLOB"); break; + case 56: + // Modify assets to support "unspendable" flag so we can implement the representative legacy QORA asset. + stmt.execute("ALTER TABLE Assets ADD COLUMN is_unspendable BOOLEAN NOT NULL DEFAULT FALSE BEFORE creation_group_id"); + stmt.execute("ALTER TABLE IssueAssetTransactions ADD COLUMN is_unspendable BOOLEAN NOT NULL DEFAULT FALSE BEFORE asset_id"); + break; + default: // nothing to do return false; diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java index e1a29003..00647708 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java @@ -17,7 +17,7 @@ public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepo } TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException { - String sql = "SELECT owner, asset_name, description, quantity, is_divisible, data, asset_id FROM IssueAssetTransactions WHERE signature = ?"; + String sql = "SELECT owner, asset_name, description, quantity, is_divisible, data, is_unspendable, asset_id FROM IssueAssetTransactions WHERE signature = ?"; try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) { if (resultSet == null) @@ -29,14 +29,15 @@ public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepo long quantity = resultSet.getLong(4); boolean isDivisible = resultSet.getBoolean(5); String data = resultSet.getString(6); + boolean isUnspendable = resultSet.getBoolean(7); // Special null-checking for asset ID - Long assetId = resultSet.getLong(7); + Long assetId = resultSet.getLong(8); if (assetId == 0 && resultSet.wasNull()) assetId = null; return new IssueAssetTransactionData(baseTransactionData, assetId, owner, assetName, description, quantity, isDivisible, - data); + data, isUnspendable); } catch (SQLException e) { throw new DataException("Unable to fetch issue asset transaction from repository", e); } @@ -51,8 +52,8 @@ public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepo saveHelper.bind("signature", issueAssetTransactionData.getSignature()).bind("issuer", issueAssetTransactionData.getIssuerPublicKey()) .bind("owner", issueAssetTransactionData.getOwner()).bind("asset_name", issueAssetTransactionData.getAssetName()) .bind("description", issueAssetTransactionData.getDescription()).bind("quantity", issueAssetTransactionData.getQuantity()) - .bind("is_divisible", issueAssetTransactionData.getIsDivisible()) - .bind("data", issueAssetTransactionData.getData()).bind("asset_id", issueAssetTransactionData.getAssetId()); + .bind("is_divisible", issueAssetTransactionData.getIsDivisible()).bind("data", issueAssetTransactionData.getData()) + .bind("is_unspendable", issueAssetTransactionData.getIsUnspendable()).bind("asset_id", issueAssetTransactionData.getAssetId()); try { saveHelper.execute(this.repository); diff --git a/src/main/java/org/qora/transaction/AccountFlagsTransaction.java b/src/main/java/org/qora/transaction/AccountFlagsTransaction.java index 9ecbfe3e..ad537ba3 100644 --- a/src/main/java/org/qora/transaction/AccountFlagsTransaction.java +++ b/src/main/java/org/qora/transaction/AccountFlagsTransaction.java @@ -77,7 +77,7 @@ public class AccountFlagsTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (creator.getConfirmedBalance(Asset.QORA).compareTo(accountFlagsTransactionData.getFee()) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(accountFlagsTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/AccountLevelTransaction.java b/src/main/java/org/qora/transaction/AccountLevelTransaction.java index 51534a77..018a339f 100644 --- a/src/main/java/org/qora/transaction/AccountLevelTransaction.java +++ b/src/main/java/org/qora/transaction/AccountLevelTransaction.java @@ -77,7 +77,7 @@ public class AccountLevelTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (creator.getConfirmedBalance(Asset.QORA).compareTo(accountLevelTransactionData.getFee()) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(accountLevelTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; @@ -86,15 +86,12 @@ public class AccountLevelTransaction extends Transaction { @Override public void process() throws DataException { Account target = getTarget(); - Integer previousLevel = target.getLevel(); - accountLevelTransactionData.setPreviousLevel(previousLevel); - - // Save this transaction with target account's previous level value + // Save this transaction this.repository.getTransactionRepository().save(accountLevelTransactionData); - // Set account's new level - target.setLevel(this.accountLevelTransactionData.getLevel()); + // Set account's initial level + target.setInitialLevel(this.accountLevelTransactionData.getLevel()); } @Override @@ -102,17 +99,8 @@ public class AccountLevelTransaction extends Transaction { // Revert Account target = getTarget(); - Integer previousLevel = accountLevelTransactionData.getPreviousLevel(); - - // If previousLevel are null then account didn't exist before this transaction - if (previousLevel == null) - this.repository.getAccountRepository().delete(target.getAddress()); - else - target.setLevel(previousLevel); - - // Remove previous level from transaction itself - accountLevelTransactionData.setPreviousLevel(null); - this.repository.getTransactionRepository().save(accountLevelTransactionData); + // This is only ever a genesis block transaction so simply delete account + this.repository.getAccountRepository().delete(target.getAddress()); } } diff --git a/src/main/java/org/qora/transaction/AddGroupAdminTransaction.java b/src/main/java/org/qora/transaction/AddGroupAdminTransaction.java index 568a35b6..2cae7648 100644 --- a/src/main/java/org/qora/transaction/AddGroupAdminTransaction.java +++ b/src/main/java/org/qora/transaction/AddGroupAdminTransaction.java @@ -102,7 +102,7 @@ public class AddGroupAdminTransaction extends Transaction { return ValidationResult.ALREADY_GROUP_ADMIN; // Check group owner has enough funds - if (owner.getConfirmedBalance(Asset.QORA).compareTo(addGroupAdminTransactionData.getFee()) < 0) + if (owner.getConfirmedBalance(Asset.QORT).compareTo(addGroupAdminTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/ArbitraryTransaction.java b/src/main/java/org/qora/transaction/ArbitraryTransaction.java index 573d9b38..0108e514 100644 --- a/src/main/java/org/qora/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qora/transaction/ArbitraryTransaction.java @@ -71,7 +71,7 @@ public class ArbitraryTransaction extends Transaction { if (arbitraryTransactionData.getVersion() != 1) for (PaymentData paymentData : arbitraryTransactionData.getPayments()) // We're only interested in QORA - if (paymentData.getAssetId() == Asset.QORA) { + if (paymentData.getAssetId() == Asset.QORT) { if (address.equals(paymentData.getRecipient())) amount = amount.add(paymentData.getAmount()); else if (address.equals(senderAddress)) diff --git a/src/main/java/org/qora/transaction/AtTransaction.java b/src/main/java/org/qora/transaction/AtTransaction.java index 25f79054..f90bd299 100644 --- a/src/main/java/org/qora/transaction/AtTransaction.java +++ b/src/main/java/org/qora/transaction/AtTransaction.java @@ -84,12 +84,12 @@ public class AtTransaction extends Transaction { if (address.equals(atAddress)) { amount = amount.subtract(this.atTransactionData.getFee()); - if (this.atTransactionData.getAmount() != null && this.atTransactionData.getAssetId() == Asset.QORA) + if (this.atTransactionData.getAmount() != null && this.atTransactionData.getAssetId() == Asset.QORT) amount = amount.subtract(this.atTransactionData.getAmount()); } if (address.equals(this.atTransactionData.getRecipient()) && this.atTransactionData.getAmount() != null - && this.atTransactionData.getAssetId() == Asset.QORA) + && this.atTransactionData.getAssetId() == Asset.QORT) amount = amount.add(this.atTransactionData.getAmount()); return amount; @@ -183,7 +183,7 @@ public class AtTransaction extends Transaction { long assetId = this.atTransactionData.getAssetId(); // For QORA amounts only: if recipient has no reference yet, then this is their starting reference - if (assetId == Asset.QORA && recipient.getLastReference() == null) + if (assetId == Asset.QORT && recipient.getLastReference() == null) // In Qora1 last reference was set to 64-bytes of zero // In Qora2 we use AT-Transction's signature, which makes more sense recipient.setLastReference(this.atTransactionData.getSignature()); @@ -220,7 +220,7 @@ public class AtTransaction extends Transaction { * For QORA amounts only: If recipient's last reference is this transaction's signature, then they can't have made any transactions of their own * (which would have changed their last reference) thus this is their first reference so remove it. */ - if (assetId == Asset.QORA && Arrays.equals(recipient.getLastReference(), this.atTransactionData.getSignature())) + if (assetId == Asset.QORT && Arrays.equals(recipient.getLastReference(), this.atTransactionData.getSignature())) recipient.setLastReference(null); } } diff --git a/src/main/java/org/qora/transaction/BuyNameTransaction.java b/src/main/java/org/qora/transaction/BuyNameTransaction.java index 07a87f05..e2642c01 100644 --- a/src/main/java/org/qora/transaction/BuyNameTransaction.java +++ b/src/main/java/org/qora/transaction/BuyNameTransaction.java @@ -110,7 +110,7 @@ public class BuyNameTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check issuer has enough funds - if (buyer.getConfirmedBalance(Asset.QORA).compareTo(buyNameTransactionData.getFee()) < 0) + if (buyer.getConfirmedBalance(Asset.QORT).compareTo(buyNameTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/CancelAssetOrderTransaction.java b/src/main/java/org/qora/transaction/CancelAssetOrderTransaction.java index 66b1cf26..0b456f95 100644 --- a/src/main/java/org/qora/transaction/CancelAssetOrderTransaction.java +++ b/src/main/java/org/qora/transaction/CancelAssetOrderTransaction.java @@ -89,7 +89,7 @@ public class CancelAssetOrderTransaction extends Transaction { return ValidationResult.INVALID_ORDER_CREATOR; // Check creator has enough QORA for fee - if (creator.getConfirmedBalance(Asset.QORA).compareTo(cancelOrderTransactionData.getFee()) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(cancelOrderTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/CancelGroupBanTransaction.java b/src/main/java/org/qora/transaction/CancelGroupBanTransaction.java index 164f7f78..7be7f157 100644 --- a/src/main/java/org/qora/transaction/CancelGroupBanTransaction.java +++ b/src/main/java/org/qora/transaction/CancelGroupBanTransaction.java @@ -100,7 +100,7 @@ public class CancelGroupBanTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (admin.getConfirmedBalance(Asset.QORA).compareTo(groupUnbanTransactionData.getFee()) < 0) + if (admin.getConfirmedBalance(Asset.QORT).compareTo(groupUnbanTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/CancelGroupInviteTransaction.java b/src/main/java/org/qora/transaction/CancelGroupInviteTransaction.java index 94ab0a55..d8f85085 100644 --- a/src/main/java/org/qora/transaction/CancelGroupInviteTransaction.java +++ b/src/main/java/org/qora/transaction/CancelGroupInviteTransaction.java @@ -100,7 +100,7 @@ public class CancelGroupInviteTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (admin.getConfirmedBalance(Asset.QORA).compareTo(cancelGroupInviteTransactionData.getFee()) < 0) + if (admin.getConfirmedBalance(Asset.QORT).compareTo(cancelGroupInviteTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/CancelSellNameTransaction.java b/src/main/java/org/qora/transaction/CancelSellNameTransaction.java index 88756295..ab18a3b3 100644 --- a/src/main/java/org/qora/transaction/CancelSellNameTransaction.java +++ b/src/main/java/org/qora/transaction/CancelSellNameTransaction.java @@ -96,7 +96,7 @@ public class CancelSellNameTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check issuer has enough funds - if (owner.getConfirmedBalance(Asset.QORA).compareTo(cancelSellNameTransactionData.getFee()) < 0) + if (owner.getConfirmedBalance(Asset.QORT).compareTo(cancelSellNameTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/CreateAssetOrderTransaction.java b/src/main/java/org/qora/transaction/CreateAssetOrderTransaction.java index a61018dd..308492a6 100644 --- a/src/main/java/org/qora/transaction/CreateAssetOrderTransaction.java +++ b/src/main/java/org/qora/transaction/CreateAssetOrderTransaction.java @@ -101,6 +101,10 @@ public class CreateAssetOrderTransaction extends Transaction { if (wantAssetData == null) return ValidationResult.ASSET_DOES_NOT_EXIST; + // Unspendable assets are not tradable + if (haveAssetData.getIsUnspendable() || wantAssetData.getIsUnspendable()) + return ValidationResult.ASSET_NOT_SPENDABLE; + Account creator = getCreator(); boolean isNewPricing = createOrderTransactionData.getTimestamp() >= BlockChain.getInstance().getNewAssetPricingTimestamp(); @@ -153,9 +157,9 @@ public class CreateAssetOrderTransaction extends Transaction { // Check order creator has enough asset balance AFTER removing fee, in case asset is QORA // If asset is QORA then we need to check amount + fee in one go - if (haveAssetId == Asset.QORA) { + if (haveAssetId == Asset.QORT) { // Check creator has enough funds for amount + fee in QORA - if (creator.getConfirmedBalance(Asset.QORA).compareTo(committedCost.add(createOrderTransactionData.getFee())) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(committedCost.add(createOrderTransactionData.getFee())) < 0) return ValidationResult.NO_BALANCE; } else { // Check creator has enough funds for amount in whatever asset @@ -165,7 +169,7 @@ public class CreateAssetOrderTransaction extends Transaction { // Check creator has enough funds for fee in QORA // NOTE: in Gen1 pre-POWFIX-RELEASE transactions didn't have this check if (createOrderTransactionData.getTimestamp() >= BlockChain.getInstance().getPowFixReleaseTimestamp() - && creator.getConfirmedBalance(Asset.QORA).compareTo(createOrderTransactionData.getFee()) < 0) + && creator.getConfirmedBalance(Asset.QORT).compareTo(createOrderTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; } diff --git a/src/main/java/org/qora/transaction/CreateGroupTransaction.java b/src/main/java/org/qora/transaction/CreateGroupTransaction.java index f1701798..85baa05c 100644 --- a/src/main/java/org/qora/transaction/CreateGroupTransaction.java +++ b/src/main/java/org/qora/transaction/CreateGroupTransaction.java @@ -98,7 +98,7 @@ public class CreateGroupTransaction extends Transaction { Account creator = getCreator(); // Check creator has enough funds - if (creator.getConfirmedBalance(Asset.QORA).compareTo(createGroupTransactionData.getFee()) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(createGroupTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/CreatePollTransaction.java b/src/main/java/org/qora/transaction/CreatePollTransaction.java index c3e96072..d8cb8c46 100644 --- a/src/main/java/org/qora/transaction/CreatePollTransaction.java +++ b/src/main/java/org/qora/transaction/CreatePollTransaction.java @@ -133,7 +133,7 @@ public class CreatePollTransaction extends Transaction { Account creator = getCreator(); // Check issuer has enough funds - if (creator.getConfirmedBalance(Asset.QORA).compareTo(createPollTransactionData.getFee()) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(createPollTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/DeployAtTransaction.java b/src/main/java/org/qora/transaction/DeployAtTransaction.java index 767d07d2..75aa3947 100644 --- a/src/main/java/org/qora/transaction/DeployAtTransaction.java +++ b/src/main/java/org/qora/transaction/DeployAtTransaction.java @@ -162,6 +162,10 @@ public class DeployAtTransaction extends Transaction { if (assetData == null) return ValidationResult.ASSET_DOES_NOT_EXIST; + // Unspendable assets are not valid + if (assetData.getIsUnspendable()) + return ValidationResult.ASSET_NOT_SPENDABLE; + // Check asset amount is integer if asset is not divisible if (!assetData.getIsDivisible() && deployATTransactionData.getAmount().stripTrailingZeros().scale() > 0) return ValidationResult.INVALID_AMOUNT; @@ -173,14 +177,14 @@ public class DeployAtTransaction extends Transaction { Account creator = getCreator(); // Check creator has enough funds - if (assetId == Asset.QORA) { + if (assetId == Asset.QORT) { // Simple case: amount and fee both in Qora BigDecimal minimumBalance = deployATTransactionData.getFee().add(deployATTransactionData.getAmount()); - if (creator.getConfirmedBalance(Asset.QORA).compareTo(minimumBalance) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(minimumBalance) < 0) return ValidationResult.NO_BALANCE; } else { - if (creator.getConfirmedBalance(Asset.QORA).compareTo(deployATTransactionData.getFee()) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(deployATTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; if (creator.getConfirmedBalance(assetId).compareTo(deployATTransactionData.getAmount()) < 0) @@ -209,14 +213,14 @@ public class DeployAtTransaction extends Transaction { long assetId = deployATTransactionData.getAssetId(); // Check creator has enough funds - if (assetId == Asset.QORA) { + if (assetId == Asset.QORT) { // Simple case: amount and fee both in Qora BigDecimal minimumBalance = deployATTransactionData.getFee().add(deployATTransactionData.getAmount()); - if (creator.getConfirmedBalance(Asset.QORA).compareTo(minimumBalance) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(minimumBalance) < 0) return ValidationResult.NO_BALANCE; } else { - if (creator.getConfirmedBalance(Asset.QORA).compareTo(deployATTransactionData.getFee()) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(deployATTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; if (creator.getConfirmedBalance(assetId).compareTo(deployATTransactionData.getAmount()) < 0) diff --git a/src/main/java/org/qora/transaction/EnableForgingTransaction.java b/src/main/java/org/qora/transaction/EnableForgingTransaction.java index dbed9c92..f0f96f9a 100644 --- a/src/main/java/org/qora/transaction/EnableForgingTransaction.java +++ b/src/main/java/org/qora/transaction/EnableForgingTransaction.java @@ -121,7 +121,7 @@ public class EnableForgingTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (creator.getConfirmedBalance(Asset.QORA).compareTo(enableForgingTransactionData.getFee()) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(enableForgingTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/GenesisTransaction.java b/src/main/java/org/qora/transaction/GenesisTransaction.java index 00b6e05c..53d40fc0 100644 --- a/src/main/java/org/qora/transaction/GenesisTransaction.java +++ b/src/main/java/org/qora/transaction/GenesisTransaction.java @@ -139,7 +139,7 @@ public class GenesisTransaction extends Transaction { Account recipient = new Account(repository, genesisTransactionData.getRecipient()); // Update recipient's balance - recipient.setConfirmedBalance(Asset.QORA, genesisTransactionData.getAmount()); + recipient.setConfirmedBalance(Asset.QORT, genesisTransactionData.getAmount()); } @Override diff --git a/src/main/java/org/qora/transaction/GroupApprovalTransaction.java b/src/main/java/org/qora/transaction/GroupApprovalTransaction.java index 59ef97a9..15035d09 100644 --- a/src/main/java/org/qora/transaction/GroupApprovalTransaction.java +++ b/src/main/java/org/qora/transaction/GroupApprovalTransaction.java @@ -87,7 +87,7 @@ public class GroupApprovalTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (admin.getConfirmedBalance(Asset.QORA).compareTo(groupApprovalTransactionData.getFee()) < 0) + if (admin.getConfirmedBalance(Asset.QORT).compareTo(groupApprovalTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/GroupBanTransaction.java b/src/main/java/org/qora/transaction/GroupBanTransaction.java index 8516e4a5..ae5d3ed5 100644 --- a/src/main/java/org/qora/transaction/GroupBanTransaction.java +++ b/src/main/java/org/qora/transaction/GroupBanTransaction.java @@ -101,7 +101,7 @@ public class GroupBanTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check admin has enough funds - if (admin.getConfirmedBalance(Asset.QORA).compareTo(groupBanTransactionData.getFee()) < 0) + if (admin.getConfirmedBalance(Asset.QORT).compareTo(groupBanTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/GroupInviteTransaction.java b/src/main/java/org/qora/transaction/GroupInviteTransaction.java index 03d6a647..54e5855b 100644 --- a/src/main/java/org/qora/transaction/GroupInviteTransaction.java +++ b/src/main/java/org/qora/transaction/GroupInviteTransaction.java @@ -107,7 +107,7 @@ public class GroupInviteTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (admin.getConfirmedBalance(Asset.QORA).compareTo(groupInviteTransactionData.getFee()) < 0) + if (admin.getConfirmedBalance(Asset.QORT).compareTo(groupInviteTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/GroupKickTransaction.java b/src/main/java/org/qora/transaction/GroupKickTransaction.java index 7f10d8e8..d953e214 100644 --- a/src/main/java/org/qora/transaction/GroupKickTransaction.java +++ b/src/main/java/org/qora/transaction/GroupKickTransaction.java @@ -107,7 +107,7 @@ public class GroupKickTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (admin.getConfirmedBalance(Asset.QORA).compareTo(groupKickTransactionData.getFee()) < 0) + if (admin.getConfirmedBalance(Asset.QORT).compareTo(groupKickTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/IssueAssetTransaction.java b/src/main/java/org/qora/transaction/IssueAssetTransaction.java index 969dba7c..f94ba68c 100644 --- a/src/main/java/org/qora/transaction/IssueAssetTransaction.java +++ b/src/main/java/org/qora/transaction/IssueAssetTransaction.java @@ -120,7 +120,7 @@ public class IssueAssetTransaction extends Transaction { Account issuer = getIssuer(); // Check issuer has enough funds - if (issuer.getConfirmedBalance(Asset.QORA).compareTo(issueAssetTransactionData.getFee()) < 0) + if (issuer.getConfirmedBalance(Asset.QORT).compareTo(issueAssetTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/JoinGroupTransaction.java b/src/main/java/org/qora/transaction/JoinGroupTransaction.java index de883a95..74a39052 100644 --- a/src/main/java/org/qora/transaction/JoinGroupTransaction.java +++ b/src/main/java/org/qora/transaction/JoinGroupTransaction.java @@ -87,7 +87,7 @@ public class JoinGroupTransaction extends Transaction { if (joinGroupTransactionData.getFee().compareTo(BigDecimal.ZERO) <= 0) return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (joiner.getConfirmedBalance(Asset.QORA).compareTo(joinGroupTransactionData.getFee()) < 0) + if (joiner.getConfirmedBalance(Asset.QORT).compareTo(joinGroupTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/LeaveGroupTransaction.java b/src/main/java/org/qora/transaction/LeaveGroupTransaction.java index 5f7a9292..9ee97d6c 100644 --- a/src/main/java/org/qora/transaction/LeaveGroupTransaction.java +++ b/src/main/java/org/qora/transaction/LeaveGroupTransaction.java @@ -86,7 +86,7 @@ public class LeaveGroupTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (leaver.getConfirmedBalance(Asset.QORA).compareTo(leaveGroupTransactionData.getFee()) < 0) + if (leaver.getConfirmedBalance(Asset.QORT).compareTo(leaveGroupTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/MessageTransaction.java b/src/main/java/org/qora/transaction/MessageTransaction.java index 7dc0b982..73639f80 100644 --- a/src/main/java/org/qora/transaction/MessageTransaction.java +++ b/src/main/java/org/qora/transaction/MessageTransaction.java @@ -61,7 +61,7 @@ public class MessageTransaction extends Transaction { amount = amount.subtract(this.transactionData.getFee()); // We're only interested in QORA - if (messageTransactionData.getAssetId() == Asset.QORA) { + if (messageTransactionData.getAssetId() == Asset.QORT) { if (address.equals(messageTransactionData.getRecipient())) amount = amount.add(messageTransactionData.getAmount()); else if (address.equals(senderAddress)) diff --git a/src/main/java/org/qora/transaction/MultiPaymentTransaction.java b/src/main/java/org/qora/transaction/MultiPaymentTransaction.java index 702c4fbf..c5e5aed6 100644 --- a/src/main/java/org/qora/transaction/MultiPaymentTransaction.java +++ b/src/main/java/org/qora/transaction/MultiPaymentTransaction.java @@ -68,7 +68,7 @@ public class MultiPaymentTransaction extends Transaction { // We're only interested in QORA for (PaymentData paymentData : multiPaymentTransactionData.getPayments()) - if (paymentData.getAssetId() == Asset.QORA) { + if (paymentData.getAssetId() == Asset.QORT) { if (address.equals(paymentData.getRecipient())) amount = amount.add(paymentData.getAmount()); else if (address.equals(senderAddress)) @@ -104,7 +104,7 @@ public class MultiPaymentTransaction extends Transaction { // Check sender has enough funds for fee // NOTE: in Gen1 pre-POWFIX-RELEASE transactions didn't have this check if (multiPaymentTransactionData.getTimestamp() >= BlockChain.getInstance().getPowFixReleaseTimestamp() - && sender.getConfirmedBalance(Asset.QORA).compareTo(multiPaymentTransactionData.getFee()) < 0) + && sender.getConfirmedBalance(Asset.QORT).compareTo(multiPaymentTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return new Payment(this.repository).isValid(multiPaymentTransactionData.getSenderPublicKey(), payments, multiPaymentTransactionData.getFee()); diff --git a/src/main/java/org/qora/transaction/PaymentTransaction.java b/src/main/java/org/qora/transaction/PaymentTransaction.java index a0c37b64..273c7790 100644 --- a/src/main/java/org/qora/transaction/PaymentTransaction.java +++ b/src/main/java/org/qora/transaction/PaymentTransaction.java @@ -71,7 +71,7 @@ public class PaymentTransaction extends Transaction { // Processing private PaymentData getPaymentData() { - return new PaymentData(paymentTransactionData.getRecipient(), Asset.QORA, paymentTransactionData.getAmount()); + return new PaymentData(paymentTransactionData.getRecipient(), Asset.QORT, paymentTransactionData.getAmount()); } @Override diff --git a/src/main/java/org/qora/transaction/ProxyForgingTransaction.java b/src/main/java/org/qora/transaction/ProxyForgingTransaction.java index 09b6c357..f11fe5ab 100644 --- a/src/main/java/org/qora/transaction/ProxyForgingTransaction.java +++ b/src/main/java/org/qora/transaction/ProxyForgingTransaction.java @@ -120,7 +120,7 @@ public class ProxyForgingTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (creator.getConfirmedBalance(Asset.QORA).compareTo(proxyForgingTransactionData.getFee()) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(proxyForgingTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/RegisterNameTransaction.java b/src/main/java/org/qora/transaction/RegisterNameTransaction.java index ca4c3748..3defabfd 100644 --- a/src/main/java/org/qora/transaction/RegisterNameTransaction.java +++ b/src/main/java/org/qora/transaction/RegisterNameTransaction.java @@ -100,7 +100,7 @@ public class RegisterNameTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check issuer has enough funds - if (registrant.getConfirmedBalance(Asset.QORA).compareTo(registerNameTransactionData.getFee()) < 0) + if (registrant.getConfirmedBalance(Asset.QORT).compareTo(registerNameTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/RemoveGroupAdminTransaction.java b/src/main/java/org/qora/transaction/RemoveGroupAdminTransaction.java index 971806f8..d5b1d117 100644 --- a/src/main/java/org/qora/transaction/RemoveGroupAdminTransaction.java +++ b/src/main/java/org/qora/transaction/RemoveGroupAdminTransaction.java @@ -100,7 +100,7 @@ public class RemoveGroupAdminTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (owner.getConfirmedBalance(Asset.QORA).compareTo(removeGroupAdminTransactionData.getFee()) < 0) + if (owner.getConfirmedBalance(Asset.QORT).compareTo(removeGroupAdminTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/SellNameTransaction.java b/src/main/java/org/qora/transaction/SellNameTransaction.java index 1302b3e9..de5cca4d 100644 --- a/src/main/java/org/qora/transaction/SellNameTransaction.java +++ b/src/main/java/org/qora/transaction/SellNameTransaction.java @@ -107,7 +107,7 @@ public class SellNameTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check issuer has enough funds - if (owner.getConfirmedBalance(Asset.QORA).compareTo(sellNameTransactionData.getFee()) < 0) + if (owner.getConfirmedBalance(Asset.QORT).compareTo(sellNameTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/SetGroupTransaction.java b/src/main/java/org/qora/transaction/SetGroupTransaction.java index 70d7845a..65d9e4da 100644 --- a/src/main/java/org/qora/transaction/SetGroupTransaction.java +++ b/src/main/java/org/qora/transaction/SetGroupTransaction.java @@ -74,7 +74,7 @@ public class SetGroupTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (creator.getConfirmedBalance(Asset.QORA).compareTo(setGroupTransactionData.getFee()) < 0) + if (creator.getConfirmedBalance(Asset.QORT).compareTo(setGroupTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/Transaction.java b/src/main/java/org/qora/transaction/Transaction.java index be713b95..2ed1e146 100644 --- a/src/main/java/org/qora/transaction/Transaction.java +++ b/src/main/java/org/qora/transaction/Transaction.java @@ -239,6 +239,7 @@ public abstract class Transaction { NO_BLOCKCHAIN_LOCK(86), ORDER_ALREADY_CLOSED(87), CLOCK_NOT_SYNCED(88), + ASSET_NOT_SPENDABLE(89), NOT_YET_RELEASED(1000); public final int value; @@ -946,7 +947,7 @@ public abstract class Transaction { Account creator = getCreator(); // Update transaction creator's balance - creator.setConfirmedBalance(Asset.QORA, creator.getConfirmedBalance(Asset.QORA).subtract(transactionData.getFee())); + creator.setConfirmedBalance(Asset.QORT, creator.getConfirmedBalance(Asset.QORT).subtract(transactionData.getFee())); // Update transaction creator's reference creator.setLastReference(transactionData.getSignature()); @@ -970,7 +971,7 @@ public abstract class Transaction { Account creator = getCreator(); // Update transaction creator's balance - creator.setConfirmedBalance(Asset.QORA, creator.getConfirmedBalance(Asset.QORA).add(transactionData.getFee())); + creator.setConfirmedBalance(Asset.QORT, creator.getConfirmedBalance(Asset.QORT).add(transactionData.getFee())); // Update transaction creator's reference creator.setLastReference(transactionData.getReference()); diff --git a/src/main/java/org/qora/transaction/TransferAssetTransaction.java b/src/main/java/org/qora/transaction/TransferAssetTransaction.java index c352b36c..8f0b06a9 100644 --- a/src/main/java/org/qora/transaction/TransferAssetTransaction.java +++ b/src/main/java/org/qora/transaction/TransferAssetTransaction.java @@ -58,7 +58,7 @@ public class TransferAssetTransaction extends Transaction { amount = amount.subtract(this.transactionData.getFee()); // We're only interested in QORA amounts - if (transferAssetTransactionData.getAssetId() == Asset.QORA) { + if (transferAssetTransactionData.getAssetId() == Asset.QORT) { if (address.equals(transferAssetTransactionData.getRecipient())) amount = amount.add(transferAssetTransactionData.getAmount()); else if (address.equals(senderAddress)) diff --git a/src/main/java/org/qora/transaction/UpdateAssetTransaction.java b/src/main/java/org/qora/transaction/UpdateAssetTransaction.java index f08c70ab..03f3d79a 100644 --- a/src/main/java/org/qora/transaction/UpdateAssetTransaction.java +++ b/src/main/java/org/qora/transaction/UpdateAssetTransaction.java @@ -110,7 +110,7 @@ public class UpdateAssetTransaction extends Transaction { Account currentOwner = getOwner(); // Check current owner has enough funds - if (currentOwner.getConfirmedBalance(Asset.QORA).compareTo(updateAssetTransactionData.getFee()) < 0) + if (currentOwner.getConfirmedBalance(Asset.QORT).compareTo(updateAssetTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/UpdateGroupTransaction.java b/src/main/java/org/qora/transaction/UpdateGroupTransaction.java index ede37bcc..528f820a 100644 --- a/src/main/java/org/qora/transaction/UpdateGroupTransaction.java +++ b/src/main/java/org/qora/transaction/UpdateGroupTransaction.java @@ -105,7 +105,7 @@ public class UpdateGroupTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check creator has enough funds - if (owner.getConfirmedBalance(Asset.QORA).compareTo(updateGroupTransactionData.getFee()) < 0) + if (owner.getConfirmedBalance(Asset.QORT).compareTo(updateGroupTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/UpdateNameTransaction.java b/src/main/java/org/qora/transaction/UpdateNameTransaction.java index eba2c0f1..d3f2bfd4 100644 --- a/src/main/java/org/qora/transaction/UpdateNameTransaction.java +++ b/src/main/java/org/qora/transaction/UpdateNameTransaction.java @@ -110,7 +110,7 @@ public class UpdateNameTransaction extends Transaction { return ValidationResult.NEGATIVE_FEE; // Check issuer has enough funds - if (owner.getConfirmedBalance(Asset.QORA).compareTo(updateNameTransactionData.getFee()) < 0) + if (owner.getConfirmedBalance(Asset.QORT).compareTo(updateNameTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transaction/VoteOnPollTransaction.java b/src/main/java/org/qora/transaction/VoteOnPollTransaction.java index 67553b00..0b38bd61 100644 --- a/src/main/java/org/qora/transaction/VoteOnPollTransaction.java +++ b/src/main/java/org/qora/transaction/VoteOnPollTransaction.java @@ -110,7 +110,7 @@ public class VoteOnPollTransaction extends Transaction { Account voter = getVoter(); // Check voter has enough funds - if (voter.getConfirmedBalance(Asset.QORA).compareTo(voteOnPollTransactionData.getFee()) < 0) + if (voter.getConfirmedBalance(Asset.QORT).compareTo(voteOnPollTransactionData.getFee()) < 0) return ValidationResult.NO_BALANCE; return ValidationResult.OK; diff --git a/src/main/java/org/qora/transform/transaction/DeployAtTransactionTransformer.java b/src/main/java/org/qora/transform/transaction/DeployAtTransactionTransformer.java index b4640cb4..8f1a79d4 100644 --- a/src/main/java/org/qora/transform/transaction/DeployAtTransactionTransformer.java +++ b/src/main/java/org/qora/transform/transaction/DeployAtTransactionTransformer.java @@ -87,7 +87,7 @@ public class DeployAtTransactionTransformer extends TransactionTransformer { BigDecimal amount = Serialization.deserializeBigDecimal(byteBuffer); - long assetId = Asset.QORA; + long assetId = Asset.QORT; if (version >= 4) assetId = byteBuffer.getLong(); diff --git a/src/main/java/org/qora/transform/transaction/GenesisTransactionTransformer.java b/src/main/java/org/qora/transform/transaction/GenesisTransactionTransformer.java index dfc9577d..3514eda5 100644 --- a/src/main/java/org/qora/transform/transaction/GenesisTransactionTransformer.java +++ b/src/main/java/org/qora/transform/transaction/GenesisTransactionTransformer.java @@ -47,7 +47,7 @@ public class GenesisTransactionTransformer extends TransactionTransformer { BigDecimal amount = Serialization.deserializeBigDecimal(byteBuffer); - long assetId = Asset.QORA; + long assetId = Asset.QORT; if (timestamp >= BlockChain.getInstance().getQoraV2Timestamp()) assetId = byteBuffer.getLong(); diff --git a/src/main/java/org/qora/transform/transaction/IssueAssetTransactionTransformer.java b/src/main/java/org/qora/transform/transaction/IssueAssetTransactionTransformer.java index 7c0454f9..d02e1904 100644 --- a/src/main/java/org/qora/transform/transaction/IssueAssetTransactionTransformer.java +++ b/src/main/java/org/qora/transform/transaction/IssueAssetTransactionTransformer.java @@ -28,6 +28,7 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { private static final int IS_DIVISIBLE_LENGTH = BOOLEAN_LENGTH; private static final int ASSET_REFERENCE_LENGTH = REFERENCE_LENGTH; private static final int DATA_SIZE_LENGTH = INT_LENGTH; + private static final int IS_UNSPENDABLE_LENGTH = BOOLEAN_LENGTH; private static final int EXTRAS_LENGTH = OWNER_LENGTH + NAME_SIZE_LENGTH + DESCRIPTION_SIZE_LENGTH + QUANTITY_LENGTH + IS_DIVISIBLE_LENGTH; @@ -50,6 +51,7 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { layout.add("can asset quantities be fractional?", TransformationType.BOOLEAN); layout.add("asset data length", TransformationType.INT); layout.add("asset data", TransformationType.STRING); + layout.add("are non-owner holders barred from using asset?", TransformationType.BOOLEAN); layout.add("fee", TransformationType.AMOUNT); layout.add("signature", TransformationType.SIGNATURE); } @@ -76,16 +78,18 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { boolean isDivisible = byteBuffer.get() != 0; - // in v2, assets have "data" field - String data = ""; - if (timestamp >= BlockChain.getInstance().getQoraV2Timestamp()) - data = Serialization.deserializeSizedString(byteBuffer, Asset.MAX_DATA_SIZE); - byte[] assetReference = new byte[ASSET_REFERENCE_LENGTH]; - // In v1, IssueAssetTransaction uses Asset.parse which also deserializes - // reference. - if (timestamp < BlockChain.getInstance().getQoraV2Timestamp()) + String data = ""; + boolean isUnspendable = false; + + if (timestamp >= BlockChain.getInstance().getQoraV2Timestamp()) { + // in v2, assets have additional fields + data = Serialization.deserializeSizedString(byteBuffer, Asset.MAX_DATA_SIZE); + isUnspendable = byteBuffer.get() != 0; + } else { + // In v1, IssueAssetTransaction uses Asset.parse which also deserializes reference. byteBuffer.get(assetReference); + } BigDecimal fee = Serialization.deserializeBigDecimal(byteBuffer); @@ -94,7 +98,7 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, issuerPublicKey, fee, signature); - return new IssueAssetTransactionData(baseTransactionData, owner, assetName, description, quantity, isDivisible, data); + return new IssueAssetTransactionData(baseTransactionData, owner, assetName, description, quantity, isDivisible, data, isUnspendable); } public static int getDataLength(TransactionData transactionData) throws TransformationException { @@ -104,14 +108,13 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { + Utf8.encodedLength(issueAssetTransactionData.getAssetName()) + Utf8.encodedLength(issueAssetTransactionData.getDescription()); - // In v2, assets have "data" field - if (transactionData.getTimestamp() >= BlockChain.getInstance().getQoraV2Timestamp()) - dataLength += DATA_SIZE_LENGTH + Utf8.encodedLength(issueAssetTransactionData.getData()); - - // In v1, IssueAssetTransaction uses Asset.toBytes which also serializes - // reference. - if (transactionData.getTimestamp() < BlockChain.getInstance().getQoraV2Timestamp()) + if (transactionData.getTimestamp() >= BlockChain.getInstance().getQoraV2Timestamp()) { + // In v2, assets have additional fields. + dataLength += DATA_SIZE_LENGTH + Utf8.encodedLength(issueAssetTransactionData.getData()) + IS_UNSPENDABLE_LENGTH; + } else { + // In v1, IssueAssetTransaction uses Asset.toBytes which also serializes reference. dataLength += ASSET_REFERENCE_LENGTH; + } return dataLength; } @@ -133,14 +136,14 @@ public class IssueAssetTransactionTransformer extends TransactionTransformer { bytes.write(Longs.toByteArray(issueAssetTransactionData.getQuantity())); bytes.write((byte) (issueAssetTransactionData.getIsDivisible() ? 1 : 0)); - // In v2, assets have "data" - if (transactionData.getTimestamp() >= BlockChain.getInstance().getQoraV2Timestamp()) + // In v2, assets have additional fields. + if (transactionData.getTimestamp() >= BlockChain.getInstance().getQoraV2Timestamp()) { Serialization.serializeSizedString(bytes, issueAssetTransactionData.getData()); - - // In v1, IssueAssetTransaction uses Asset.toBytes which also - // serializes Asset's reference which is the IssueAssetTransaction's - // signature - if (transactionData.getTimestamp() < BlockChain.getInstance().getQoraV2Timestamp()) { + bytes.write((byte) (issueAssetTransactionData.getIsUnspendable() ? 1 : 0)); + } else { + // In v1, IssueAssetTransaction uses Asset.toBytes which also + // serializes Asset's reference which is the IssueAssetTransaction's + // signature byte[] assetReference = issueAssetTransactionData.getSignature(); if (assetReference != null) bytes.write(assetReference); diff --git a/src/main/java/org/qora/transform/transaction/MessageTransactionTransformer.java b/src/main/java/org/qora/transform/transaction/MessageTransactionTransformer.java index a195c210..cd3a0694 100644 --- a/src/main/java/org/qora/transform/transaction/MessageTransactionTransformer.java +++ b/src/main/java/org/qora/transform/transaction/MessageTransactionTransformer.java @@ -68,7 +68,7 @@ public class MessageTransactionTransformer extends TransactionTransformer { long assetId; if (version == 1) - assetId = Asset.QORA; + assetId = Asset.QORT; else assetId = byteBuffer.getLong(); diff --git a/src/test/java/org/qora/test/RepositoryTests.java b/src/test/java/org/qora/test/RepositoryTests.java index 42653d9a..f700b337 100644 --- a/src/test/java/org/qora/test/RepositoryTests.java +++ b/src/test/java/org/qora/test/RepositoryTests.java @@ -78,14 +78,14 @@ public class RepositoryTests extends Common { try (final Repository repository2 = RepositoryManager.getRepository()) { // Update account in 2 Account account2 = Common.getTestAccount(repository2, "alice"); - account2.setConfirmedBalance(Asset.QORA, BigDecimal.valueOf(1234L)); + account2.setConfirmedBalance(Asset.QORT, BigDecimal.valueOf(1234L)); repository2.saveChanges(); } repository1.discardChanges(); // Update account in 1 - account1.setConfirmedBalance(Asset.QORA, BigDecimal.valueOf(5678L)); + account1.setConfirmedBalance(Asset.QORT, BigDecimal.valueOf(5678L)); repository1.saveChanges(); } } diff --git a/src/test/java/org/qora/test/TransactionTests.java b/src/test/java/org/qora/test/TransactionTests.java index f80ecf44..cdc6d61f 100644 --- a/src/test/java/org/qora/test/TransactionTests.java +++ b/src/test/java/org/qora/test/TransactionTests.java @@ -105,18 +105,18 @@ public class TransactionTests extends Common { // Create test generator account generator = new PrivateKeyAccount(repository, generatorSeed); - accountRepository.setLastReference(new AccountData(generator.getAddress(), generatorSeed, generator.getPublicKey(), Group.NO_GROUP, 0, null, 0)); - accountRepository.save(new AccountBalanceData(generator.getAddress(), Asset.QORA, initialGeneratorBalance)); + accountRepository.setLastReference(new AccountData(generator.getAddress(), generatorSeed, generator.getPublicKey(), Group.NO_GROUP, 0, null, 0, 0)); + accountRepository.save(new AccountBalanceData(generator.getAddress(), Asset.QORT, initialGeneratorBalance)); // Create test sender account sender = new PrivateKeyAccount(repository, senderSeed); // Mock account reference = senderSeed; - accountRepository.setLastReference(new AccountData(sender.getAddress(), reference, sender.getPublicKey(), Group.NO_GROUP, 0, null, 0)); + accountRepository.setLastReference(new AccountData(sender.getAddress(), reference, sender.getPublicKey(), Group.NO_GROUP, 0, null, 0, 0)); // Mock balance - accountRepository.save(new AccountBalanceData(sender.getAddress(), Asset.QORA, initialSenderBalance)); + accountRepository.save(new AccountBalanceData(sender.getAddress(), Asset.QORT, initialSenderBalance)); repository.saveChanges(); } @@ -170,17 +170,17 @@ public class TransactionTests extends Common { // Check sender's balance BigDecimal expectedBalance = initialSenderBalance.subtract(amount).subtract(fee); - BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Fee should be in generator's balance expectedBalance = initialGeneratorBalance.add(fee); - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Amount should be in recipient's balance expectedBalance = amount; - actualBalance = accountRepository.getBalance(recipient.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(recipient.getAddress(), Asset.QORT).getBalance(); assertTrue("Recipient's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Check recipient's reference @@ -192,11 +192,11 @@ public class TransactionTests extends Common { repository.saveChanges(); // Check sender's balance - actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's reverted balance incorrect", initialSenderBalance.compareTo(actualBalance) == 0); // Check generator's balance - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's new balance incorrect", initialGeneratorBalance.compareTo(actualBalance) == 0); } @@ -230,12 +230,12 @@ public class TransactionTests extends Common { // Check sender's balance BigDecimal expectedBalance = initialSenderBalance.subtract(fee); - BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Fee should be in generator's balance expectedBalance = initialGeneratorBalance.add(fee); - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Check name was registered @@ -494,12 +494,12 @@ public class TransactionTests extends Common { // Check sender's balance BigDecimal expectedBalance = initialSenderBalance.subtract(fee); - BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Fee should be in generator's balance expectedBalance = initialGeneratorBalance.add(fee); - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Check poll was created @@ -598,9 +598,10 @@ public class TransactionTests extends Common { BigDecimal fee = BigDecimal.ONE; long timestamp = parentBlockData.getTimestamp() + 1_000; String data = (timestamp >= BlockChain.getInstance().getQoraV2Timestamp()) ? "{}" : null; + boolean isUnspendable = false; BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, sender.getPublicKey(), fee, null); - IssueAssetTransactionData issueAssetTransactionData = new IssueAssetTransactionData(baseTransactionData, sender.getAddress(), assetName, description, quantity, isDivisible, data); + IssueAssetTransactionData issueAssetTransactionData = new IssueAssetTransactionData(baseTransactionData, sender.getAddress(), assetName, description, quantity, isDivisible, data, isUnspendable); Transaction issueAssetTransaction = new IssueAssetTransaction(repository, issueAssetTransactionData); issueAssetTransaction.sign(sender); @@ -618,19 +619,19 @@ public class TransactionTests extends Common { // Check sender's balance BigDecimal expectedBalance = initialSenderBalance.subtract(fee); - BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Fee should be in generator's balance expectedBalance = initialGeneratorBalance.add(fee); - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Check we now have an assetId Long assetId = issueAssetTransactionData.getAssetId(); assertNotNull(assetId); // Should NOT collide with Asset.QORA - assertFalse(assetId == Asset.QORA); + assertFalse(assetId == Asset.QORT); // Check asset now exists AssetRepository assetRepo = this.repository.getAssetRepository(); @@ -647,11 +648,11 @@ public class TransactionTests extends Common { repository.saveChanges(); // Check sender's balance - actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's reverted balance incorrect", initialSenderBalance.compareTo(actualBalance) == 0); // Check generator's balance - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's reverted balance incorrect", initialGeneratorBalance.compareTo(actualBalance) == 0); // Check asset no longer exists @@ -678,8 +679,8 @@ public class TransactionTests extends Common { AssetRepository assetRepo = this.repository.getAssetRepository(); AssetData originalAssetData = assetRepo.fromAssetName(assetName); long assetId = originalAssetData.getAssetId(); - BigDecimal originalSenderBalance = sender.getConfirmedBalance(Asset.QORA); - BigDecimal originalGeneratorBalance = generator.getConfirmedBalance(Asset.QORA); + BigDecimal originalSenderBalance = sender.getConfirmedBalance(Asset.QORT); + BigDecimal originalGeneratorBalance = generator.getConfirmedBalance(Asset.QORT); // Transfer asset to new recipient Account recipient = new PublicKeyAccount(repository, recipientSeed); @@ -706,12 +707,12 @@ public class TransactionTests extends Common { // Check sender's balance BigDecimal expectedBalance = originalSenderBalance.subtract(fee); - BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Fee should be in generator's balance expectedBalance = originalGeneratorBalance.add(fee); - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Check asset balances @@ -729,11 +730,11 @@ public class TransactionTests extends Common { repository.saveChanges(); // Check sender's balance - actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's reverted balance incorrect", originalSenderBalance.compareTo(actualBalance) == 0); // Check generator's balance - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's reverted balance incorrect", originalGeneratorBalance.compareTo(actualBalance) == 0); // Check asset balances @@ -781,7 +782,7 @@ public class TransactionTests extends Common { parentBlockData = block.getBlockData(); // Order: buyer has 10 QORA and wants to buy "test asset" at a price of 50 "test asset" per QORA. - long haveAssetId = Asset.QORA; + long haveAssetId = Asset.QORT; BigDecimal amount = BigDecimal.valueOf(10).setScale(8); long wantAssetId = assetId; BigDecimal price = BigDecimal.valueOf(50).setScale(8); @@ -852,7 +853,7 @@ public class TransactionTests extends Common { PrivateKeyAccount buyer = new PrivateKeyAccount(repository, recipientSeed); // Fetch orders - long haveAssetId = Asset.QORA; + long haveAssetId = Asset.QORT; long wantAssetId = assetId; List orders = assetRepo.getOpenOrders(haveAssetId, wantAssetId); @@ -917,7 +918,7 @@ public class TransactionTests extends Common { PrivateKeyAccount buyer = new PrivateKeyAccount(repository, recipientSeed); // Fetch orders - long originalHaveAssetId = Asset.QORA; + long originalHaveAssetId = Asset.QORT; long originalWantAssetId = assetId; List orders = assetRepo.getOpenOrders(originalHaveAssetId, originalWantAssetId); @@ -937,7 +938,7 @@ public class TransactionTests extends Common { // This order should be a partial match for original order, and at a better price than asked long haveAssetId = assetId; BigDecimal amount = BigDecimal.valueOf(40).setScale(8); - long wantAssetId = Asset.QORA; + long wantAssetId = Asset.QORT; BigDecimal price = BigDecimal.ONE.setScale(8).divide(BigDecimal.valueOf(60).setScale(8), RoundingMode.DOWN); BigDecimal fee = BigDecimal.ONE; long timestamp = parentBlockData.getTimestamp() + 1_000; @@ -1041,7 +1042,7 @@ public class TransactionTests extends Common { byte[] seed = recipientSeed.clone(); seed[0] += i; Account recipient = new PublicKeyAccount(repository, seed); - long assetId = Asset.QORA; + long assetId = Asset.QORT; BigDecimal amount = BigDecimal.valueOf(1_000L + i).setScale(8); expectedSenderBalance = expectedSenderBalance.subtract(amount); @@ -1069,12 +1070,12 @@ public class TransactionTests extends Common { repository.saveChanges(); // Check sender's balance - BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's new balance incorrect", expectedSenderBalance.compareTo(actualBalance) == 0); // Fee should be in generator's balance BigDecimal expectedBalance = initialGeneratorBalance.add(fee); - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Check recipients @@ -1087,7 +1088,7 @@ public class TransactionTests extends Common { // Amount should be in recipient's balance expectedBalance = paymentData.getAmount(); - actualBalance = accountRepository.getBalance(recipient.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(recipient.getAddress(), Asset.QORT).getBalance(); assertTrue("Recipient's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); } @@ -1097,11 +1098,11 @@ public class TransactionTests extends Common { repository.saveChanges(); // Check sender's balance - actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's reverted balance incorrect", initialSenderBalance.compareTo(actualBalance) == 0); // Check generator's balance - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's new balance incorrect", initialGeneratorBalance.compareTo(actualBalance) == 0); } @@ -1121,7 +1122,7 @@ public class TransactionTests extends Common { BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, sender.getPublicKey(), fee, null); MessageTransactionData messageTransactionData = new MessageTransactionData(baseTransactionData, version, - recipient.getAddress(), Asset.QORA, amount, data, isText, isEncrypted); + recipient.getAddress(), Asset.QORT, amount, data, isText, isEncrypted); Transaction messageTransaction = new MessageTransaction(repository, messageTransactionData); messageTransaction.sign(sender); @@ -1139,17 +1140,17 @@ public class TransactionTests extends Common { // Check sender's balance BigDecimal expectedBalance = initialSenderBalance.subtract(amount).subtract(fee); - BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance(); + BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORT).getBalance(); assertTrue("Sender's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Fee should be in generator's balance expectedBalance = initialGeneratorBalance.add(fee); - actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORT).getBalance(); assertTrue("Generator's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); // Amount should be in recipient's balance expectedBalance = amount; - actualBalance = accountRepository.getBalance(recipient.getAddress(), Asset.QORA).getBalance(); + actualBalance = accountRepository.getBalance(recipient.getAddress(), Asset.QORT).getBalance(); assertTrue("Recipient's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0); } diff --git a/src/test/java/org/qora/test/common/AssetUtils.java b/src/test/java/org/qora/test/common/AssetUtils.java index dabaf68f..fc40afa9 100644 --- a/src/test/java/org/qora/test/common/AssetUtils.java +++ b/src/test/java/org/qora/test/common/AssetUtils.java @@ -39,7 +39,7 @@ public class AssetUtils { long timestamp = repository.getTransactionRepository().fromSignature(reference).getTimestamp() + 1; BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, AssetUtils.txGroupId, reference, account.getPublicKey(), AssetUtils.fee, null); - TransactionData transactionData = new IssueAssetTransactionData(baseTransactionData, account.getAddress(), assetName, "desc", quantity, isDivisible, "{}"); + TransactionData transactionData = new IssueAssetTransactionData(baseTransactionData, account.getAddress(), assetName, "desc", quantity, isDivisible, "{}", false); TransactionUtils.signAndForge(repository, transactionData, account); diff --git a/src/test/java/org/qora/test/common/transaction/ArbitraryTestTransaction.java b/src/test/java/org/qora/test/common/transaction/ArbitraryTestTransaction.java index abb37648..3ada2849 100644 --- a/src/test/java/org/qora/test/common/transaction/ArbitraryTestTransaction.java +++ b/src/test/java/org/qora/test/common/transaction/ArbitraryTestTransaction.java @@ -25,7 +25,7 @@ public class ArbitraryTestTransaction extends TestTransaction { DataType dataType = DataType.RAW_DATA; String recipient = account.getAddress(); - final long assetId = Asset.QORA; + final long assetId = Asset.QORT; BigDecimal amount = BigDecimal.valueOf(123L); List payments = new ArrayList<>(); diff --git a/src/test/java/org/qora/test/common/transaction/AtTestTransaction.java b/src/test/java/org/qora/test/common/transaction/AtTestTransaction.java index e1b5d106..b5ceba18 100644 --- a/src/test/java/org/qora/test/common/transaction/AtTestTransaction.java +++ b/src/test/java/org/qora/test/common/transaction/AtTestTransaction.java @@ -18,7 +18,7 @@ public class AtTestTransaction extends TestTransaction { String atAddress = Crypto.toATAddress(signature); String recipient = account.getAddress(); BigDecimal amount = BigDecimal.valueOf(123); - final long assetId = Asset.QORA; + final long assetId = Asset.QORT; byte[] message = new byte[32]; random.nextBytes(message); diff --git a/src/test/java/org/qora/test/common/transaction/CreateAssetOrderTestTransaction.java b/src/test/java/org/qora/test/common/transaction/CreateAssetOrderTestTransaction.java index f1085d83..dc3911b5 100644 --- a/src/test/java/org/qora/test/common/transaction/CreateAssetOrderTestTransaction.java +++ b/src/test/java/org/qora/test/common/transaction/CreateAssetOrderTestTransaction.java @@ -12,7 +12,7 @@ import org.qora.repository.Repository; public class CreateAssetOrderTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { - final long haveAssetId = Asset.QORA; + final long haveAssetId = Asset.QORT; final long wantAssetId = 1; BigDecimal amount = BigDecimal.valueOf(123); BigDecimal price = BigDecimal.valueOf(123); diff --git a/src/test/java/org/qora/test/common/transaction/DeployAtTestTransaction.java b/src/test/java/org/qora/test/common/transaction/DeployAtTestTransaction.java index de5807e0..34e25389 100644 --- a/src/test/java/org/qora/test/common/transaction/DeployAtTestTransaction.java +++ b/src/test/java/org/qora/test/common/transaction/DeployAtTestTransaction.java @@ -22,7 +22,7 @@ public class DeployAtTestTransaction extends TestTransaction { byte[] creationBytes = new byte[1024]; random.nextBytes(creationBytes); BigDecimal amount = BigDecimal.valueOf(123); - final long assetId = Asset.QORA; + final long assetId = Asset.QORT; return new DeployAtTransactionData(generateBase(account), name, description, atType, tags, creationBytes, amount, assetId); } diff --git a/src/test/java/org/qora/test/common/transaction/IssueAssetTestTransaction.java b/src/test/java/org/qora/test/common/transaction/IssueAssetTestTransaction.java index 3d3c6537..1347d130 100644 --- a/src/test/java/org/qora/test/common/transaction/IssueAssetTestTransaction.java +++ b/src/test/java/org/qora/test/common/transaction/IssueAssetTestTransaction.java @@ -20,8 +20,9 @@ public class IssueAssetTestTransaction extends TestTransaction { final long quantity = 1_000_000L; final boolean isDivisible = true; String data = AssetUtils.randomData(); + final boolean isUnspendable = false; - return new IssueAssetTransactionData(generateBase(account), owner, assetName, description, quantity, isDivisible, data); + return new IssueAssetTransactionData(generateBase(account), owner, assetName, description, quantity, isDivisible, data, isUnspendable); } } diff --git a/src/test/java/org/qora/test/common/transaction/MessageTestTransaction.java b/src/test/java/org/qora/test/common/transaction/MessageTestTransaction.java index dabd983b..64a8c3eb 100644 --- a/src/test/java/org/qora/test/common/transaction/MessageTestTransaction.java +++ b/src/test/java/org/qora/test/common/transaction/MessageTestTransaction.java @@ -14,7 +14,7 @@ public class MessageTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { final int version = 3; String recipient = account.getAddress(); - final long assetId = Asset.QORA; + final long assetId = Asset.QORT; BigDecimal amount = BigDecimal.valueOf(123L); byte[] data = "message contents".getBytes(); final boolean isText = true; diff --git a/src/test/java/org/qora/test/common/transaction/MultiPaymentTestTransaction.java b/src/test/java/org/qora/test/common/transaction/MultiPaymentTestTransaction.java index c57de8a0..46e80487 100644 --- a/src/test/java/org/qora/test/common/transaction/MultiPaymentTestTransaction.java +++ b/src/test/java/org/qora/test/common/transaction/MultiPaymentTestTransaction.java @@ -16,7 +16,7 @@ public class MultiPaymentTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { String recipient = account.getAddress(); - final long assetId = Asset.QORA; + final long assetId = Asset.QORT; BigDecimal amount = BigDecimal.valueOf(123L); List payments = new ArrayList<>(); diff --git a/src/test/java/org/qora/test/common/transaction/TransferAssetTestTransaction.java b/src/test/java/org/qora/test/common/transaction/TransferAssetTestTransaction.java index d7e52530..879c35fe 100644 --- a/src/test/java/org/qora/test/common/transaction/TransferAssetTestTransaction.java +++ b/src/test/java/org/qora/test/common/transaction/TransferAssetTestTransaction.java @@ -13,7 +13,7 @@ public class TransferAssetTestTransaction extends TestTransaction { public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException { String recipient = account.getAddress(); - final long assetId = Asset.QORA; + final long assetId = Asset.QORT; BigDecimal amount = BigDecimal.valueOf(123); return new TransferAssetTransactionData(generateBase(account), recipient, amount, assetId); diff --git a/src/test/java/org/qora/test/forging/RewardTests.java b/src/test/java/org/qora/test/forging/RewardTests.java index c9704307..a78fc750 100644 --- a/src/test/java/org/qora/test/forging/RewardTests.java +++ b/src/test/java/org/qora/test/forging/RewardTests.java @@ -35,7 +35,7 @@ public class RewardTests extends Common { @Test public void testSimpleReward() throws DataException { try (final Repository repository = RepositoryManager.getRepository()) { - Map> initialBalances = AccountUtils.getBalances(repository, Asset.QORA); + Map> initialBalances = AccountUtils.getBalances(repository, Asset.QORT); PrivateKeyAccount forgingAccount = Common.getTestAccount(repository, "alice"); @@ -43,15 +43,15 @@ public class RewardTests extends Common { BlockGenerator.generateTestingBlock(repository, forgingAccount); - BigDecimal expectedBalance = initialBalances.get("alice").get(Asset.QORA).add(blockReward); - AccountUtils.assertBalance(repository, "alice", Asset.QORA, expectedBalance); + BigDecimal expectedBalance = initialBalances.get("alice").get(Asset.QORT).add(blockReward); + AccountUtils.assertBalance(repository, "alice", Asset.QORT, expectedBalance); } } @Test public void testRewards() throws DataException { try (final Repository repository = RepositoryManager.getRepository()) { - Map> initialBalances = AccountUtils.getBalances(repository, Asset.QORA); + Map> initialBalances = AccountUtils.getBalances(repository, Asset.QORT); PrivateKeyAccount forgingAccount = Common.getTestAccount(repository, "alice"); @@ -60,7 +60,7 @@ public class RewardTests extends Common { int rewardIndex = rewards.size() - 1; RewardByHeight rewardInfo = rewards.get(rewardIndex); - BigDecimal expectedBalance = initialBalances.get("alice").get(Asset.QORA); + BigDecimal expectedBalance = initialBalances.get("alice").get(Asset.QORT); for (int height = rewardInfo.height; height > 1; --height) { if (height < rewardInfo.height) { @@ -72,7 +72,7 @@ public class RewardTests extends Common { expectedBalance = expectedBalance.add(rewardInfo.reward); } - AccountUtils.assertBalance(repository, "alice", Asset.QORA, expectedBalance); + AccountUtils.assertBalance(repository, "alice", Asset.QORT, expectedBalance); } } @@ -84,17 +84,17 @@ public class RewardTests extends Common { byte[] proxyPrivateKey = AccountUtils.proxyForging(repository, "alice", "bob", share); PrivateKeyAccount proxyAccount = new PrivateKeyAccount(repository, proxyPrivateKey); - Map> initialBalances = AccountUtils.getBalances(repository, Asset.QORA); + Map> initialBalances = AccountUtils.getBalances(repository, Asset.QORT); BigDecimal blockReward = BlockUtils.getNextBlockReward(repository); BlockGenerator.generateTestingBlock(repository, proxyAccount); // We're expecting reward * 12.8% to Bob, the rest to Alice BigDecimal bobShare = blockReward.multiply(share.movePointLeft(2)).setScale(8, RoundingMode.DOWN); - AccountUtils.assertBalance(repository, "bob", Asset.QORA, initialBalances.get("bob").get(Asset.QORA).add(bobShare)); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, initialBalances.get("bob").get(Asset.QORT).add(bobShare)); BigDecimal aliceShare = blockReward.subtract(bobShare); - AccountUtils.assertBalance(repository, "alice", Asset.QORA, initialBalances.get("alice").get(Asset.QORA).add(aliceShare)); + AccountUtils.assertBalance(repository, "alice", Asset.QORT, initialBalances.get("alice").get(Asset.QORT).add(aliceShare)); } } diff --git a/src/test/java/org/qora/test/group/GroupApprovalTests.java b/src/test/java/org/qora/test/group/GroupApprovalTests.java index fc7ead27..0d0ca29a 100644 --- a/src/test/java/org/qora/test/group/GroupApprovalTests.java +++ b/src/test/java/org/qora/test/group/GroupApprovalTests.java @@ -90,8 +90,8 @@ public class GroupApprovalTests extends Common { PrivateKeyAccount bobAccount = Common.getTestAccount(repository, "bob"); byte[] bobOriginalReference = bobAccount.getLastReference(); - BigDecimal aliceOriginalBalance = aliceAccount.getConfirmedBalance(Asset.QORA); - BigDecimal bobOriginalBalance = bobAccount.getConfirmedBalance(Asset.QORA); + BigDecimal aliceOriginalBalance = aliceAccount.getConfirmedBalance(Asset.QORT); + BigDecimal bobOriginalBalance = bobAccount.getConfirmedBalance(Asset.QORT); BigDecimal blockReward = BlockUtils.getNextBlockReward(repository); Transaction bobAssetTransaction = buildIssueAssetTransaction(repository, "bob", groupId); @@ -106,11 +106,11 @@ public class GroupApprovalTests extends Common { assertFalse("reference should have changed", Arrays.equals(bobOriginalReference, bobPostAssetReference)); // Bob's balance should have the fee removed, even though the transaction itself hasn't been approved yet - BigDecimal bobPostAssetBalance = bobAccount.getConfirmedBalance(Asset.QORA); + BigDecimal bobPostAssetBalance = bobAccount.getConfirmedBalance(Asset.QORT); Common.assertEqualBigDecimals("approval-pending transaction creator's balance incorrect", bobOriginalBalance.subtract(fee), bobPostAssetBalance); // Transaction fee should have ended up in forging account - BigDecimal alicePostAssetBalance = aliceAccount.getConfirmedBalance(Asset.QORA); + BigDecimal alicePostAssetBalance = aliceAccount.getConfirmedBalance(Asset.QORT); Common.assertEqualBigDecimals("block forger's balance incorrect", aliceOriginalBalance.add(blockReward).add(fee), alicePostAssetBalance); // Have Bob do a non-approval transaction to change his last-reference @@ -167,7 +167,7 @@ public class GroupApprovalTests extends Common { assertTrue("reference should be pre-payment", Arrays.equals(bobOriginalReference, bobReference)); // Also check Bob's balance is back to original value - BigDecimal bobBalance = bobAccount.getConfirmedBalance(Asset.QORA); + BigDecimal bobBalance = bobAccount.getConfirmedBalance(Asset.QORT); Common.assertEqualBigDecimals("reverted balance doesn't match original", bobOriginalBalance, bobBalance); } } @@ -438,7 +438,7 @@ public class GroupApprovalTests extends Common { long timestamp = repository.getTransactionRepository().fromSignature(reference).getTimestamp() + 1; BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, account.getPublicKey(), fee, null); - TransactionData transactionData = new IssueAssetTransactionData(baseTransactionData, account.getAddress(), "test asset", "test asset desc", 1000L, true, "{}"); + TransactionData transactionData = new IssueAssetTransactionData(baseTransactionData, account.getAddress(), "test asset", "test asset desc", 1000L, true, "{}", false); return Transaction.fromData(repository, transactionData); }