Skip to content

Commit

Permalink
Merge pull request #604 from rsksmart/revert_pr_586
Browse files Browse the repository at this point in the history
Revert PR #586 for not including in upcoming release
  • Loading branch information
diega authored Jun 28, 2018
2 parents 4e0f9a5 + 468a1f9 commit d6a711b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 71 deletions.
97 changes: 27 additions & 70 deletions rskj-core/src/main/java/co/rsk/remasc/Remasc.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import co.rsk.core.Coin;
import co.rsk.core.RskAddress;
import co.rsk.core.bc.SelectionRule;
import org.apache.commons.collections4.CollectionUtils;
import org.ethereum.core.Block;
import org.ethereum.core.BlockHeader;
import org.ethereum.core.Repository;
Expand All @@ -36,9 +37,7 @@
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
* Implements the actual Remasc distribution logic
Expand Down Expand Up @@ -83,7 +82,6 @@ public RemascState getStateForDebugging() {
return new RemascState(this.provider.getRewardBalance(), this.provider.getBurnedBalance(), this.provider.getSiblings(), this.provider.getBrokenSelectionRule());
}


/**
* Implements the actual Remasc distribution logic
*/
Expand All @@ -94,38 +92,17 @@ void processMinersFees() throws IOException, BlockStoreException {
// 2) invocation to remasc from another contract (ie call opcode)
throw new RemascInvalidInvocationException("Invoked Remasc outside last tx of the block");
}

// This is not necessary but maintained for consensus reasons before we do a network upgrade
this.addNewSiblings();

long blockNbr = executionBlock.getNumber();

long processingBlockNumber = blockNbr - remascConstants.getMaturity();
if (processingBlockNumber < 1 ) {
logger.debug("First block has not reached maturity yet, current block is {}", blockNbr);
return;
}

int uncleGenerationLimit = config.getBlockchainConfig().getCommonConstants().getUncleGenerationLimit();
List<Block> descendantsBlocks = new ArrayList<>(uncleGenerationLimit);

// this search can be optimized if have certainty that the execution block is not in a fork
// larger than depth
Block currentBlock = blockStore.getBlockByHashAndDepth(
executionBlock.getParentHash().getBytes(),
remascConstants.getMaturity() - 1 - uncleGenerationLimit
);
descendantsBlocks.add(currentBlock);

for (int i = 0; i < uncleGenerationLimit - 1; i++) {
currentBlock = blockStore.getBlockByHash(currentBlock.getParentHash().getBytes());
descendantsBlocks.add(currentBlock);
}

// descendants are reversed because the original order to pay siblings is defined in the way
// blocks are ordered in the blockchain (the same as were stored in remasc contract)
Collections.reverse(descendantsBlocks);

Block processingBlock = blockStore.getBlockByHash(currentBlock.getParentHash().getBytes());
Block processingBlock = blockStore.getBlockByHashAndDepth(executionBlock.getParentHash().getBytes(), remascConstants.getMaturity() - 1);
BlockHeader processingBlockHeader = processingBlock.getHeader();

// Adds current block fees to accumulated rewardBalance
Expand All @@ -140,24 +117,23 @@ void processMinersFees() throws IOException, BlockStoreException {
}

// Takes from rewardBalance this block's height reward.
Coin syntheticReward = rewardBalance.divide(BigInteger.valueOf(remascConstants.getSyntheticSpan()));
rewardBalance = rewardBalance.subtract(syntheticReward);
Coin fullBlockReward = rewardBalance.divide(BigInteger.valueOf(remascConstants.getSyntheticSpan()));
rewardBalance = rewardBalance.subtract(fullBlockReward);
provider.setRewardBalance(rewardBalance);

// Pay RSK labs cut
Coin payToRskLabs = syntheticReward.divide(BigInteger.valueOf(remascConstants.getRskLabsDivisor()));
Coin payToRskLabs = fullBlockReward.divide(BigInteger.valueOf(remascConstants.getRskLabsDivisor()));
feesPayer.payMiningFees(processingBlockHeader.getHash().getBytes(), payToRskLabs, remascConstants.getRskLabsAddress(), logs);
syntheticReward = syntheticReward.subtract(payToRskLabs);
fullBlockReward = fullBlockReward.subtract(payToRskLabs);

RemascFederationProvider federationProvider = new RemascFederationProvider(config, repository, processingBlock);

Coin payToFederation = syntheticReward.divide(BigInteger.valueOf(remascConstants.getFederationDivisor()));
Coin payToFederation = fullBlockReward.divide(BigInteger.valueOf(remascConstants.getFederationDivisor()));

