mirror of
https://github.com/Qortal/qortal.git
synced 2025-07-23 04:36:50 +00:00
Merge chain-stall, blocksMinted and other fixes
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
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;
|
||||
import org.qortal.account.PrivateKeyAccount;
|
||||
import org.qortal.block.BlockMinter;
|
||||
import org.qortal.data.account.RewardShareData;
|
||||
import org.qortal.repository.DataException;
|
||||
import org.qortal.repository.Repository;
|
||||
import org.qortal.repository.RepositoryManager;
|
||||
import org.qortal.test.common.AccountUtils;
|
||||
import org.qortal.test.common.BlockUtils;
|
||||
import org.qortal.test.common.Common;
|
||||
import org.qortal.test.common.TestAccount;
|
||||
|
||||
public class BlocksMintedCountTests extends Common {
|
||||
|
||||
@Before
|
||||
public void beforeTest() throws DataException {
|
||||
Common.useDefaultSettings();
|
||||
}
|
||||
|
||||
@After
|
||||
public void afterTest() throws DataException {
|
||||
Common.orphanCheck();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonSelfShare() throws DataException {
|
||||
final BigDecimal sharePercent = new BigDecimal("12.8");
|
||||
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
// Create reward-share
|
||||
byte[] testRewardSharePrivateKey = AccountUtils.rewardShare(repository, "alice", "bob", sharePercent);
|
||||
PrivateKeyAccount testRewardShareAccount = new PrivateKeyAccount(repository, testRewardSharePrivateKey);
|
||||
|
||||
// Confirm reward-share info set correctly
|
||||
RewardShareData testRewardShareData = repository.getAccountRepository().getRewardShare(testRewardShareAccount.getPublicKey());
|
||||
assertNotNull(testRewardShareData);
|
||||
|
||||
testRewardShare(repository, testRewardShareAccount, +1, +1);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelfShare() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
PrivateKeyAccount testRewardShareAccount = Common.getTestAccount(repository, "alice-reward-share");
|
||||
|
||||
// Confirm reward-share exists
|
||||
RewardShareData testRewardShareData = repository.getAccountRepository().getRewardShare(testRewardShareAccount.getPublicKey());
|
||||
assertNotNull(testRewardShareData);
|
||||
|
||||
testRewardShare(repository, testRewardShareAccount, +1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void testRewardShare(Repository repository, PrivateKeyAccount mintingAccount, int aliceDelta, int bobDelta) throws DataException {
|
||||
// Fetch pre-mint blocks minted counts
|
||||
int alicePreMintCount = getBlocksMinted(repository, "alice");
|
||||
int bobPreMintCount = getBlocksMinted(repository, "bob");
|
||||
|
||||
// Mint another block
|
||||
BlockMinter.mintTestingBlock(repository, mintingAccount);
|
||||
|
||||
// Fetch post-mint blocks minted counts
|
||||
int alicePostMintCount = getBlocksMinted(repository, "alice");
|
||||
int bobPostMintCount = getBlocksMinted(repository, "bob");
|
||||
|
||||
// Check both accounts
|
||||
assertEquals("Alice's post-mint blocks-minted count incorrect", alicePreMintCount + aliceDelta, alicePostMintCount);
|
||||
assertEquals("Bob's post-mint blocks-minted count incorrect", bobPreMintCount + bobDelta, bobPostMintCount);
|
||||
|
||||
// Orphan latest block
|
||||
BlockUtils.orphanLastBlock(repository);
|
||||
|
||||
// Fetch post-orphan blocks minted counts
|
||||
int alicePostOrphanCount = getBlocksMinted(repository, "alice");
|
||||
int bobPostOrphanCount = getBlocksMinted(repository, "bob");
|
||||
|
||||
// Check blocks minted counts reverted correctly
|
||||
assertEquals("Alice's post-orphan blocks-minted count incorrect", alicePreMintCount, alicePostOrphanCount);
|
||||
assertEquals("Bob's post-orphan blocks-minted count incorrect", bobPreMintCount, bobPostOrphanCount);
|
||||
}
|
||||
|
||||
private int getBlocksMinted(Repository repository, String name) throws DataException {
|
||||
TestAccount testAccount = Common.getTestAccount(repository, name);
|
||||
return repository.getAccountRepository().getAccount(testAccount.getAddress()).getBlocksMinted();
|
||||
}
|
||||
|
||||
}
|
125
src/test/java/org/qortal/test/minting/DisagreementTests.java
Normal file
125
src/test/java/org/qortal/test/minting/DisagreementTests.java
Normal file
@@ -0,0 +1,125 @@
|
||||
package org.qortal.test.minting;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.qortal.account.PrivateKeyAccount;
|
||||
import org.qortal.block.BlockMinter;
|
||||
import org.qortal.controller.Controller;
|
||||
import org.qortal.data.account.RewardShareData;
|
||||
import org.qortal.data.block.BlockData;
|
||||
import org.qortal.data.transaction.TransactionData;
|
||||
import org.qortal.repository.DataException;
|
||||
import org.qortal.repository.Repository;
|
||||
import org.qortal.repository.RepositoryManager;
|
||||
import org.qortal.test.common.AccountUtils;
|
||||
import org.qortal.test.common.Common;
|
||||
import org.qortal.test.common.TestAccount;
|
||||
import org.qortal.test.common.TransactionUtils;
|
||||
import org.qortal.transform.block.BlockTransformer;
|
||||
import org.roaringbitmap.IntIterator;
|
||||
|
||||
import io.druid.extendedset.intset.ConciseSet;
|
||||
|
||||
public class DisagreementTests extends Common {
|
||||
|
||||
private static final BigDecimal CANCEL_SHARE_PERCENT = BigDecimal.ONE.negate();
|
||||
|
||||
@Before
|
||||
public void beforeTest() throws DataException {
|
||||
Common.useDefaultSettings();
|
||||
}
|
||||
|
||||
@After
|
||||
public void afterTest() throws DataException {
|
||||
Common.orphanCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing minting a block when there is a signed online account timestamp present
|
||||
* that no longer has a corresponding reward-share in DB.
|
||||
* <p>
|
||||
* Something like:
|
||||
* <ul>
|
||||
* <li>Mint block, with tx to create reward-share R</li>
|
||||
* <li>Sign current timestamp with R</li>
|
||||
* <li>Mint block including R as online account</li>
|
||||
* <li>Mint block, with tx to cancel reward-share R</li>
|
||||
* <li>Mint another block: R's timestamp should be excluded</li>
|
||||
* </ul>
|
||||
*
|
||||
* @throws DataException
|
||||
*/
|
||||
@Test
|
||||
public void testOnlineAccounts() throws DataException {
|
||||
final BigDecimal sharePercent = new BigDecimal("12.8");
|
||||
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
TestAccount mintingAccount = Common.getTestAccount(repository, "alice-reward-share");
|
||||
TestAccount signingAccount = Common.getTestAccount(repository, "alice");
|
||||
|
||||
// Create reward-share
|
||||
byte[] testRewardSharePrivateKey = AccountUtils.rewardShare(repository, "alice", "bob", sharePercent);
|
||||
PrivateKeyAccount testRewardShareAccount = new PrivateKeyAccount(repository, testRewardSharePrivateKey);
|
||||
|
||||
// Confirm reward-share info set correctly
|
||||
RewardShareData testRewardShareData = repository.getAccountRepository().getRewardShare(testRewardShareAccount.getPublicKey());
|
||||
assertNotNull(testRewardShareData);
|
||||
|
||||
// Create signed timestamps
|
||||
Controller.getInstance().ensureTestingAccountsOnline(mintingAccount, testRewardShareAccount);
|
||||
|
||||
// Mint another block
|
||||
BlockMinter.mintTestingBlockRetainingTimestamps(repository, mintingAccount);
|
||||
|
||||
// Confirm reward-share's signed timestamp is included
|
||||
BlockData blockData = repository.getBlockRepository().getLastBlock();
|
||||
List<RewardShareData> rewardSharesData = fetchRewardSharesForBlock(repository, blockData);
|
||||
boolean doesContainRewardShare = rewardSharesData.stream().anyMatch(rewardShareData -> Arrays.equals(rewardShareData.getRewardSharePublicKey(), testRewardShareData.getRewardSharePublicKey()));
|
||||
assertTrue(doesContainRewardShare);
|
||||
|
||||
// Cancel reward-share
|
||||
TransactionData cancelRewardShareTransactionData = AccountUtils.createRewardShare(repository, "alice", "bob", CANCEL_SHARE_PERCENT);
|
||||
TransactionUtils.signAsUnconfirmed(repository, cancelRewardShareTransactionData, signingAccount);
|
||||
BlockMinter.mintTestingBlockRetainingTimestamps(repository, mintingAccount);
|
||||
|
||||
// Confirm reward-share no longer exists in repository
|
||||
RewardShareData cancelledRewardShareData = repository.getAccountRepository().getRewardShare(testRewardShareAccount.getPublicKey());
|
||||
assertNull("Reward-share shouldn't exist", cancelledRewardShareData);
|
||||
|
||||
// Attempt to mint with cancelled reward-share
|
||||
BlockMinter.mintTestingBlockRetainingTimestamps(repository, mintingAccount);
|
||||
|
||||
// Confirm reward-share's signed timestamp is NOT included
|
||||
blockData = repository.getBlockRepository().getLastBlock();
|
||||
rewardSharesData = fetchRewardSharesForBlock(repository, blockData);
|
||||
doesContainRewardShare = rewardSharesData.stream().anyMatch(rewardShareData -> Arrays.equals(rewardShareData.getRewardSharePublicKey(), testRewardShareData.getRewardSharePublicKey()));
|
||||
assertFalse(doesContainRewardShare);
|
||||
}
|
||||
}
|
||||
|
||||
private List<RewardShareData> fetchRewardSharesForBlock(Repository repository, BlockData blockData) throws DataException {
|
||||
byte[] encodedOnlineAccounts = blockData.getEncodedOnlineAccounts();
|
||||
ConciseSet accountIndexes = BlockTransformer.decodeOnlineAccounts(encodedOnlineAccounts);
|
||||
|
||||
List<RewardShareData> rewardSharesData = new ArrayList<>();
|
||||
|
||||
IntIterator iterator = accountIndexes.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int accountIndex = iterator.next();
|
||||
|
||||
RewardShareData rewardShareData = repository.getAccountRepository().getRewardShareByIndex(accountIndex);
|
||||
rewardSharesData.add(rewardShareData);
|
||||
}
|
||||
|
||||
return rewardSharesData;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user