Massive conversion from BigDecimal to long.

Now possible thanks to removing Qora v1 support.

Maximum asset quantities now unified to 10_000_000_000,
to 8 decimal places, removing prior 10 billion billion
indivisible maximum.

All values can now fit into a 64bit long.
(Except maybe when processing asset trades).

Added a general-use JAXB AmountTypeAdapter for converting
amounts to/from String/long.

Asset trading engine split into more methods for easier
readability.

Switched to using FIXED founder block reward distribution code,
ready for launch.

In HSQLDBDatabaseUpdates,
QortalAmount changed from DECIMAL(27, 0) to BIGINT
RewardSharePercent added to replace DECIMAL(5,2) with INT

Ripped out unused Transaction.isInvolved and Transaction.getAmount
in all subclasses.

Changed
  Transaction.getRecipientAccounts() : List<Account>
to
  Transaction.getRecipientAddresses() : List<String>
as only addresses are ever used.

Corrected returned values for above getRecipientAddresses() for
some transaction subclasses.

Added some account caching to some transactions to reduce repeated
loads during validation and then processing.

Transaction transformers:

Changed serialization of asset amounts from using 12 bytes to
now standard 8 byte long.

Updated transaction 'layouts' to reflect new sizes.

RewardShareTransactionTransformer still uses 8byte long to represent
reward share percent.

Updated some unit tests - more work needed!
This commit is contained in:
catbref
2020-04-29 17:30:25 +01:00
parent 0006911e0a
commit 9eaf31707a
150 changed files with 1795 additions and 2767 deletions

View File

