Skip to content

Commit

Permalink
Merge pull request #147 from ltonetwork/juicy-fix-fork
Browse files Browse the repository at this point in the history
Fix for JUICY fork when synced from genesis
  • Loading branch information
jasny authored Apr 30, 2022
2 parents 035c21f + b58d67c commit 254edd0
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 24 deletions.
10 changes: 3 additions & 7 deletions src/main/scala/com/ltonetwork/block/Block.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.ltonetwork.state._
import com.ltonetwork.transaction.ValidationError.GenericError
import com.ltonetwork.transaction._
import com.ltonetwork.transaction.genesis.GenesisTransaction
import com.ltonetwork.utils.ScorexLogging
import com.ltonetwork.utils.{Fraction, ScorexLogging}
import monix.eval.Coeval
import play.api.libs.json.{JsObject, Json}
import scorex.crypto.signatures.Curve25519._
Expand Down Expand Up @@ -72,12 +72,8 @@ case class Block private (override val timestamp: Long,
}

object Block extends ScorexLogging {

case class Fraction(dividend: Int, divider: Int) {
def apply(l: Long): Long = l / divider * dividend
}

val CurrentBlockFeePart: Fraction = Fraction(2, 5)
val OpenerBlockFeePart: Fraction = Fraction.roundDown(2, 5)
val CloserBlockFeePart: Fraction = Fraction.roundUp(3, 5)

type BlockIds = Seq[ByteStr]
type BlockId = ByteStr
Expand Down
18 changes: 11 additions & 7 deletions src/main/scala/com/ltonetwork/block/BlockRewardCalculator.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.ltonetwork.block
import cats.Monoid
import com.ltonetwork.block.Block.CurrentBlockFeePart
import com.ltonetwork.block.Block.{CloserBlockFeePart, OpenerBlockFeePart}
import com.ltonetwork.features.BlockchainFeatures
import com.ltonetwork.features.FeatureProvider._
import com.ltonetwork.fee.FeeCalculator
Expand All @@ -26,11 +26,13 @@ object BlockRewardCalculator {
Portfolio(balance = Math.min(maxMiningReward(settings, bc, height), bc.burned(height)))
def miningReward(settings: FunctionalitySettings, bc: Blockchain): Portfolio = miningReward(settings, bc, bc.height)

def rewardedFee(bc: Blockchain, height: Int, tx: Transaction): Portfolio = {
// During activation of burnfeeture, where only fee was only burned for closer.
def rewardedFee(bc: Blockchain, height: Int, tx: Transaction): Portfolio = rewardedFee(bc, height, tx, 1)
private def rewardedFee(bc: Blockchain, height: Int, tx: Transaction, burnFeetureOffset: Int): Portfolio = {
Portfolio(balance = {
if (bc.isFeatureActivated(BlockchainFeatures.Juicy, height))
(FeeCalculator(bc).fee(height, tx) * (1 - feeBurnPct)).toLong
else if (bc.isFeatureActivated(BlockchainFeatures.BurnFeeture, height))
else if (bc.isFeatureActivated(BlockchainFeatures.BurnFeeture, height - burnFeetureOffset))
Math.max(tx.fee - feeBurnAmt, 0)
else
tx.fee
Expand All @@ -40,8 +42,11 @@ object BlockRewardCalculator {
def burnedFee(bc: Blockchain, height: Int, tx: Transaction): Long =
if (bc.isFeatureActivated(BlockchainFeatures.Juicy, height))
(FeeCalculator(bc).fee(height, tx) * feeBurnPct).toLong
else if (bc.isFeatureActivated(BlockchainFeatures.BurnFeeture, height))
else if (bc.isFeatureActivated(BlockchainFeatures.BurnFeeture, height - 1))
Math.min(tx.fee, feeBurnAmt)
else if (bc.featureActivationHeight(BlockchainFeatures.BurnFeeture).contains(height))
// During activation of burnfeeture, where only fee was only burned for closer.
CloserBlockFeePart(Math.min(tx.fee, feeBurnAmt))
else
0L

Expand All @@ -55,12 +60,11 @@ object BlockRewardCalculator {

def openerBlockFee(bc: Blockchain, height: Int, block: Block): Portfolio =
Monoid[Portfolio].combineAll(block.transactionData.map { tx =>
val fees = rewardedFee(bc, height, tx)
fees.minus(fees.multiply(CurrentBlockFeePart))
rewardedFee(bc, height, tx).multiply(OpenerBlockFeePart)
})

def closerBlockFee(bc: Blockchain, height: Int, block: Block): Portfolio =
Monoid[Portfolio].combineAll(block.transactionData.map { tx =>
rewardedFee(bc, height, tx).multiply(CurrentBlockFeePart)
rewardedFee(bc, height, tx, 0).multiply(CloserBlockFeePart)
})
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ltonetwork.database.migration
import com.ltonetwork.account.Address
import com.ltonetwork.block.Block.{CloserBlockFeePart, OpenerBlockFeePart}
import com.ltonetwork.block.{Block, BlockRewardCalculator}
import com.ltonetwork.database.Keys
import com.ltonetwork.features.BlockchainFeatures
Expand All @@ -16,7 +17,8 @@ case class CalculateBurnMigration(writableDB: DB, fs: FunctionalitySettings) ext

var burned: Long = 0L

val burnFeetureHeight: Int = readOnly(_.get(Keys.activatedFeatures)).getOrElse(BlockchainFeatures.BurnFeeture.id, Int.MaxValue)
val burnFeetureHeight: Int = readOnly(_.get(Keys.activatedFeatures))
.getOrElse(BlockchainFeatures.BurnFeeture.id, Int.MaxValue)

def isBurnAddress(address: Address): Boolean = fs.burnAddresses.contains(address.toString)

Expand All @@ -31,8 +33,10 @@ case class CalculateBurnMigration(writableDB: DB, fs: FunctionalitySettings) ext
}).toLong)

protected def transactionBurn(height: Int, block: Block): Long =
if (height >= burnFeetureHeight)
if (height > burnFeetureHeight)
block.transactionCount * BlockRewardCalculator.feeBurnAmt
else if (height == burnFeetureHeight)
CloserBlockFeePart(block.transactionCount * BlockRewardCalculator.feeBurnAmt)
else
0L

Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/com/ltonetwork/state/Portfolio.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.ltonetwork.state

import cats._
import com.ltonetwork.block.Block.Fraction
import com.ltonetwork.utils.Fraction

case class Portfolio(balance: Long, lease: LeaseBalance) {
lazy val effectiveBalance: Long = safeSum(balance, lease.in) - lease.out
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/com/ltonetwork/state/diffs/BlockDiffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.ltonetwork.state.diffs
import cats.Monoid
import cats.implicits._
import com.ltonetwork.account.Address
import com.ltonetwork.block.Block.CurrentBlockFeePart
import com.ltonetwork.block.Block.OpenerBlockFeePart
import com.ltonetwork.block.{Block, BlockRewardCalculator, MicroBlock}
import com.ltonetwork.metrics.Instrumented
import com.ltonetwork.mining.MiningConstraint
Expand All @@ -30,7 +30,7 @@ object BlockDiffer extends ScorexLogging with Instrumented {
val miningReward = BlockRewardCalculator.miningReward(settings, blockchain)
val initDiff = Diff.empty.copy(
portfolios = Map(blockGenerator.toAddress -> Monoid[Portfolio].combine(
maybePrevBlock.map(b => BlockRewardCalculator.openerBlockFee(blockchain, stateHeight, b)).orEmpty, // NG reward for closing block
maybePrevBlock.map(b => BlockRewardCalculator.closerBlockFee(blockchain, stateHeight, b)).orEmpty, // NG reward for closing block
miningReward,
)),
burned = -1 * miningReward.balance
Expand Down Expand Up @@ -102,7 +102,7 @@ object BlockDiffer extends ScorexLogging with Instrumented {
else
txDiffer(updatedBlockchain, tx).map { newDiff =>
val updatedDiff = currDiff.combine(newDiff)
val curBlockFees = BlockRewardCalculator.rewardedFee(blockchain, currentBlockHeight, tx).multiply(CurrentBlockFeePart)
val curBlockFees = BlockRewardCalculator.rewardedFee(blockchain, currentBlockHeight, tx).multiply(OpenerBlockFeePart)
val burnedFees = BlockRewardCalculator.burnedFee(blockchain, currentBlockHeight, tx)
val diff = updatedDiff.combine(Diff.empty.copy(
portfolios = Map(blockGenerator -> curBlockFees),
Expand Down
19 changes: 19 additions & 0 deletions src/main/scala/com/ltonetwork/utils/Fraction.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.ltonetwork.utils

trait Fraction {
def apply(l: Long): Long;
}

object Fraction {
private case class RoundDownFraction(dividend: Int, divider: Int) extends Fraction {
def apply(l: Long): Long = l / divider * dividend
}

private case class RoundUpFraction(dividend: Int, divider: Int) extends Fraction {
private val inv = RoundDownFraction(divider - dividend, divider)
def apply(l: Long): Long = l - inv(l)
}

def roundDown(dividend: Int, divider: Int): Fraction = RoundDownFraction(dividend, divider)
def roundUp(dividend: Int, divider: Int): Fraction = RoundUpFraction(dividend, divider)
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class SponsoredTransactionDiffTest
d.portfolios(sponsorship.sender.toAddress).balance shouldBe (-transfer.fee)
d.portfolios(transfer.sender.toAddress).balance shouldBe (-transfer.amount)
d.portfolios(transfer.recipient).balance shouldBe transfer.amount
val fees = Block.CurrentBlockFeePart(transfer.fee) + sponsorship.fee - Block.CurrentBlockFeePart(sponsorship.fee)
val fees = Block.OpenerBlockFeePart(transfer.fee) + sponsorship.fee - Block.OpenerBlockFeePart(sponsorship.fee)
d.portfolios(TestBlock.defaultSigner).balance shouldBe fees
b.sponsorOf(transfer.sender.toAddress) shouldBe List(sponsorship.sender.toAddress)
}
Expand Down Expand Up @@ -159,7 +159,7 @@ class SponsoredTransactionDiffTest
d.portfolios(sponsor.toAddress).balance shouldBe (-transfer.fee)
d.portfolios(sponsoredTransfer.sender.toAddress).balance shouldBe (-transfer.amount)
d.portfolios(sponsoredTransfer.recipient).balance shouldBe transfer.amount
val fees = Block.CurrentBlockFeePart(sponsoredTransfer.fee)
val fees = Block.OpenerBlockFeePart(sponsoredTransfer.fee)
d.portfolios(TestBlock.defaultSigner).balance shouldBe fees
}
}
Expand All @@ -175,7 +175,7 @@ class SponsoredTransactionDiffTest
d.portfolios(sponsor.toAddress).balance shouldBe (-transfer.fee)
d.portfolios(sponsoredTransfer.sender.toAddress).balance shouldBe (-transfer.amount)
d.portfolios(sponsoredTransfer.recipient).balance shouldBe transfer.amount
val fees = Block.CurrentBlockFeePart(transfer.fee) + sponsorship.fee - Block.CurrentBlockFeePart(sponsorship.fee)
val fees = Block.OpenerBlockFeePart(transfer.fee) + sponsorship.fee - Block.OpenerBlockFeePart(sponsorship.fee)
d.portfolios(TestBlock.defaultSigner).balance shouldBe fees
b.sponsorOf(transfer.sender.toAddress) shouldBe List(sponsorship.sender.toAddress)
}
Expand All @@ -195,7 +195,7 @@ class SponsoredTransactionDiffTest
d.portfolios(sponsor.toAddress).balance shouldBe (-transfer.fee)
d.portfolios(sponsoredTransfer.sender.toAddress).balance shouldBe (-transfer.amount)
d.portfolios(sponsoredTransfer.recipient).balance shouldBe transfer.amount
val fees = Block.CurrentBlockFeePart(transfer.fee) + setScript.fee - Block.CurrentBlockFeePart(setScript.fee)
val fees = Block.OpenerBlockFeePart(transfer.fee) + setScript.fee - Block.OpenerBlockFeePart(setScript.fee)
d.portfolios(TestBlock.defaultSigner).balance shouldBe fees
}
}
Expand Down

0 comments on commit 254edd0

Please sign in to comment.