use of co.rsk.core.bc.BlockExecutor in project rskj by rsksmart.
the class SyncProcessorTest method processBodyResponseWithTransactionAddsToBlockchain.
@Test
public void processBodyResponseWithTransactionAddsToBlockchain() {
Account senderAccount = createAccount("sender");
Account receiverAccount = createAccount("receiver");
List<Account> accounts = new ArrayList<Account>();
List<Coin> balances = new ArrayList<>();
accounts.add(senderAccount);
balances.add(Coin.valueOf(20000000));
accounts.add(receiverAccount);
balances.add(Coin.ZERO);
final BlockStore store = new BlockStore();
Blockchain blockchain = BlockChainBuilder.ofSize(0, false, accounts, balances);
Block genesis = blockchain.getBestBlock();
SimpleMessageChannel sender = new SimpleMessageChannel(new byte[] { 0x01 });
Assert.assertEquals(0, blockchain.getBestBlock().getNumber());
Transaction tx = createTransaction(senderAccount, receiverAccount, BigInteger.valueOf(1000000), BigInteger.ZERO);
List<Transaction> txs = new ArrayList<>();
txs.add(tx);
Block block = new BlockGenerator().createChildBlock(genesis, txs, blockchain.getRepository().getRoot());
BlockExecutor blockExecutor = new BlockExecutor(config, blockchain.getRepository(), null, blockchain.getBlockStore(), null);
Assert.assertEquals(1, block.getTransactionsList().size());
blockExecutor.executeAndFillAll(block, genesis);
Assert.assertEquals(21000, block.getFeesPaidToMiner().asBigInteger().intValueExact());
Assert.assertEquals(1, block.getTransactionsList().size());
Assert.assertEquals(1, block.getNumber());
Assert.assertArrayEquals(blockchain.getBestBlockHash(), block.getParentHash().getBytes());
BlockNodeInformation nodeInformation = new BlockNodeInformation();
RskSystemProperties config = new RskSystemProperties();
BlockSyncService blockSyncService = new BlockSyncService(config, store, blockchain, nodeInformation, SyncConfiguration.IMMEDIATE_FOR_TESTING);
SyncProcessor processor = new SyncProcessor(config, blockchain, blockSyncService, RskMockFactory.getPeerScoringManager(), getChannelManager(), SyncConfiguration.IMMEDIATE_FOR_TESTING, new ProofOfWorkRule(config).setFallbackMiningEnabled(false), DIFFICULTY_CALCULATOR);
processor.setSelectedPeer(sender, StatusUtils.getFakeStatus(), 0);
List<Transaction> transactions = block.getTransactionsList();
List<BlockHeader> uncles = block.getUncleList();
long lastRequestId = new Random().nextLong();
BodyResponseMessage response = new BodyResponseMessage(lastRequestId, transactions, uncles);
processor.registerExpectedMessage(response);
Deque<BlockHeader> headerStack = new ArrayDeque<>();
headerStack.add(block.getHeader());
List<Deque<BlockHeader>> headers = new ArrayList<>();
headers.add(headerStack);
List<BlockIdentifier> bids = new ArrayList<>();
bids.add(new BlockIdentifier(blockchain.getBlockByNumber(0).getHash().getBytes(), 0));
bids.add(new BlockIdentifier(block.getHash().getBytes(), 1));
processor.startDownloadingBodies(headers, Collections.singletonMap(sender.getPeerNodeID(), bids));
((DownloadingBodiesSyncState) processor.getSyncState()).expectBodyResponseFor(lastRequestId, sender.getPeerNodeID(), block.getHeader());
processor.processBodyResponse(sender, response);
Assert.assertEquals(1, blockchain.getBestBlock().getNumber());
Assert.assertArrayEquals(block.getHash().getBytes(), blockchain.getBestBlockHash());
Assert.assertTrue(processor.getExpectedResponses().isEmpty());
}
use of co.rsk.core.bc.BlockExecutor in project rskj by rsksmart.
the class RemascProcessMinerFeesTest method processMinersFeesFromTxInvokedByAnotherContract.
@Test
public void processMinersFeesFromTxInvokedByAnotherContract() throws IOException, BlockStoreException {
BlockChainBuilder builder = new BlockChainBuilder();
Blockchain blockchain = builder.setTesting(true).setGenesis(genesisBlock).build();
List<Block> blocks = createSimpleBlocks(genesisBlock, 4);
Block blockWithOneTx = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), coinbaseA, null, minerFee, 0, txValue, cowKey);
blocks.add(blockWithOneTx);
blocks.addAll(createSimpleBlocks(blockWithOneTx, 9));
BlockExecutor blockExecutor = new BlockExecutor(config, blockchain.getRepository(), null, blockchain.getBlockStore(), null);
for (Block b : blocks) {
blockExecutor.executeAndFillAll(b, blockchain.getBestBlock());
b.seal();
blockchain.tryToConnect(b);
}
Repository repository = blockchain.getRepository();
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(blockchain);
assertEquals(Coin.ZERO, remasceStorageProvider.getRewardBalance());
assertEquals(Coin.ZERO, remasceStorageProvider.getBurnedBalance());
assertEquals(0, remasceStorageProvider.getSiblings().size());
// 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 = new Transaction(Coin.valueOf(1).getBytes(), Coin.valueOf(1).getBytes(), Coin.valueOf(txCreateContractGasLimit).getBytes(), null, Coin.ZERO.getBytes(), Hex.decode("6060604052346000575b6077806100176000396000f30060606040525b3460005760495b6000600890508073ffffffffffffffffffffffffffffffffffffffff166040518090506000604051808303816000866161da5a03f1915050505b50565b0000a165627a7a7230582036692fbb1395da1688af0189be5b0ac18df3d93a2402f4fc8f927b31c1baa2460029"), config.getBlockchainConfig().getCommonConstants().getChainId());
txCreateContract.sign(cowKey.getPrivKeyBytes());
long txCallRemascGasLimit = 21828;
Transaction txCallRemasc = new Transaction(Coin.valueOf(2).getBytes(), Coin.valueOf(1).getBytes(), Coin.valueOf(txCallRemascGasLimit).getBytes(), Hex.decode("da7ce79725418f4f6e13bf5f520c89cec5f6a974"), Coin.ZERO.getBytes(), null, config.getBlockchainConfig().getCommonConstants().getChainId());
txCallRemasc.sign(cowKey.getPrivKeyBytes());
Block newblock = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), TestUtils.randomAddress(), null, null, txCreateContract, txCallRemasc);
blockExecutor.executeAndFillAll(newblock, blockchain.getBestBlock());
newblock.seal();
blockchain.tryToConnect(newblock);
repository = blockchain.getRepository();
// 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(this.getRemascStorageProvider(blockchain), expectedRewardBalance, Coin.ZERO, 0L);
this.validateFederatorsBalanceIsCorrect(blockchain.getRepository(), federationReward);
}
use of co.rsk.core.bc.BlockExecutor in project rskj by rsksmart.
the class RemascProcessMinerFeesTest method processMinersFeesFromTxThatIsNotTheLatestTx.
@Test
public void processMinersFeesFromTxThatIsNotTheLatestTx() throws IOException, BlockStoreException {
BlockChainBuilder builder = new BlockChainBuilder();
Blockchain blockchain = builder.setTesting(true).setGenesis(genesisBlock).build();
List<Block> blocks = createSimpleBlocks(genesisBlock, 4);
Block blockWithOneTx = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), coinbaseA, null, minerFee, 0, txValue, cowKey);
blocks.add(blockWithOneTx);
blocks.addAll(createSimpleBlocks(blockWithOneTx, 9));
BlockExecutor blockExecutor = new BlockExecutor(config, blockchain.getRepository(), null, blockchain.getBlockStore(), null);
for (Block b : blocks) {
blockExecutor.executeAndFillAll(b, blockchain.getBestBlock());
blockchain.tryToConnect(b);
}
Repository repository = blockchain.getRepository();
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(blockchain);
assertEquals(Coin.ZERO, remasceStorageProvider.getRewardBalance());
assertEquals(Coin.ZERO, remasceStorageProvider.getBurnedBalance());
assertEquals(0, remasceStorageProvider.getSiblings().size());
// 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 = new Transaction(Coin.valueOf(1).getBytes(), Coin.valueOf(1).getBytes(), Coin.valueOf(minerFee).getBytes(), PrecompiledContracts.REMASC_ADDR.getBytes(), Coin.valueOf(txValue * 2).getBytes(), null, config.getBlockchainConfig().getCommonConstants().getChainId());
tx.sign(cowKey.getPrivKeyBytes());
Block newblock = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), TestUtils.randomAddress(), null, null, tx);
blockExecutor.executeAndFillAll(newblock, blockchain.getBestBlock());
blockchain.tryToConnect(newblock);
repository = blockchain.getRepository();
// 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(this.getRemascStorageProvider(blockchain), expectedRewardBalance, Coin.ZERO, 0L);
this.validateFederatorsBalanceIsCorrect(blockchain.getRepository(), federationReward);
}
use of co.rsk.core.bc.BlockExecutor in project rskj by rsksmart.
the class RemascProcessMinerFeesTest method siblingThatBreaksSelectionRuleGetsPunished.
@Test
public void siblingThatBreaksSelectionRuleGetsPunished() throws IOException, BlockStoreException {
BlockChainBuilder builder = new BlockChainBuilder();
Blockchain blockchain = builder.setTesting(true).setGenesis(genesisBlock).build();
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, null, minerFee, 0, txValue, cowKey, 2l);
blocks.add(blockWithOneTxA);
Block blockWithOneTxC = RemascTestRunner.createBlock(this.genesisBlock, blockWithOneTxA, PegTestUtils.createHash3(), coinbaseC, null, minerFee, 1, txValue, cowKey, 2l);
blocks.add(blockWithOneTxC);
Block blockWithOneTxD = RemascTestRunner.createBlock(this.genesisBlock, blockWithOneTxA, PegTestUtils.createHash3(), coinbaseD, null, minerFee, 1, txValue, cowKey, 2l);
Block blockWithOneTxB = RemascTestRunner.createBlock(this.genesisBlock, blockAtHeightThree, PegTestUtils.createHash3(), coinbaseB, null, 3 * minerFee, 0, txValue, cowKey, 2l);
Block blockThatIncludesUnclesE = RemascTestRunner.createBlock(this.genesisBlock, blockWithOneTxC, PegTestUtils.createHash3(), coinbaseE, Lists.newArrayList(blockWithOneTxB.getHeader(), blockWithOneTxD.getHeader()), minerFee, 2, txValue, cowKey);
blocks.add(blockThatIncludesUnclesE);
blocks.addAll(createSimpleBlocks(blockThatIncludesUnclesE, 7));
BlockExecutor blockExecutor = new BlockExecutor(config, blockchain.getRepository(), null, blockchain.getBlockStore(), null);
for (Block b : blocks) {
blockExecutor.executeAndFillAll(b, blockchain.getBestBlock());
blockchain.tryToConnect(b);
}
// 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(blockchain.getRepository(), cowRemainingBalance, minerFee * NUMBER_OF_TXS_WITH_FEES, null, this.getAccountsWithExpectedBalance(otherAccountsBalance));
this.validateRemascsStorageIsCorrect(this.getRemascStorageProvider(blockchain), 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(), null, minerFee, 3, txValue, cowKey);
blockExecutor.executeAndFillAll(blockToPayFeesOnHeightFour, blockchain.getBestBlock());
blockchain.tryToConnect(blockToPayFeesOnHeightFour);
Repository repository = blockchain.getRepository();
// -- 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);
// 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(this.getRemascStorageProvider(blockchain), 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(), null, minerFee, 4, txValue, cowKey);
blockExecutor.executeAndFillAll(blockToPayFeesOnHeightFive, blockchain.getBestBlock());
blockchain.tryToConnect(blockToPayFeesOnHeightFive);
repository = blockchain.getRepository();
// -- 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(this.getRemascStorageProvider(blockchain), expectedRewardBalance, expectedBurnedBalance.add(Coin.valueOf(1)), 0L);
this.validateFederatorsBalanceIsCorrect(blockchain.getRepository(), federationReward + federationReward2);
}
use of co.rsk.core.bc.BlockExecutor in project rskj by rsksmart.
the class RemascProcessMinerFeesTest method processMinersFeesWithoutMinimumSyntheticSpan.
@Test
public void processMinersFeesWithoutMinimumSyntheticSpan() throws IOException {
BlockChainBuilder builder = new BlockChainBuilder();
Blockchain blockchain = builder.setTesting(true).setGenesis(genesisBlock).build();
List<Block> blocks = createSimpleBlocks(genesisBlock, 2);
Block blockWithOneTx = RemascTestRunner.createBlock(this.genesisBlock, blocks.get(blocks.size() - 1), PegTestUtils.createHash3(), coinbaseA, null, minerFee, 0, txValue, cowKey);
blocks.add(blockWithOneTx);
blocks.addAll(createSimpleBlocks(blockWithOneTx, 9));
BlockExecutor blockExecutor = new BlockExecutor(config, blockchain.getRepository(), null, blockchain.getBlockStore(), null);
for (Block b : blocks) {
blockExecutor.executeAndFillAll(b, blockchain.getBestBlock());
blockchain.tryToConnect(b);
}
assertEquals(cowInitialBalance.subtract(Coin.valueOf(minerFee + txValue)), blockchain.getRepository().getAccountState(new RskAddress(cowAddress)).getBalance());
Repository repository = blockchain.getRepository();
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(), null, null);
blockExecutor.executeAndFillAll(newblock, blockchain.getBestBlock());
blockchain.tryToConnect(newblock);
repository = blockchain.getRepository();
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(blockchain);
assertEquals(Coin.valueOf(minerFee), remascStorageProvider.getRewardBalance());
assertEquals(Coin.ZERO, remascStorageProvider.getBurnedBalance());
assertEquals(0, remascStorageProvider.getSiblings().size());
}
Aggregations