@@ -2,7 +2,6 @@ package org.qortal.test;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -48,18 +47,18 @@ public class AccountBalanceTests extends Common {
}
}
private BigDecimal testNewerBalance(Repository repository, TestAccount testAccount) throws DataException {
private long testNewerBalance(Repository repository, TestAccount testAccount) throws DataException {
// Grab initial balance
BigDecimal initialBalance = testAccount.getConfirmedBalance(Asset.QORT);
long initialBalance = testAccount.getConfirmedBalance(Asset.QORT);
// Mint block to cause newer balance
BlockUtils.mintBlock(repository);
// Grab newer balance
BigDecimal newerBalance = testAccount.getConfirmedBalance(Asset.QORT);
long newerBalance = testAccount.getConfirmedBalance(Asset.QORT);
// Confirm newer balance is greater than initial balance
assertTrue("Newer balance should be greater than initial balance", newerBalance.compareTo(initialBalance) > 0);
assertTrue("Newer balance should be greater than initial balance", newerBalance > initialBalance);
return initialBalance;
}
@@ -70,15 +69,15 @@ public class AccountBalanceTests extends Common {
try (final Repository repository = RepositoryManager.getRepository()) {
TestAccount alice = Common.getTestAccount(repository, "alice");
BigDecimal initialBalance = testNewerBalance(repository, alice);
long initialBalance = testNewerBalance(repository, alice);
BlockUtils.orphanLastBlock(repository);
// Grab post-orphan balance
BigDecimal orphanedBalance = alice.getConfirmedBalance(Asset.QORT);
long orphanedBalance = alice.getConfirmedBalance(Asset.QORT);
// Confirm post-orphan balance is same as initial
assertEqualBigDecimals("Post-orphan balance should match initial", initialBalance, orphanedBalance);
assertEquals("Post-orphan balance should match initial", initialBalance, orphanedBalance);
}
}
@@ -111,7 +110,7 @@ public class AccountBalanceTests extends Common {
for (int i = 0; i < 100000; ++i) {
Account account = accounts.get(random.nextInt(accounts.size()));
int assetId = random.nextInt(2);
BigDecimal balance = BigDecimal.valueOf(random.nextInt(100000));
long balance = random.nextInt(100000);
AccountBalanceData accountBalanceData = new AccountBalanceData(account.getAddress(), assetId, balance);
repository.getAccountRepository().save(accountBalanceData);

View File

@@ -2,7 +2,6 @@ package org.qortal.test;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Random;
@@ -247,7 +246,7 @@ public class AccountRefCacheTests extends Common {
// Test Block support
@Test
public void testBlockSupport() throws DataException {
final BigDecimal amount = BigDecimal.valueOf(12345670000L, 8);
final long amount = 12345670000L;
try (final Repository repository = RepositoryManager.getRepository()) {
TestAccount alice = Common.getTestAccount(repository, "alice");

View File

@@ -1,6 +1,5 @@
package org.qortal.test;
import java.math.BigDecimal;
import java.util.List;
import org.junit.Before;
@@ -56,7 +55,7 @@ public class BlockTests extends Common {
if (transactionData.getType() != Transaction.TransactionType.GENESIS)
continue;
assertTrue(transactionData.getFee().compareTo(BigDecimal.ZERO) == 0);
assertEquals(0L, (long) transactionData.getFee());
assertTrue(transaction.isSignatureValid());
assertEquals(Transaction.ValidationResult.OK, transaction.isValid());
@@ -68,7 +67,7 @@ public class BlockTests extends Common {
assertNotNull(transactionData);
assertEquals(Transaction.TransactionType.GENESIS, transactionData.getType());
assertTrue(transactionData.getFee().compareTo(BigDecimal.ZERO) == 0);
assertEquals(0L, (long) transactionData.getFee());
// assertNull(transactionData.getReference());
Transaction transaction = Transaction.fromData(repository, transactionData);

View File

@@ -13,7 +13,6 @@ import org.qortal.test.common.Common;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -84,14 +83,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.QORT, BigDecimal.valueOf(1234L));
account2.setConfirmedBalance(Asset.QORT, 1234L);
repository2.saveChanges();
}
repository1.discardChanges();
// Update account in 1
account1.setConfirmedBalance(Asset.QORT, BigDecimal.valueOf(5678L));
account1.setConfirmedBalance(Asset.QORT, 5678L);
repository1.saveChanges();
}
}

View File

@@ -24,7 +24,6 @@ import org.qortal.transform.Transformer;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.util.List;
import java.util.Random;
@@ -166,11 +165,11 @@ public class TransferPrivsTests extends Common {
public void testMultipleIntoChloeTransferPrivs() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
// Alice needs to mint block containing REWARD_SHARE BEFORE Alice loses minting privs
byte[] aliceChloeRewardSharePrivateKey = AccountUtils.rewardShare(repository, "alice", "chloe", BigDecimal.ZERO); // Block minted by Alice
byte[] aliceChloeRewardSharePrivateKey = AccountUtils.rewardShare(repository, "alice", "chloe", 0); // Block minted by Alice
PrivateKeyAccount aliceChloeRewardShareAccount = new PrivateKeyAccount(repository, aliceChloeRewardSharePrivateKey);
// Alice needs to mint block containing REWARD_SHARE BEFORE Alice loses minting privs
byte[] dilbertRewardSharePrivateKey = AccountUtils.rewardShare(repository, "dilbert", "dilbert", BigDecimal.ZERO); // Block minted by Alice
byte[] dilbertRewardSharePrivateKey = AccountUtils.rewardShare(repository, "dilbert", "dilbert", 0); // Block minted by Alice
PrivateKeyAccount dilbertRewardShareAccount = new PrivateKeyAccount(repository, dilbertRewardSharePrivateKey);
TestAccount alice = Common.getTestAccount(repository, "alice");
@@ -281,7 +280,7 @@ public class TransferPrivsTests extends Common {
byte[] reference = senderAccount.getLastReference();
long timestamp = repository.getTransactionRepository().fromSignature(reference).getTimestamp() + 1;
int txGroupId = 0;
BigDecimal fee = BigDecimal.ONE.setScale(8);
long fee = 1L;
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, senderAccount.getPublicKey(), fee, null);
TransactionData transactionData = new TransferPrivsTransactionData(baseTransactionData, recipientAccount.getAddress());

View File

@@ -76,9 +76,10 @@ public class GranularityTests extends Common {
}
private void testGranularity(boolean isAmountAssetDivisible, boolean isReturnAssetDivisible, String dividend, String divisor, String expectedGranularity) {
final BigDecimal price = new BigDecimal(dividend).setScale(8).divide(new BigDecimal(divisor).setScale(8), RoundingMode.DOWN);
BigDecimal bdPrice = new BigDecimal(dividend).setScale(8).divide(new BigDecimal(divisor).setScale(8), RoundingMode.DOWN);
long price = bdPrice.unscaledValue().longValue();
BigDecimal granularity = Order.calculateAmountGranularity(isAmountAssetDivisible, isReturnAssetDivisible, price);
BigDecimal granularity = BigDecimal.valueOf(Order.calculateAmountGranularity(isAmountAssetDivisible, isReturnAssetDivisible, price), 8);
assertEqualBigDecimals("Granularity incorrect", new BigDecimal(expectedGranularity), granularity);
}

View File

@@ -1,6 +1,7 @@
package org.qortal.test.common;
import java.math.BigDecimal;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
@@ -16,9 +17,9 @@ import org.qortal.repository.Repository;
public class AccountUtils {
public static final int txGroupId = Group.NO_GROUP;
public static final BigDecimal fee = BigDecimal.ONE.setScale(8);
public static final long fee = 1L;
public static void pay(Repository repository, String sender, String recipient, BigDecimal amount) throws DataException {
public static void pay(Repository repository, String sender, String recipient, long amount) throws DataException {
PrivateKeyAccount sendingAccount = Common.getTestAccount(repository, sender);
PrivateKeyAccount recipientAccount = Common.getTestAccount(repository, recipient);
@@ -31,7 +32,7 @@ public class AccountUtils {
TransactionUtils.signAndMint(repository, transactionData, sendingAccount);
}
public static TransactionData createRewardShare(Repository repository, String minter, String recipient, BigDecimal sharePercent) throws DataException {
public static TransactionData createRewardShare(Repository repository, String minter, String recipient, int sharePercent) throws DataException {
PrivateKeyAccount mintingAccount = Common.getTestAccount(repository, minter);
PrivateKeyAccount recipientAccount = Common.getTestAccount(repository, recipient);
@@ -47,7 +48,7 @@ public class AccountUtils {
return transactionData;
}
public static byte[] rewardShare(Repository repository, String minter, String recipient, BigDecimal sharePercent) throws DataException {
public static byte[] rewardShare(Repository repository, String minter, String recipient, int sharePercent) throws DataException {
TransactionData transactionData = createRewardShare(repository, minter, recipient, sharePercent);
PrivateKeyAccount rewardShareAccount = Common.getTestAccount(repository, minter);
@@ -59,16 +60,16 @@ public class AccountUtils {
return rewardSharePrivateKey;
}
public static Map<String, Map<Long, BigDecimal>> getBalances(Repository repository, long... assetIds) throws DataException {
Map<String, Map<Long, BigDecimal>> balances = new HashMap<>();
public static Map<String, Map<Long, Long>> getBalances(Repository repository, long... assetIds) throws DataException {
Map<String, Map<Long, Long>> balances = new HashMap<>();
for (TestAccount account : Common.getTestAccounts(repository))
for (Long assetId : assetIds) {
BigDecimal balance = account.getConfirmedBalance(assetId);
long balance = account.getConfirmedBalance(assetId);
balances.compute(account.accountName, (key, value) -> {
if (value == null)
value = new HashMap<Long, BigDecimal>();
value = new HashMap<Long, Long>();
value.put(assetId, balance);
@@ -79,15 +80,15 @@ public class AccountUtils {
return balances;
}
public static BigDecimal getBalance(Repository repository, String accountName, long assetId) throws DataException {
public static long getBalance(Repository repository, String accountName, long assetId) throws DataException {
return Common.getTestAccount(repository, accountName).getConfirmedBalance(assetId);
}
public static void assertBalance(Repository repository, String accountName, long assetId, BigDecimal expectedBalance) throws DataException {
BigDecimal actualBalance = getBalance(repository, accountName, assetId);
public static void assertBalance(Repository repository, String accountName, long assetId, long expectedBalance) throws DataException {
long actualBalance = getBalance(repository, accountName, assetId);
String assetName = repository.getAssetRepository().fromAssetId(assetId).getName();
Common.assertEqualBigDecimals(String.format("%s's %s [%d] balance incorrect", accountName, assetName, assetId), expectedBalance, actualBalance);
assertEquals(String.format("%s's %s [%d] balance incorrect", accountName, assetName, assetId), expectedBalance, actualBalance);
}
}

View File

@@ -1,8 +1,8 @@
package org.qortal.test.common;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.math.BigDecimal;
import java.util.Base64;
import java.util.Base64.Encoder;
@@ -26,7 +26,7 @@ import java.util.Random;
public class AssetUtils {
public static final int txGroupId = Group.NO_GROUP;
public static final BigDecimal fee = BigDecimal.ONE.setScale(8);
public static final long fee = 1L;
// QORT: 0, LEGACY_QORA: 1, QORT_FROM_QORA: 2
public static final long testAssetId = 3L; // Owned by Alice
@@ -47,7 +47,7 @@ public class AssetUtils {
return repository.getAssetRepository().fromAssetName(assetName).getAssetId();
}
public static void transferAsset(Repository repository, String fromAccountName, String toAccountName, long assetId, BigDecimal amount) throws DataException {
public static void transferAsset(Repository repository, String fromAccountName, String toAccountName, long assetId, long amount) throws DataException {
PrivateKeyAccount fromAccount = Common.getTestAccount(repository, fromAccountName);
PrivateKeyAccount toAccount = Common.getTestAccount(repository, toAccountName);
@@ -60,7 +60,7 @@ public class AssetUtils {
TransactionUtils.signAndMint(repository, transactionData, fromAccount);
}
public static byte[] createOrder(Repository repository, String accountName, long haveAssetId, long wantAssetId, BigDecimal amount, BigDecimal price) throws DataException {
public static byte[] createOrder(Repository repository, String accountName, long haveAssetId, long wantAssetId, long amount, long price) throws DataException {
PrivateKeyAccount account = Common.getTestAccount(repository, accountName);
byte[] reference = account.getLastReference();
@@ -94,12 +94,12 @@ public class AssetUtils {
}
public static void genericTradeTest(long haveAssetId, long wantAssetId,
BigDecimal aliceAmount, BigDecimal alicePrice,
BigDecimal bobAmount, BigDecimal bobPrice,
BigDecimal aliceCommitment, BigDecimal bobCommitment,
BigDecimal aliceReturn, BigDecimal bobReturn, BigDecimal bobSaving) throws DataException {
long aliceAmount, long alicePrice,
long bobAmount, long bobPrice,
long aliceCommitment, long bobCommitment,
long aliceReturn, long bobReturn, long bobSaving) throws DataException {
try (Repository repository = RepositoryManager.getRepository()) {
Map<String, Map<Long, BigDecimal>> initialBalances = AccountUtils.getBalances(repository, haveAssetId, wantAssetId);
Map<String, Map<Long, Long>> initialBalances = AccountUtils.getBalances(repository, haveAssetId, wantAssetId);
// Create target order
byte[] targetOrderId = createOrder(repository, "alice", haveAssetId, wantAssetId, aliceAmount, alicePrice);
@@ -108,36 +108,36 @@ public class AssetUtils {
byte[] initiatingOrderId = createOrder(repository, "bob", wantAssetId, haveAssetId, bobAmount, bobPrice);
// Check balances to check expected outcome
BigDecimal expectedBalance;
long expectedBalance;
OrderData targetOrderData = repository.getAssetRepository().fromOrderId(targetOrderId);
OrderData initiatingOrderData = repository.getAssetRepository().fromOrderId(initiatingOrderId);
// Alice selling have asset
expectedBalance = initialBalances.get("alice").get(haveAssetId).subtract(aliceCommitment);
expectedBalance = initialBalances.get("alice").get(haveAssetId) - aliceCommitment;
AccountUtils.assertBalance(repository, "alice", haveAssetId, expectedBalance);
// Alice buying want asset
expectedBalance = initialBalances.get("alice").get(wantAssetId).add(aliceReturn);
expectedBalance = initialBalances.get("alice").get(wantAssetId) + aliceReturn;
AccountUtils.assertBalance(repository, "alice", wantAssetId, expectedBalance);
// Bob selling want asset
expectedBalance = initialBalances.get("bob").get(wantAssetId).subtract(bobCommitment).add(bobSaving);
expectedBalance = initialBalances.get("bob").get(wantAssetId) - bobCommitment + bobSaving;
AccountUtils.assertBalance(repository, "bob", wantAssetId, expectedBalance);
// Bob buying have asset
expectedBalance = initialBalances.get("bob").get(haveAssetId).add(bobReturn);
expectedBalance = initialBalances.get("bob").get(haveAssetId) + bobReturn;
AccountUtils.assertBalance(repository, "bob", haveAssetId, expectedBalance);
// Check orders
BigDecimal expectedFulfilled = (initiatingOrderData.getHaveAssetId() < initiatingOrderData.getWantAssetId()) ? bobReturn : aliceReturn;
long expectedFulfilled = (initiatingOrderData.getHaveAssetId() < initiatingOrderData.getWantAssetId()) ? bobReturn : aliceReturn;
// Check matching order
assertNotNull("matching order missing", initiatingOrderData);
Common.assertEqualBigDecimals(String.format("Bob's order \"fulfilled\" incorrect"), expectedFulfilled, initiatingOrderData.getFulfilled());
assertEquals(String.format("Bob's order \"fulfilled\" incorrect"), expectedFulfilled, initiatingOrderData.getFulfilled());
// Check initial order
assertNotNull("initial order missing", targetOrderData);
Common.assertEqualBigDecimals(String.format("Alice's order \"fulfilled\" incorrect"), expectedFulfilled, targetOrderData.getFulfilled());
assertEquals(String.format("Alice's order \"fulfilled\" incorrect"), expectedFulfilled, targetOrderData.getFulfilled());
}
}

View File

@@ -1,7 +1,5 @@
package org.qortal.test.common;
import java.math.BigDecimal;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.qortal.account.PrivateKeyAccount;
@@ -22,7 +20,7 @@ public class BlockUtils {
BlockMinter.mintTestingBlock(repository, mintingAccount);
}
public static BigDecimal getNextBlockReward(Repository repository) throws DataException {
public static Long getNextBlockReward(Repository repository) throws DataException {
int currentHeight = repository.getBlockRepository().getBlockchainHeight();
return BlockChain.getInstance().getRewardAtHeight(currentHeight + 1);

View File

@@ -152,7 +152,7 @@ public class Common {
checkOrphanedLists("group", initialGroups, remainingGroups, GroupData::getGroupId, GroupData::getGroupId);
List<AccountBalanceData> remainingBalances = repository.getAccountRepository().getAssetBalances(Collections.emptyList(), Collections.emptyList(), BalanceOrdering.ASSET_ACCOUNT, false, null, null, null);
checkOrphanedLists("account balance", initialBalances, remainingBalances, entry -> entry.getAddress() + " [" + entry.getAssetName() + "]", entry -> entry.getBalance().toPlainString());
checkOrphanedLists("account balance", initialBalances, remainingBalances, entry -> entry.getAddress() + " [" + entry.getAssetName() + "]", entry -> entry.getBalance());
assertEquals("remainingBalances is different size", initialBalances.size(), remainingBalances.size());
// Actually compare balances
@@ -163,7 +163,7 @@ public class Common {
assertEquals("Remaining balance's address differs", initialBalance.getAddress(), remainingBalance.getAddress());
assertEquals(initialBalance.getAddress() + " remaining balance's asset differs", initialBalance.getAssetId(), remainingBalance.getAssetId());
assertEqualBigDecimals(initialBalance.getAddress() + " remaining balance differs", initialBalance.getBalance(), remainingBalance.getBalance());
assertEquals(initialBalance.getAddress() + " remaining balance differs", initialBalance.getBalance(), remainingBalance.getBalance());
}
}
}

View File

@@ -1,7 +1,5 @@
package org.qortal.test.common;
import java.math.BigDecimal;
import org.qortal.account.PrivateKeyAccount;
import org.qortal.data.transaction.BaseTransactionData;
import org.qortal.data.transaction.CreateGroupTransactionData;
@@ -17,7 +15,7 @@ import org.qortal.transaction.Transaction.ApprovalStatus;
public class GroupUtils {
public static final int txGroupId = Group.NO_GROUP;
public static final BigDecimal fee = BigDecimal.ONE.setScale(8);
public static final long fee = 1L;
public static int createGroup(Repository repository, String creatorAccountName, String groupName, boolean isOpen, ApprovalThreshold approvalThreshold,
int minimumBlockDelay, int maximumBlockDelay) throws DataException {

View File

@@ -2,8 +2,6 @@ package org.qortal.test.minting;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -23,7 +21,7 @@ import org.qortal.utils.Base58;
public class RewardShareTests extends Common {
private static final BigDecimal CANCEL_SHARE_PERCENT = BigDecimal.ONE.negate();
private static final int CANCEL_SHARE_PERCENT = -1;
@Before
public void beforeTest() throws DataException {
@@ -37,7 +35,7 @@ public class RewardShareTests extends Common {
@Test
public void testCreateRewardShare() throws DataException {
final BigDecimal sharePercent = new BigDecimal("12.8");
final int sharePercent = 12_80; // 12.80%
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount aliceAccount = Common.getTestAccount(repository, "alice");
@@ -53,13 +51,13 @@ public class RewardShareTests extends Common {
RewardShareData rewardShareData = repository.getAccountRepository().getRewardShare(rewardShareAccount.getPublicKey());
assertEquals("Incorrect minter public key", Base58.encode(aliceAccount.getPublicKey()), Base58.encode(rewardShareData.getMinterPublicKey()));
assertEquals("Incorrect recipient", bobAccount.getAddress(), rewardShareData.getRecipient());
assertEqualBigDecimals("Incorrect share percentage", sharePercent, rewardShareData.getSharePercent());
assertEquals("Incorrect share percentage", sharePercent, rewardShareData.getSharePercent());
// Fetch using minter public key and recipient address combination
rewardShareData = repository.getAccountRepository().getRewardShare(aliceAccount.getPublicKey(), bobAccount.getAddress());
assertEquals("Incorrect minter public key", Base58.encode(aliceAccount.getPublicKey()), Base58.encode(rewardShareData.getMinterPublicKey()));
assertEquals("Incorrect recipient", bobAccount.getAddress(), rewardShareData.getRecipient());
assertEqualBigDecimals("Incorrect share percentage", sharePercent, rewardShareData.getSharePercent());
assertEquals("Incorrect share percentage", sharePercent, rewardShareData.getSharePercent());
// Delete reward-share
byte[] newRewardSharePrivateKey = AccountUtils.rewardShare(repository, "alice", "bob", CANCEL_SHARE_PERCENT);
@@ -89,14 +87,14 @@ public class RewardShareTests extends Common {
assertNotNull("Reward-share should have been restored", newRewardShareData);
assertEquals("Incorrect minter public key", Base58.encode(aliceAccount.getPublicKey()), Base58.encode(newRewardShareData.getMinterPublicKey()));
assertEquals("Incorrect recipient", bobAccount.getAddress(), newRewardShareData.getRecipient());
assertEqualBigDecimals("Incorrect share percentage", sharePercent, newRewardShareData.getSharePercent());
assertEquals("Incorrect share percentage", sharePercent, newRewardShareData.getSharePercent());
// Fetch using minter public key and recipient address combination
newRewardShareData = repository.getAccountRepository().getRewardShare(aliceAccount.getPublicKey(), bobAccount.getAddress());
assertNotNull("Reward-share should have been restored", newRewardShareData);
assertEquals("Incorrect minter public key", Base58.encode(aliceAccount.getPublicKey()), Base58.encode(newRewardShareData.getMinterPublicKey()));
assertEquals("Incorrect recipient", bobAccount.getAddress(), newRewardShareData.getRecipient());
assertEqualBigDecimals("Incorrect share percentage", sharePercent, newRewardShareData.getSharePercent());
assertEquals("Incorrect share percentage", sharePercent, newRewardShareData.getSharePercent());
// Orphan another block to remove initial reward-share
BlockUtils.orphanLastBlock(repository);
@@ -137,7 +135,7 @@ public class RewardShareTests extends Common {
// PrivateKeyAccount rewardShareAccount = new PrivateKeyAccount(repository, rewardSharePrivateKey);
// Create self-reward-share
TransactionData transactionData = AccountUtils.createRewardShare(repository, testAccountName, testAccountName, BigDecimal.valueOf(100L));
TransactionData transactionData = AccountUtils.createRewardShare(repository, testAccountName, testAccountName, 100_00);
Transaction transaction = Transaction.fromData(repository, transactionData);
// Confirm self-share is valid
@@ -145,14 +143,14 @@ public class RewardShareTests extends Common {
assertEquals("Initial self-share should be valid", ValidationResult.OK, validationResult);
// Check zero fee is valid
transactionData.setFee(BigDecimal.ZERO);
transactionData.setFee(0L);
validationResult = transaction.isValidUnconfirmed();
assertEquals("Zero-fee self-share should be valid", ValidationResult.OK, validationResult);
TransactionUtils.signAndMint(repository, transactionData, signingAccount);
// Subsequent non-terminating (0% share) self-reward-share should be invalid
TransactionData newTransactionData = AccountUtils.createRewardShare(repository, testAccountName, testAccountName, BigDecimal.valueOf(99L));
TransactionData newTransactionData = AccountUtils.createRewardShare(repository, testAccountName, testAccountName, 99_00);
Transaction newTransaction = Transaction.fromData(repository, newTransactionData);
// Confirm subsequent self-reward-share is actually invalid
@@ -160,7 +158,7 @@ public class RewardShareTests extends Common {
assertNotSame("Subsequent self-share should be invalid", ValidationResult.OK, validationResult);
// Recheck with zero fee
newTransactionData.setFee(BigDecimal.ZERO);
newTransactionData.setFee(0L);
validationResult = newTransaction.isValidUnconfirmed();
assertNotSame("Subsequent zero-fee self-share should be invalid", ValidationResult.OK, validationResult);
@@ -173,7 +171,7 @@ public class RewardShareTests extends Common {
assertEquals("Subsequent self-share cancel should be valid", ValidationResult.OK, validationResult);
// Confirm terminating reward-share with zero fee is invalid
newTransactionData.setFee(BigDecimal.ZERO);
newTransactionData.setFee(0L);
validationResult = newTransaction.isValidUnconfirmed();
assertNotSame("Subsequent zero-fee self-share cancel should be invalid", ValidationResult.OK, validationResult);
}

View File

@@ -41,13 +41,13 @@ public class RewardTests extends Common {
@Test
public void testSimpleReward() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
Map<String, Map<Long, BigDecimal>> initialBalances = AccountUtils.getBalances(repository, Asset.QORT);
Map<String, Map<Long, Long>> initialBalances = AccountUtils.getBalances(repository, Asset.QORT);
BigDecimal blockReward = BlockUtils.getNextBlockReward(repository);
Long blockReward = BlockUtils.getNextBlockReward(repository);
BlockUtils.mintBlock(repository);
BigDecimal expectedBalance = initialBalances.get("alice").get(Asset.QORT).add(blockReward);
long expectedBalance = initialBalances.get("alice").get(Asset.QORT) + blockReward;
AccountUtils.assertBalance(repository, "alice", Asset.QORT, expectedBalance);
}
}
@@ -57,12 +57,12 @@ public class RewardTests extends Common {
List<RewardByHeight> rewardsByHeight = BlockChain.getInstance().getBlockRewardsByHeight();
try (final Repository repository = RepositoryManager.getRepository()) {
Map<String, Map<Long, BigDecimal>> initialBalances = AccountUtils.getBalances(repository, Asset.QORT);
Map<String, Map<Long, Long>> initialBalances = AccountUtils.getBalances(repository, Asset.QORT);
int rewardIndex = rewardsByHeight.size() - 1;
RewardByHeight rewardInfo = rewardsByHeight.get(rewardIndex);
BigDecimal expectedBalance = initialBalances.get("alice").get(Asset.QORT);
Long 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 {
BlockUtils.mintBlock(repository);
expectedBalance = expectedBalance.add(rewardInfo.reward);
expectedBalance += rewardInfo.unscaledReward;
}
AccountUtils.assertBalance(repository, "alice", Asset.QORT, expectedBalance);
@@ -81,24 +81,24 @@ public class RewardTests extends Common {
@Test
public void testRewardSharing() throws DataException {
final BigDecimal share = new BigDecimal("12.8");
final int share = 12_80; // 12.80%
try (final Repository repository = RepositoryManager.getRepository()) {
byte[] rewardSharePrivateKey = AccountUtils.rewardShare(repository, "alice", "bob", share);
PrivateKeyAccount rewardShareAccount = new PrivateKeyAccount(repository, rewardSharePrivateKey);
Map<String, Map<Long, BigDecimal>> initialBalances = AccountUtils.getBalances(repository, Asset.QORT);
BigDecimal blockReward = BlockUtils.getNextBlockReward(repository);
Map<String, Map<Long, Long>> initialBalances = AccountUtils.getBalances(repository, Asset.QORT);
Long blockReward = BlockUtils.getNextBlockReward(repository);
BlockMinter.mintTestingBlock(repository, rewardShareAccount);
// 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.QORT, initialBalances.get("bob").get(Asset.QORT).add(bobShare));
long bobShare = (blockReward * share) / 100L;
AccountUtils.assertBalance(repository, "bob", Asset.QORT, initialBalances.get("bob").get(Asset.QORT) + bobShare);
BigDecimal aliceShare = blockReward.subtract(bobShare);
AccountUtils.assertBalance(repository, "alice", Asset.QORT, initialBalances.get("alice").get(Asset.QORT).add(aliceShare));
long aliceShare = blockReward - bobShare;
AccountUtils.assertBalance(repository, "alice", Asset.QORT, initialBalances.get("alice").get(Asset.QORT) + aliceShare);
}
}
@@ -107,19 +107,19 @@ public class RewardTests extends Common {
public void testLegacyQoraReward() throws DataException {
Common.useSettings("test-settings-v2-qora-holder.json");
BigDecimal qoraHoldersShare = BlockChain.getInstance().getQoraHoldersShare();
BigDecimal qoraPerQort = BlockChain.getInstance().getQoraPerQortReward();
long qoraHoldersShare = BlockChain.getInstance().getQoraHoldersUnscaledShare();
long qoraPerQort = BlockChain.getInstance().getUnscaledQoraPerQortReward();
try (final Repository repository = RepositoryManager.getRepository()) {
Map<String, Map<Long, BigDecimal>> initialBalances = AccountUtils.getBalances(repository, Asset.QORT, Asset.LEGACY_QORA, Asset.QORT_FROM_QORA);
Map<String, Map<Long, Long>> initialBalances = AccountUtils.getBalances(repository, Asset.QORT, Asset.LEGACY_QORA, Asset.QORT_FROM_QORA);
BigDecimal blockReward = BlockUtils.getNextBlockReward(repository);
Long blockReward = BlockUtils.getNextBlockReward(repository);
// Fetch all legacy QORA holder balances
List<AccountBalanceData> qoraHolders = repository.getAccountRepository().getAssetBalances(Asset.LEGACY_QORA, true);
BigDecimal totalQoraHeld = BigDecimal.ZERO.setScale(8);
long totalQoraHeld = 0L;
for (AccountBalanceData accountBalanceData : qoraHolders)
totalQoraHeld = totalQoraHeld.add(accountBalanceData.getBalance());
totalQoraHeld += accountBalanceData.getBalance();
BlockUtils.mintBlock(repository);
@@ -142,19 +142,19 @@ public class RewardTests extends Common {
*/
// Expected reward
BigDecimal qoraHoldersReward = blockReward.multiply(qoraHoldersShare);
assertTrue("QORA-holders share of block reward should be less than total block reward", qoraHoldersReward.compareTo(blockReward) < 0);
long qoraHoldersReward = (blockReward * qoraHoldersShare) / Asset.MULTIPLIER;
assertTrue("QORA-holders share of block reward should be less than total block reward", qoraHoldersReward < blockReward);
BigDecimal ourQoraHeld = initialBalances.get("chloe").get(Asset.LEGACY_QORA);
BigDecimal ourQoraReward = qoraHoldersReward.multiply(ourQoraHeld).divide(totalQoraHeld, RoundingMode.DOWN).setScale(8, RoundingMode.DOWN);
assertTrue("Our QORA-related reward should be less than total QORA-holders share of block reward", ourQoraReward.compareTo(qoraHoldersReward) < 0);
long ourQoraHeld = initialBalances.get("chloe").get(Asset.LEGACY_QORA);
long ourQoraReward = (qoraHoldersReward * ourQoraHeld) / totalQoraHeld;
assertTrue("Our QORA-related reward should be less than total QORA-holders share of block reward", ourQoraReward < qoraHoldersReward);
BigDecimal ourQortFromQoraCap = ourQoraHeld.divide(qoraPerQort, RoundingMode.DOWN);
long ourQortFromQoraCap = ourQoraHeld / qoraPerQort;
BigDecimal expectedReward = ourQoraReward.min(ourQortFromQoraCap);
AccountUtils.assertBalance(repository, "chloe", Asset.QORT, initialBalances.get("chloe").get(Asset.QORT).add(expectedReward));
long expectedReward = Math.min(ourQoraReward, ourQortFromQoraCap);
AccountUtils.assertBalance(repository, "chloe", Asset.QORT, initialBalances.get("chloe").get(Asset.QORT) + expectedReward);
AccountUtils.assertBalance(repository, "chloe", Asset.QORT_FROM_QORA, initialBalances.get("chloe").get(Asset.QORT_FROM_QORA).add(expectedReward));
AccountUtils.assertBalance(repository, "chloe", Asset.QORT_FROM_QORA, initialBalances.get("chloe").get(Asset.QORT_FROM_QORA) + expectedReward);
}
}