use of co.rsk.core.Coin in project rskj by rsksmart.
the class Remasc method processMinersFees.
/**
* Implements the actual Remasc distribution logic
*/
void processMinersFees() throws IOException, BlockStoreException {
if (!(executionTx instanceof RemascTransaction)) {
// 2) invocation to remasc from another contract (ie call opcode)
throw new RemascInvalidInvocationException("Invoked Remasc outside last tx of the block");
}
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;
}
Block processingBlock = blockStore.getBlockByHashAndDepth(executionBlock.getParentHash().getBytes(), remascConstants.getMaturity() - 1);
BlockHeader processingBlockHeader = processingBlock.getHeader();
// Adds current block fees to accumulated rewardBalance
Coin processingBlockReward = processingBlockHeader.getPaidFees();
Coin rewardBalance = provider.getRewardBalance();
rewardBalance = rewardBalance.add(processingBlockReward);
provider.setRewardBalance(rewardBalance);
if (processingBlockNumber - remascConstants.getSyntheticSpan() < 0) {
logger.debug("First block has not reached maturity+syntheticSpan yet, current block is {}", executionBlock.getNumber());
return;
}
// Takes from rewardBalance this block's height reward.
Coin fullBlockReward = rewardBalance.divide(BigInteger.valueOf(remascConstants.getSyntheticSpan()));
rewardBalance = rewardBalance.subtract(fullBlockReward);
provider.setRewardBalance(rewardBalance);
// Pay RSK labs cut
Coin payToRskLabs = fullBlockReward.divide(BigInteger.valueOf(remascConstants.getRskLabsDivisor()));
feesPayer.payMiningFees(processingBlockHeader.getHash().getBytes(), payToRskLabs, remascConstants.getRskLabsAddress(), logs);
fullBlockReward = fullBlockReward.subtract(payToRskLabs);
// TODO to improve
// this type choreography is only needed because the RepositoryTrack support the
// get snapshot to method
Repository processingRepository = ((RepositoryTrack) repository).getOriginRepository().getSnapshotTo(processingBlockHeader.getStateRoot());
// TODO to improve
// and we need a RepositoryTrack to feed RemascFederationProvider
// because it supports the update of bytes (notably, RepositoryImpl don't)
// the update of bytes is needed, because BridgeSupport creation could alter
// the storage when getChainHead is null (specially in production)
processingRepository = processingRepository.startTracking();
BridgeSupport bridgeSupport = new BridgeSupport(config, processingRepository, null, PrecompiledContracts.BRIDGE_ADDR, processingBlock);
RemascFederationProvider federationProvider = new RemascFederationProvider(bridgeSupport);
Coin payToFederation = fullBlockReward.divide(BigInteger.valueOf(remascConstants.getFederationDivisor()));
byte[] processingBlockHash = processingBlockHeader.getHash().getBytes();
int nfederators = federationProvider.getFederationSize();
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++) {
RskAddress federatorAddress = federationProvider.getFederatorAddress(k);
if (k == nfederators - 1 && restToLastFederator.compareTo(Coin.ZERO) > 0) {
feesPayer.payMiningFees(processingBlockHash, payToFederator.add(restToLastFederator), federatorAddress, logs);
} else {
feesPayer.payMiningFees(processingBlockHash, payToFederator, federatorAddress, logs);
}
paidToFederation = paidToFederation.add(payToFederator);
}
fullBlockReward = fullBlockReward.subtract(payToFederation);
List<Sibling> siblings = provider.getSiblings().get(processingBlockNumber);
if (CollectionUtils.isNotEmpty(siblings)) {
// Block has siblings, reward distribution is more complex
boolean previousBrokenSelectionRule = provider.getBrokenSelectionRule();
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 = fullBlockReward.divide(BigInteger.valueOf(remascConstants.getPunishmentDivisor()));
fullBlockReward = fullBlockReward.subtract(punishment);
provider.setBurnedBalance(provider.getBurnedBalance().add(punishment));
}
feesPayer.payMiningFees(processingBlockHeader.getHash().getBytes(), fullBlockReward, processingBlockHeader.getCoinbase(), logs);
provider.setBrokenSelectionRule(Boolean.FALSE);
}
this.removeUsedSiblings(processingBlockHeader);
}
use of co.rsk.core.Coin in project rskj by rsksmart.
the class Remasc method payIncludedSiblings.
private void payIncludedSiblings(byte[] blockHash, List<Sibling> siblings, Coin topReward) {
long perLateBlockPunishmentDivisor = remascConstants.getLateUncleInclusionPunishmentDivisor();
for (Sibling sibling : siblings) {
long processingBlockNumber = executionBlock.getNumber() - remascConstants.getMaturity();
long numberOfBlocksLate = sibling.getIncludedHeight() - processingBlockNumber - 1L;
Coin lateInclusionPunishment = topReward.multiply(BigInteger.valueOf(numberOfBlocksLate)).divide(BigInteger.valueOf(perLateBlockPunishmentDivisor));
feesPayer.payMiningFees(blockHash, topReward.subtract(lateInclusionPunishment), sibling.getCoinbase(), logs);
provider.addToBurnBalance(lateInclusionPunishment);
}
}
use of co.rsk.core.Coin in project rskj by rsksmart.
the class RemascState method create.
public static RemascState create(byte[] data) {
RLPList rlpList = (RLPList) RLP.decode2(data).get(0);
Coin rlpRewardBalance = RLP.parseCoin(rlpList.get(0).getRLPData());
Coin rlpBurnedBalance = RLP.parseCoin(rlpList.get(1).getRLPData());
SortedMap<Long, List<Sibling>> rlpSiblings = RemascStorageProvider.getSiblingsFromBytes(rlpList.get(2).getRLPData());
byte[] rlpBrokenSelectionRuleBytes = rlpList.get(3).getRLPData();
Boolean rlpBrokenSelectionRule;
if (rlpBrokenSelectionRuleBytes != null && rlpBrokenSelectionRuleBytes.length != 0 && rlpBrokenSelectionRuleBytes[0] != 0) {
rlpBrokenSelectionRule = Boolean.TRUE;
} else {
rlpBrokenSelectionRule = Boolean.FALSE;
}
return new RemascState(rlpRewardBalance, rlpBurnedBalance, rlpSiblings, rlpBrokenSelectionRule);
}
use of co.rsk.core.Coin in project rskj by rsksmart.
the class RemascStorageProvider method getBurnedBalance.
public Coin getBurnedBalance() {
if (burnedBalance != null) {
return burnedBalance;
}
DataWord address = new DataWord(BURNED_BALANCE_KEY.getBytes(StandardCharsets.UTF_8));
DataWord value = this.repository.getStorageValue(this.contractAddress, address);
if (value == null) {
return Coin.ZERO;
}
return new Coin(value.getData());
}
use of co.rsk.core.Coin in project rskj by rsksmart.
the class Sibling method create.
public static Sibling create(byte[] data) {
ArrayList<RLPElement> params = RLP.decode2(data);
RLPList sibling = (RLPList) params.get(0);
byte[] hash = sibling.get(0).getRLPData();
RskAddress coinbase = RLP.parseRskAddress(sibling.get(1).getRLPData());
RskAddress includedBlockCoinbase = RLP.parseRskAddress(sibling.get(2).getRLPData());
Coin paidFees = RLP.parseCoin(sibling.get(3).getRLPData());
byte[] bytesIncludedHeight = sibling.get(4).getRLPData();
RLPElement uncleCountElement = sibling.get(5);
byte[] bytesUncleCount = uncleCountElement != null ? uncleCountElement.getRLPData() : null;
long includedHeight = bytesIncludedHeight == null ? 0 : BigIntegers.fromUnsignedByteArray(bytesIncludedHeight).longValue();
int uncleCount = bytesUncleCount == null ? 0 : BigIntegers.fromUnsignedByteArray(bytesUncleCount).intValue();
return new Sibling(hash, coinbase, includedBlockCoinbase, paidFees, includedHeight, uncleCount);
}
Aggregations