use of co.rsk.db.RepositoryLocator in project rskj by rsksmart.
the class RemascProcessMinerFeesTest method siblingThatBreaksSelectionRuleGetsPunished.
@Test
public void siblingThatBreaksSelectionRuleGetsPunished() {
Blockchain blockchain = blockchainBuilder.build();
BlockStore blockStore = blockchainBuilder.getBlockStore();
RepositoryLocator repositoryLocator = blockchainBuilder.getRepositoryLocator();
final long NUMBER_OF_TXS_WITH_FEES = 3;
List<Block> blocks = createSimpleBlocks(genesisBlock, 4);
Block blockAtHeightThree = blocks.get(blocks.size() - 1);
Block blockWithOneTxA = RemascTestRunner.createBlock(this.genesisBlock, blockAtHeightThree, PegTestUtils.createHash3(), coinbaseA, Collections.emptyList(), minerFee, 0, txValue, cowKey, 2l);
blocks.add(blockWithOneTxA);
Block blockWithOneTxC = RemascTestRunner.createBlock(this.genesisBlock, blockWithOneTxA, PegTestUtils.createHash3(), coinbaseC, Collections.emptyList(), minerFee, 1, txValue, cowKey, 2l);
blocks.add(blockWithOneTxC);
Block blockWithOneTxD = RemascTestRunner.createBlock(this.genesisBlock, blockWithOneTxA, PegTestUtils.createHash3(), coinbaseD, Collections.emptyList(), minerFee, 1, txValue, cowKey, 2l);
Block blockWithOneTxB = RemascTestRunner.createBlock(this.genesisBlock, blockAtHeightThree, PegTestUtils.createHash3(), coinbaseB, Collections.emptyList(), 3 * minerFee, 0, txValue, cowKey, 2l);
Block blockThatIncludesUnclesE = RemascTestRunner.createBlock(this.genesisBlock, blockWithOneTxC, PegTestUtils.createHash3(), coinbaseE, Arrays.asList(blockWithOneTxB.getHeader(), blockWithOneTxD.getHeader()), minerFee, 2, txValue, cowKey);
blocks.add(blockThatIncludesUnclesE);
blocks.addAll(createSimpleBlocks(blockThatIncludesUnclesE, 7));
BlockExecutor blockExecutor = buildBlockExecutor(repositoryLocator, blockStore);
executeBlocks(blockchain, blocks, blockExecutor);
RepositorySnapshot repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader());
// validate that the blockchain's and REMASC's initial states are correct
Coin cowRemainingBalance = cowInitialBalance.subtract(Coin.valueOf(minerFee * NUMBER_OF_TXS_WITH_FEES + txValue * NUMBER_OF_TXS_WITH_FEES));
List<Long> otherAccountsBalance = new ArrayList<>(Arrays.asList(null, null, null, null));
this.validateAccountsCurrentBalanceIsCorrect(repository, cowRemainingBalance, minerFee * NUMBER_OF_TXS_WITH_FEES, null, this.getAccountsWithExpectedBalance(otherAccountsBalance));
this.validateRemascsStorageIsCorrect(getRemascStorageProvider(repository), Coin.ZERO, Coin.ZERO, 2L);
// add block to pay fees of blocks on blockchain's height 4
Block blockToPayFeesOnHeightFour = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), TestUtils.randomAddress(), Collections.emptyList(), minerFee, 3, txValue, cowKey);
blockExecutor.executeAndFillAll(blockToPayFeesOnHeightFour, blockchain.getBestBlock().getHeader());
blockchain.tryToConnect(blockToPayFeesOnHeightFour);
repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader());
// -- After executing REMASC's contract for paying height 4 block
// validate that account's balances are correct
cowRemainingBalance = cowRemainingBalance.subtract(Coin.valueOf(minerFee + txValue));
long minerRewardOnHeightFour = minerFee / remascConfig.getSyntheticSpan();
long burnBalanceLevelFour = minerRewardOnHeightFour;
long remascCurrentBalance = minerFee * 4 - burnBalanceLevelFour;
long rskCurrentBalance = minerRewardOnHeightFour / remascConfig.getRskLabsDivisor();
minerRewardOnHeightFour -= rskCurrentBalance;
long federationReward = minerRewardOnHeightFour / remascConfig.getFederationDivisor();
minerRewardOnHeightFour -= federationReward;
long publishersFee = minerRewardOnHeightFour / remascConfig.getPublishersDivisor();
minerRewardOnHeightFour -= minerRewardOnHeightFour / remascConfig.getPublishersDivisor();
minerRewardOnHeightFour /= 2;
long siblingPunishmentLvlFour = (long) (minerRewardOnHeightFour * 0.05);
long siblingReward = minerRewardOnHeightFour - siblingPunishmentLvlFour;
HashMap<byte[], Coin> otherAccountsBalanceOnHeightFour = this.getAccountsWithExpectedBalance(new ArrayList<>(Arrays.asList(minerRewardOnHeightFour, siblingReward, null, null)));
otherAccountsBalanceOnHeightFour.put(coinbaseE.getBytes(), Coin.valueOf(publishersFee));
remascCurrentBalance += siblingPunishmentLvlFour;
// TODO review one unit burned?
this.validateAccountsCurrentBalanceIsCorrect(repository, cowRemainingBalance, remascCurrentBalance + 1, rskCurrentBalance, otherAccountsBalanceOnHeightFour);
this.validateFederatorsBalanceIsCorrect(repository, federationReward, blockToPayFeesOnHeightFour);
// validate that REMASC's state is correct
long blockRewardOnHeightFour = minerFee / remascConfig.getSyntheticSpan();
Coin expectedRewardBalance = Coin.valueOf(minerFee - blockRewardOnHeightFour);
Coin expectedBurnedBalance = Coin.valueOf(siblingPunishmentLvlFour);
// TODO review one more burned unit
this.validateRemascsStorageIsCorrect(getRemascStorageProvider(repository), expectedRewardBalance, expectedBurnedBalance.add(Coin.valueOf(1)), 1L);
// add block to pay fees of blocks on blockchain's height 5
Block blockToPayFeesOnHeightFive = RemascTestRunner.createBlock(this.genesisBlock, blockToPayFeesOnHeightFour, PegTestUtils.createHash3(), TestUtils.randomAddress(), Collections.emptyList(), minerFee, 4, txValue, cowKey);
blockExecutor.executeAndFillAll(blockToPayFeesOnHeightFive, blockchain.getBestBlock().getHeader());
blockchain.tryToConnect(blockToPayFeesOnHeightFive);
repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader());
// -- After executing REMASC's contract for paying height 5 block
// validate that account's balances are correct
cowRemainingBalance = cowRemainingBalance.subtract(Coin.valueOf(minerFee + txValue));
long rewardBalance = minerFee - blockRewardOnHeightFour;
rewardBalance += minerFee;
long blockRewardOnHeightFive = rewardBalance / remascConfig.getSyntheticSpan();
remascCurrentBalance += minerFee - blockRewardOnHeightFive;
long rskReward = blockRewardOnHeightFive / remascConfig.getRskLabsDivisor();
rskCurrentBalance += rskReward;
blockRewardOnHeightFive -= rskReward;
long federationReward2 = blockRewardOnHeightFive / remascConfig.getFederationDivisor();
blockRewardOnHeightFive -= federationReward2;
long publishersFeeOnHeightFive = blockRewardOnHeightFive / remascConfig.getPublishersDivisor();
blockRewardOnHeightFive -= publishersFeeOnHeightFive;
long numberOfSiblingsOnHeightFive = 2;
blockRewardOnHeightFive /= numberOfSiblingsOnHeightFive;
long punishmentFee = blockRewardOnHeightFive / remascConfig.getPunishmentDivisor();
blockRewardOnHeightFive -= punishmentFee;
remascCurrentBalance += (numberOfSiblingsOnHeightFive * punishmentFee);
HashMap<byte[], Coin> otherAccountsBalanceOnHeightFive = this.getAccountsWithExpectedBalance(new ArrayList<>(Arrays.asList(minerRewardOnHeightFour, siblingReward, blockRewardOnHeightFive, blockRewardOnHeightFive)));
otherAccountsBalanceOnHeightFive.put(coinbaseE.getBytes(), Coin.valueOf(publishersFee + publishersFeeOnHeightFive));
// TODO review value 1
this.validateAccountsCurrentBalanceIsCorrect(repository, cowRemainingBalance, remascCurrentBalance + 1, rskCurrentBalance, otherAccountsBalanceOnHeightFive);
// validate that REMASC's state is correct
blockRewardOnHeightFive = (2 * minerFee - blockRewardOnHeightFour) / remascConfig.getSyntheticSpan();
expectedRewardBalance = Coin.valueOf(minerFee * 2 - blockRewardOnHeightFour - blockRewardOnHeightFive);
expectedBurnedBalance = Coin.valueOf((2 * punishmentFee) + siblingPunishmentLvlFour);
// TODO review value + 1
this.validateRemascsStorageIsCorrect(getRemascStorageProvider(repository), expectedRewardBalance, expectedBurnedBalance.add(Coin.valueOf(1)), 0L);
this.validateFederatorsBalanceIsCorrect(repository, federationReward + federationReward2, blockToPayFeesOnHeightFive);
}
use of co.rsk.db.RepositoryLocator in project rskj by rsksmart.
the class RemascProcessMinerFeesTest method processMinersFeesFromTxInvokedByAnotherContract.
@Test
public void processMinersFeesFromTxInvokedByAnotherContract() {
Blockchain blockchain = blockchainBuilder.build();
BlockStore blockStore = blockchainBuilder.getBlockStore();
RepositoryLocator repositoryLocator = blockchainBuilder.getRepositoryLocator();
List<Block> blocks = createSimpleBlocks(genesisBlock, 4);
Block blockWithOneTx = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), coinbaseA, Collections.emptyList(), minerFee, 0, txValue, cowKey);
blocks.add(blockWithOneTx);
blocks.addAll(createSimpleBlocks(blockWithOneTx, 9));
BlockExecutor blockExecutor = buildBlockExecutor(repositoryLocator, blockStore);
for (Block b : blocks) {
blockExecutor.executeAndFillAll(b, blockchain.getBestBlock().getHeader());
b.seal();
blockchain.tryToConnect(b);
}
RepositorySnapshot repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader());
assertEquals(cowInitialBalance.subtract(Coin.valueOf(minerFee + txValue)), repository.getAccountState(new RskAddress(cowAddress)).getBalance());
assertEquals(Coin.valueOf(minerFee), repository.getAccountState(PrecompiledContracts.REMASC_ADDR).getBalance());
assertNull(repository.getAccountState(coinbaseA));
assertNull(repository.getAccountState(remascConfig.getRskLabsAddress()));
RemascStorageProvider remasceStorageProvider = getRemascStorageProvider(repository);
assertEquals(Coin.ZERO, remasceStorageProvider.getRewardBalance());
assertEquals(Coin.ZERO, remasceStorageProvider.getBurnedBalance());
// A hacker trying to screw the system creates a contracts that calls remasc and a fool/accomplice miner includes that tx in a block
// Contract code
// pragma solidity ^0.4.3;
// contract RemascHacker {
//
// function()
// {
// address remasc = 0x0000000000000000000000000000000001000008;
// remasc.call();
// }
// }
long txCreateContractGasLimit = 53755 + 32000;
Transaction txCreateContract = Transaction.builder().nonce(Coin.valueOf(1)).gasPrice(Coin.valueOf(1)).gasLimit(Coin.valueOf(txCreateContractGasLimit)).data(Hex.decode("6060604052346000575b6077806100176000396000f30060606040525b3460005760495b6000600890508073ffffffffffffffffffffffffffffffffffffffff166040518090506000604051808303816000866161da5a03f1915050505b50565b0000a165627a7a7230582036692fbb1395da1688af0189be5b0ac18df3d93a2402f4fc8f927b31c1baa2460029")).chainId(config.getNetworkConstants().getChainId()).value(Coin.ZERO).build();
txCreateContract.sign(cowKey.getPrivKeyBytes());
long txCallRemascGasLimit = 21828;
Transaction txCallRemasc = Transaction.builder().nonce(Coin.valueOf(2)).gasPrice(Coin.valueOf(1)).gasLimit(Coin.valueOf(txCallRemascGasLimit)).destination(Hex.decode("da7ce79725418f4f6e13bf5f520c89cec5f6a974")).chainId(config.getNetworkConstants().getChainId()).value(Coin.ZERO).build();
txCallRemasc.sign(cowKey.getPrivKeyBytes());
Block newblock = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), TestUtils.randomAddress(), Collections.emptyList(), null, txCreateContract, txCallRemasc);
blockExecutor.executeAndFillAll(newblock, blockchain.getBestBlock().getHeader());
newblock.seal();
blockchain.tryToConnect(newblock);
repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader());
// Check "hack" tx makes no changes to the remasc state, sender pays fees, and value is added to remasc account balance
assertEquals(cowInitialBalance.subtract(Coin.valueOf(txCreateContractGasLimit + txCallRemascGasLimit + txValue + minerFee)), repository.getAccountState(new RskAddress(cowAddress)).getBalance());
long blockReward = minerFee / remascConfig.getSyntheticSpan();
long originalBlockReward = blockReward;
long rskReward = blockReward / remascConfig.getRskLabsDivisor();
assertEquals(Coin.valueOf(rskReward), repository.getAccountState(remascConfig.getRskLabsAddress()).getBalance());
blockReward -= rskReward;
long federationReward = blockReward / remascConfig.getFederationDivisor();
assertEquals(33, federationReward);
blockReward -= federationReward;
assertEquals(Coin.valueOf(blockReward), repository.getAccountState(coinbaseA).getBalance());
Coin expectedRewardBalance = Coin.valueOf(minerFee - originalBlockReward);
this.validateRemascsStorageIsCorrect(getRemascStorageProvider(repository), expectedRewardBalance, Coin.ZERO, 0L);
this.validateFederatorsBalanceIsCorrect(repository, federationReward, newblock);
}
use of co.rsk.db.RepositoryLocator in project rskj by rsksmart.
the class RemascProcessMinerFeesTest method processMinersFeesFromTxThatIsNotTheLatestTx.
@Test
public void processMinersFeesFromTxThatIsNotTheLatestTx() {
Blockchain blockchain = blockchainBuilder.build();
BlockStore blockStore = blockchainBuilder.getBlockStore();
RepositoryLocator repositoryLocator = blockchainBuilder.getRepositoryLocator();
List<Block> blocks = createSimpleBlocks(genesisBlock, 4);
Block blockWithOneTx = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), coinbaseA, Collections.emptyList(), minerFee, 0, txValue, cowKey);
blocks.add(blockWithOneTx);
blocks.addAll(createSimpleBlocks(blockWithOneTx, 9));
BlockExecutor blockExecutor = buildBlockExecutor(repositoryLocator, blockStore);
executeBlocks(blockchain, blocks, blockExecutor);
RepositorySnapshot repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader());
assertEquals(cowInitialBalance.subtract(Coin.valueOf(minerFee + txValue)), repository.getAccountState(new RskAddress(cowAddress)).getBalance());
assertEquals(Coin.valueOf(minerFee), repository.getAccountState(PrecompiledContracts.REMASC_ADDR).getBalance());
assertNull(repository.getAccountState(coinbaseA));
assertNull(repository.getAccountState(remascConfig.getRskLabsAddress()));
RemascStorageProvider remasceStorageProvider = getRemascStorageProvider(repository);
assertEquals(Coin.ZERO, remasceStorageProvider.getRewardBalance());
assertEquals(Coin.ZERO, remasceStorageProvider.getBurnedBalance());
// A hacker trying to screw the system creates a tx to remasc and a fool/accomplice miner includes that tx in a block
Transaction tx = Transaction.builder().nonce(Coin.valueOf(1)).gasPrice(Coin.valueOf(1)).gasLimit(Coin.valueOf(minerFee)).destination(PrecompiledContracts.REMASC_ADDR).chainId(config.getNetworkConstants().getChainId()).value(Coin.valueOf(txValue * 2)).build();
tx.sign(cowKey.getPrivKeyBytes());
Block newblock = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), TestUtils.randomAddress(), Collections.emptyList(), null, tx);
blockExecutor.executeAndFillAll(newblock, blockchain.getBestBlock().getHeader());
blockchain.tryToConnect(newblock);
repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader());
// Check "hack" tx makes no changes to the remasc state, sender pays fees, and value is added to remasc account balance
assertEquals(cowInitialBalance.subtract(Coin.valueOf(minerFee + txValue + minerFee)), repository.getAccountState(new RskAddress(cowAddress)).getBalance());
long blockReward = minerFee / remascConfig.getSyntheticSpan();
long originalBlockReward = blockReward;
assertEquals(Coin.valueOf(minerFee + minerFee - blockReward), repository.getAccountState(PrecompiledContracts.REMASC_ADDR).getBalance());
long rskReward = blockReward / remascConfig.getRskLabsDivisor();
assertEquals(Coin.valueOf(rskReward), repository.getAccountState(remascConfig.getRskLabsAddress()).getBalance());
blockReward -= rskReward;
long federationReward = blockReward / remascConfig.getFederationDivisor();
assertEquals(33, federationReward);
blockReward -= federationReward;
assertEquals(Coin.valueOf(blockReward), repository.getAccountState(coinbaseA).getBalance());
Coin expectedRewardBalance = Coin.valueOf(minerFee - originalBlockReward);
this.validateRemascsStorageIsCorrect(getRemascStorageProvider(repository), expectedRewardBalance, Coin.ZERO, 0L);
this.validateFederatorsBalanceIsCorrect(repository, federationReward, newblock);
}
use of co.rsk.db.RepositoryLocator in project rskj by rsksmart.
the class RemascProcessMinerFeesTest method processMinersFeesWithoutMinimumSyntheticSpan.
@Test
public void processMinersFeesWithoutMinimumSyntheticSpan() {
Blockchain blockchain = blockchainBuilder.build();
BlockStore blockStore = blockchainBuilder.getBlockStore();
RepositoryLocator repositoryLocator = blockchainBuilder.getRepositoryLocator();
List<Block> blocks = createSimpleBlocks(genesisBlock, 2);
Block blockWithOneTx = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), coinbaseA, Collections.emptyList(), minerFee, 0, txValue, cowKey);
blocks.add(blockWithOneTx);
blocks.addAll(createSimpleBlocks(blockWithOneTx, 9));
BlockExecutor blockExecutor = buildBlockExecutor(repositoryLocator, blockStore);
executeBlocks(blockchain, blocks, blockExecutor);
RepositorySnapshot repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader());
assertEquals(cowInitialBalance.subtract(Coin.valueOf(minerFee + txValue)), repository.getAccountState(new RskAddress(cowAddress)).getBalance());
assertEquals(Coin.valueOf(minerFee), repository.getAccountState(PrecompiledContracts.REMASC_ADDR).getBalance());
assertNull(repository.getAccountState(coinbaseA));
assertNull(repository.getAccountState(remascConfig.getRskLabsAddress()));
Block newblock = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), TestUtils.randomAddress(), Collections.emptyList(), null);
blockExecutor.executeAndFillAll(newblock, blockchain.getBestBlock().getHeader());
blockchain.tryToConnect(newblock);
repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader());
assertEquals(cowInitialBalance.subtract(Coin.valueOf(minerFee + txValue)), repository.getAccountState(new RskAddress(cowAddress)).getBalance());
assertEquals(Coin.valueOf(minerFee), repository.getAccountState(PrecompiledContracts.REMASC_ADDR).getBalance());
assertNull(repository.getAccountState(coinbaseA));
assertNull(repository.getAccountState(remascConfig.getRskLabsAddress()));
RemascStorageProvider remascStorageProvider = getRemascStorageProvider(repository);
assertEquals(Coin.valueOf(minerFee), remascStorageProvider.getRewardBalance());
assertEquals(Coin.ZERO, remascStorageProvider.getBurnedBalance());
}
use of co.rsk.db.RepositoryLocator in project rskj by rsksmart.
the class StateTestRunner method runImpl.
public List<String> runImpl() {
vStats = new ValidationStats();
logger.info("");
trieStore = new TrieStoreImpl(new HashMapDB());
repository = RepositoryBuilder.build(trieStore, stateTestCase.getPre());
logger.info("loaded repository");
transaction = TransactionBuilder.build(stateTestCase.getTransaction());
logger.info("transaction: {}", transaction.toString());
BlockStore blockStore = new IndexedBlockStore(blockFactory, new HashMapDB(), new HashMapBlocksIndex());
StateRootHandler stateRootHandler = new StateRootHandler(config.getActivationConfig(), new StateRootsStoreImpl(new HashMapDB()));
blockchain = new BlockChainImpl(blockStore, null, null, null, null, new BlockExecutor(config.getActivationConfig(), new RepositoryLocator(trieStore, stateRootHandler), new TransactionExecutorFactory(config, blockStore, null, blockFactory, new ProgramInvokeFactoryImpl(), precompiledContracts, new BlockTxSignatureCache(new ReceivedTxSignatureCache()))), stateRootHandler);
env = EnvBuilder.build(stateTestCase.getEnv());
invokeFactory = new TestProgramInvokeFactory(env);
block = build(env);
block.setStateRoot(repository.getRoot());
block.flushRLP();
blockchain.setStatus(block, block.getCumulativeDifficulty());
// blockchain.setProgramInvokeFactory(invokeFactory);
// blockchain.startTracking();
ProgramResult programResult = executeTransaction(transaction);
trieStore.flush();
List<LogInfo> origLogs = programResult.getLogInfoList();
List<LogInfo> postLogs = LogBuilder.build(stateTestCase.getLogs());
List<String> logsResult = LogsValidator.valid(origLogs, postLogs, vStats);
Repository postRepository = RepositoryBuilder.build(stateTestCase.getPost());
// Balances cannot be validated because has consumption for CALLs differ.
List<String> repoResults = RepositoryValidator.valid(repository, postRepository, false, false, vStats);
logger.info("--------- POST Validation---------");
List<String> outputResults = OutputValidator.valid(ByteUtil.toHexString(programResult.getHReturn()), stateTestCase.getOut(), vStats);
List<String> results = new ArrayList<>();
results.addAll(repoResults);
results.addAll(logsResult);
results.addAll(outputResults);
for (String result : results) {
logger.error(result);
}
if ((vStats.storageChecks == 0) && (vStats.logChecks == 0) && (vStats.balancetChecks == 0) && (vStats.outputChecks == 0) && (vStats.blockChecks == 0)) {
// This generally mean that the test didn't check anything
// AccountChecks are considered not indicative of the result of the test
logger.info("IRRELEVANT\n");
}
logger.info("\n\n");
return results;
}
Aggregations