byte[] processingBlockHash = processingBlockHeader.getHash().getBytes();
int nfederators = federationProvider.getFederationSize();
Coin[] payAndRemainderToFederator = payToFederation.divideAndRemainder(BigInteger.valueOf(nfederators));
Coin payToFederator = payAndRemainderToFederator[0];
Coin restToLastFederator = payAndRemainderToFederator[1];
Coin payToFederator = payToFederation.divide(BigInteger.valueOf(nfederators));
Coin restToLastFederator = payToFederation.subtract(payToFederator.multiply(BigInteger.valueOf(nfederators)));
Coin paidToFederation = Coin.ZERO;

for (int k = 0; k < nfederators; k++) {
Expand All @@ -172,31 +148,30 @@ void processMinersFees() throws IOException, BlockStoreException {
paidToFederation = paidToFederation.add(payToFederator);
}

syntheticReward = syntheticReward.subtract(payToFederation);
fullBlockReward = fullBlockReward.subtract(payToFederation);

List<Sibling> siblings = provider.getSiblings().get(processingBlockNumber);

List<Sibling> siblings = getSiblingsToReward(descendantsBlocks, processingBlockNumber);
if (!siblings.isEmpty()) {
if (CollectionUtils.isNotEmpty(siblings)) {
// Block has siblings, reward distribution is more complex
boolean previousBrokenSelectionRule = provider.getBrokenSelectionRule();
this.payWithSiblings(processingBlockHeader, syntheticReward, siblings, previousBrokenSelectionRule);
this.payWithSiblings(processingBlockHeader, fullBlockReward, siblings, previousBrokenSelectionRule);
boolean brokenSelectionRule = SelectionRule.isBrokenSelectionRule(processingBlockHeader, siblings);
provider.setBrokenSelectionRule(brokenSelectionRule);
} else {
if (provider.getBrokenSelectionRule()) {
// broken selection rule, apply punishment, ie burn part of the reward.
Coin punishment = syntheticReward.divide(BigInteger.valueOf(remascConstants.getPunishmentDivisor()));
syntheticReward = syntheticReward.subtract(punishment);
Coin punishment = fullBlockReward.divide(BigInteger.valueOf(remascConstants.getPunishmentDivisor()));
fullBlockReward = fullBlockReward.subtract(punishment);
provider.setBurnedBalance(provider.getBurnedBalance().add(punishment));
}
feesPayer.payMiningFees(processingBlockHeader.getHash().getBytes(), syntheticReward, processingBlockHeader.getCoinbase(), logs);
feesPayer.payMiningFees(processingBlockHeader.getHash().getBytes(), fullBlockReward, processingBlockHeader.getCoinbase(), logs);
provider.setBrokenSelectionRule(Boolean.FALSE);
}

// This is not necessary but maintained for consensus reasons before we do a network upgrade
this.removeUsedSiblings(processingBlockHeader);
}


/**
* Remove siblings just processed if any
*/
Expand All @@ -210,37 +185,19 @@ private void removeUsedSiblings(BlockHeader processingBlockHeader) {
private void addNewSiblings() {
// Add uncles of the execution block to the siblings map
List<BlockHeader> uncles = executionBlock.getUncleList();
if (uncles == null) {
return;
}

for (BlockHeader uncleHeader : uncles) {
List<Sibling> siblings = provider.getSiblings().get(uncleHeader.getNumber());
if (siblings == null) {
siblings = new ArrayList<>();
if (CollectionUtils.isNotEmpty(uncles)) {
for (BlockHeader uncleHeader : uncles) {
List<Sibling> siblings = provider.getSiblings().get(uncleHeader.getNumber());
if (siblings == null) {
siblings = new ArrayList<>();
}

siblings.add(new Sibling(uncleHeader, executionBlock.getHeader().getCoinbase(), executionBlock.getNumber()));
provider.getSiblings().put(uncleHeader.getNumber(), siblings);
}

siblings.add(new Sibling(uncleHeader, executionBlock.getHeader().getCoinbase(), executionBlock.getNumber()));
provider.getSiblings().put(uncleHeader.getNumber(), siblings);
}
}

/**
* Descendants included on the same chain as the processing block could include siblings
* that should be rewarded when fees on this block are paid
* @param descendants blocks in the same blockchain that may include rewarded siblings
* @param blockNumber number of the block is looked for siblings
* @return
*/
private List<Sibling> getSiblingsToReward(List<Block> descendants, long blockNumber) {
return descendants.stream()
.flatMap(block -> block.getUncleList().stream()
.filter(header -> header.getNumber() == blockNumber)
.map(header -> new Sibling(header, block.getCoinbase(), block.getNumber()))
)
.collect(Collectors.toList());
}

/**
* Pay the mainchain block miner, its siblings miners and the publisher miners
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class IndexedBlockStore extends AbstractBlockstore {

private static final Logger logger = LoggerFactory.getLogger("general");

private final BlockCache blockCache = new BlockCache(50000);
private final BlockCache blockCache = new BlockCache(5000);

private final Map<Long, List<BlockInfo>> index;
private final DB indexDB;
Expand Down

0 comments on commit d6a711b

Please sign in to comment.