Fix off-by-one error when reducing account level during block orphaning.

Added test to cover above.

Modified test-chain-v2.json so Dilbert starts with level 5, not 8,
to reduce number of blocks minted during tests.
This commit is contained in:
catbref
2020-01-21 13:34:46 +00:00
parent c3a6e0d9fd
commit 5cd35e07d0
5 changed files with 70 additions and 2 deletions

View File

@@ -46,4 +46,21 @@ public class BlockUtils {
orphanLastBlock(repository);
}
public static void orphanToBlock(Repository repository, int targetHeight) throws DataException {
do {
BlockData blockData = repository.getBlockRepository().getLastBlock();
final int height = blockData.getHeight();
if (height <= targetHeight)
return;
Block block = new Block(repository, blockData);
block.orphan();
LOGGER.info(String.format("Orphaned block: %d", height));
repository.saveChanges();
} while (true);
}
}

View File

@@ -22,6 +22,7 @@ import org.qora.repository.RepositoryManager;
import org.qora.test.common.AccountUtils;
import org.qora.test.common.BlockUtils;
import org.qora.test.common.Common;
import org.qora.test.common.TestAccount;
public class RewardTests extends Common {
@@ -175,4 +176,32 @@ public class RewardTests extends Common {
}
}
/** Use Alice-Chloe reward-share to bump Chloe from level 0 to level 1, then check orphaning works as expected. */
@Test
public void testLevel1() throws DataException {
List<Integer> cumulativeBlocksByLevel = BlockChain.getInstance().getCumulativeBlocksByLevel();
try (final Repository repository = RepositoryManager.getRepository()) {
TestAccount chloe = Common.getTestAccount(repository, "chloe");
assertEquals(0, (int) chloe.getLevel());
// 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
PrivateKeyAccount aliceChloeRewardShareAccount = new PrivateKeyAccount(repository, aliceChloeRewardSharePrivateKey);
final int minterBlocksNeeded = cumulativeBlocksByLevel.get(1);
// Mint enough blocks to bump testAccount level
for (int bc = 0; bc < minterBlocksNeeded; ++bc)
BlockMinter.mintTestingBlock(repository, aliceChloeRewardShareAccount);
assertEquals(1, (int) chloe.getLevel());
// Orphan back to genesis block
BlockUtils.orphanToBlock(repository, 1);
assertEquals(0, (int) chloe.getLevel());
}
}
}

View File

@@ -62,7 +62,7 @@
{ "type": "ACCOUNT_FLAGS", "target": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "andMask": -1, "orMask": 1, "xorMask": 0 },
{ "type": "REWARD_SHARE", "minterPublicKey": "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP", "recipient": "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v", "rewardSharePublicKey": "7PpfnvLSG7y4HPh8hE7KoqAjLCkv7Ui6xw4mKAkbZtox", "sharePercent": 100 },
{ "type": "ACCOUNT_LEVEL", "target": "Qci5m9k4rcwe4ruKrZZQKka4FzUUMut3er", "level": 8 }
{ "type": "ACCOUNT_LEVEL", "target": "Qci5m9k4rcwe4ruKrZZQKka4FzUUMut3er", "level": 5 }
]
}
}