summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTolik Zinovyev <tolik@algorand.com>2022-01-19 16:13:57 -0500
committerGitHub <noreply@github.com>2022-01-19 16:13:57 -0500
commit2edd3decd1066696a08a90b48e2cfcee11b90323 (patch)
tree35796acd21a71ed8528cb70cdd51f260536e8397
parent4006ce219ebcebbb65c621b9f04362b45b256065 (diff)
ledger: fix `NextRewardsState()` (#3403)
## Summary A modification of #3336. Added a new test where the rewards pool overspends and proposed a fix in `NextRewardsState()` requiring a consensus upgrade. ## Test Plan This is mostly tests.
-rw-r--r--config/consensus.go5
-rw-r--r--daemon/algod/api/server/v2/test/handlers_test.go2
-rw-r--r--data/bookkeeping/block.go25
-rw-r--r--data/bookkeeping/block_test.go322
-rw-r--r--ledger/internal/eval.go4
-rw-r--r--ledger/ledger_test.go6
6 files changed, 342 insertions, 22 deletions
diff --git a/config/consensus.go b/config/consensus.go
index 1f553d20e..1bd7bd774 100644
--- a/config/consensus.go
+++ b/config/consensus.go
@@ -394,6 +394,9 @@ type ConsensusParams struct {
// MaxProposedExpiredOnlineAccounts is the maximum number of online accounts, which need
// to be taken offline, that would be proposed to be taken offline.
MaxProposedExpiredOnlineAccounts int
+
+ // When rewards rate changes, use the new value immediately.
+ RewardsCalculationFix bool
}
// PaysetCommitType enumerates possible ways for the block header to commit to
@@ -1054,6 +1057,8 @@ func initConsensusProtocols() {
vFuture.MaxProposedExpiredOnlineAccounts = 32
+ vFuture.RewardsCalculationFix = true
+
Consensus[protocol.ConsensusFuture] = vFuture
}
diff --git a/daemon/algod/api/server/v2/test/handlers_test.go b/daemon/algod/api/server/v2/test/handlers_test.go
index 0b416eaa5..9af675fa9 100644
--- a/daemon/algod/api/server/v2/test/handlers_test.go
+++ b/daemon/algod/api/server/v2/test/handlers_test.go
@@ -177,7 +177,7 @@ func TestGetBlockJsonEncoding(t *testing.T) {
Round: l.Latest() + 1,
Branch: genBlk.Hash(),
TimeStamp: 0,
- RewardsState: genBlk.NextRewardsState(l.Latest()+1, proto, poolBal.MicroAlgos, totalRewardUnits),
+ RewardsState: genBlk.NextRewardsState(l.Latest()+1, proto, poolBal.MicroAlgos, totalRewardUnits, logging.Base()),
UpgradeState: genBlk.UpgradeState,
}
diff --git a/data/bookkeeping/block.go b/data/bookkeeping/block.go
index f75c08386..29a3f274d 100644
--- a/data/bookkeeping/block.go
+++ b/data/bookkeeping/block.go
@@ -285,17 +285,17 @@ func (block *Block) Seed() committee.Seed {
// NextRewardsState computes the RewardsState of the subsequent round
// given the subsequent consensus parameters, along with the incentive pool
// balance and the total reward units in the system as of the current round.
-func (s RewardsState) NextRewardsState(nextRound basics.Round, nextProto config.ConsensusParams, incentivePoolBalance basics.MicroAlgos, totalRewardUnits uint64) (res RewardsState) {
+func (s RewardsState) NextRewardsState(nextRound basics.Round, nextProto config.ConsensusParams, incentivePoolBalance basics.MicroAlgos, totalRewardUnits uint64, log logging.Logger) (res RewardsState) {
res = s
- if nextRound == s.RewardsRecalculationRound {
+ if nextRound == res.RewardsRecalculationRound {
maxSpentOver := nextProto.MinBalance
overflowed := false
if nextProto.PendingResidueRewards {
- maxSpentOver, overflowed = basics.OAdd(maxSpentOver, s.RewardsResidue)
+ maxSpentOver, overflowed = basics.OAdd(maxSpentOver, res.RewardsResidue)
if overflowed {
- logging.Base().Errorf("overflowed when trying to accumulate MinBalance(%d) and RewardsResidue(%d) for round %d (state %+v)", nextProto.MinBalance, s.RewardsResidue, nextRound, s)
+ log.Errorf("overflowed when trying to accumulate MinBalance(%d) and RewardsResidue(%d) for round %d (state %+v)", nextProto.MinBalance, res.RewardsResidue, nextRound, s)
// this should never happen, but if it does, adjust the maxSpentOver so that we will have no rewards.
maxSpentOver = incentivePoolBalance.Raw
}
@@ -304,7 +304,7 @@ func (s RewardsState) NextRewardsState(nextRound basics.Round, nextProto config.
// it is time to refresh the rewards rate
newRate, overflowed := basics.OSub(incentivePoolBalance.Raw, maxSpentOver)
if overflowed {
- logging.Base().Errorf("overflowed when trying to refresh RewardsRate for round %v (state %+v)", nextRound, s)
+ log.Errorf("overflowed when trying to refresh RewardsRate for round %v (state %+v)", nextRound, s)
newRate = 0
}
@@ -317,14 +317,21 @@ func (s RewardsState) NextRewardsState(nextRound basics.Round, nextProto config.
return
}
+ var rewardsRate uint64
+ if nextProto.RewardsCalculationFix {
+ rewardsRate = res.RewardsRate
+ } else {
+ rewardsRate = s.RewardsRate
+ }
+
var ot basics.OverflowTracker
- rewardsWithResidue := ot.Add(s.RewardsRate, s.RewardsResidue)
- nextRewardLevel := ot.Add(s.RewardsLevel, rewardsWithResidue/totalRewardUnits)
+ rewardsWithResidue := ot.Add(rewardsRate, res.RewardsResidue)
+ nextRewardLevel := ot.Add(res.RewardsLevel, rewardsWithResidue/totalRewardUnits)
nextResidue := rewardsWithResidue % totalRewardUnits
if ot.Overflowed {
- logging.Base().Errorf("could not compute next reward level (current level %v, adding %v MicroAlgos in total, number of reward units %v) using old level",
- s.RewardsLevel, s.RewardsRate, totalRewardUnits)
+ log.Errorf("could not compute next reward level (current level %v, adding %v MicroAlgos in total, number of reward units %v) using old level",
+ res.RewardsLevel, rewardsRate, totalRewardUnits)
return
}
diff --git a/data/bookkeeping/block_test.go b/data/bookkeeping/block_test.go
index 078a0b253..2956edb12 100644
--- a/data/bookkeeping/block_test.go
+++ b/data/bookkeeping/block_test.go
@@ -17,15 +17,19 @@
package bookkeeping
import (
+ "bytes"
+ "math"
"testing"
"time"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/transactions"
+ "github.com/algorand/go-algorand/logging"
"github.com/algorand/go-algorand/protocol"
"github.com/algorand/go-algorand/test/partitiontest"
)
@@ -248,20 +252,30 @@ func TestTime(t *testing.T) {
func TestRewardsLevel(t *testing.T) {
partitiontest.PartitionTest(t)
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
proto := config.Consensus[protocol.ConsensusCurrentVersion]
var prev Block
prev.RewardsLevel = 1
prev.RewardsRate = 10
rewardUnits := uint64(10)
- state := prev.NextRewardsState(prev.Round()+1, proto, basics.MicroAlgos{}, rewardUnits)
+ state := prev.NextRewardsState(prev.Round()+1, proto, basics.MicroAlgos{}, rewardUnits, log)
require.Equal(t, uint64(2), state.RewardsLevel)
require.Equal(t, uint64(0), state.RewardsResidue)
+
+ assert.Zero(t, buf.Len())
}
func TestRewardsLevelWithResidue(t *testing.T) {
partitiontest.PartitionTest(t)
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
proto := config.Consensus[protocol.ConsensusCurrentVersion]
var prev Block
@@ -270,14 +284,20 @@ func TestRewardsLevelWithResidue(t *testing.T) {
prev.RewardsRate = 1
rewardUnits := uint64(10)
- state := prev.NextRewardsState(prev.Round()+1, proto, basics.MicroAlgos{}, rewardUnits)
+ state := prev.NextRewardsState(prev.Round()+1, proto, basics.MicroAlgos{}, rewardUnits, log)
require.Equal(t, uint64(11), state.RewardsLevel)
require.Equal(t, uint64(0), state.RewardsResidue)
+
+ assert.Zero(t, buf.Len())
}
func TestRewardsLevelNoUnits(t *testing.T) {
partitiontest.PartitionTest(t)
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
proto := config.Consensus[protocol.ConsensusCurrentVersion]
var prev Block
@@ -285,14 +305,20 @@ func TestRewardsLevelNoUnits(t *testing.T) {
prev.RewardsResidue = 2
rewardUnits := uint64(0)
- state := prev.NextRewardsState(prev.Round()+1, proto, basics.MicroAlgos{}, rewardUnits)
+ state := prev.NextRewardsState(prev.Round()+1, proto, basics.MicroAlgos{}, rewardUnits, log)
require.Equal(t, prev.RewardsLevel, state.RewardsLevel)
require.Equal(t, prev.RewardsResidue, state.RewardsResidue)
+
+ assert.Zero(t, buf.Len())
}
func TestTinyLevel(t *testing.T) {
partitiontest.PartitionTest(t)
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
proto := config.Consensus[protocol.ConsensusCurrentVersion]
var prev Block
@@ -300,13 +326,19 @@ func TestTinyLevel(t *testing.T) {
prev.RewardsRate = 10 * unitsInAlgos
algosInSystem := uint64(1000 * 1000 * 1000)
rewardUnits := algosInSystem * unitsInAlgos / proto.RewardUnit
- state := prev.NextRewardsState(prev.Round()+1, proto, basics.MicroAlgos{}, rewardUnits)
+ state := prev.NextRewardsState(prev.Round()+1, proto, basics.MicroAlgos{}, rewardUnits, log)
require.True(t, state.RewardsLevel > 0 || state.RewardsResidue > 0)
+
+ assert.Zero(t, buf.Len())
}
func TestRewardsRate(t *testing.T) {
partitiontest.PartitionTest(t)
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
var prev Block
prev.RewardsLevel = 1
prev.RewardsRate = 10
@@ -318,14 +350,20 @@ func TestRewardsRate(t *testing.T) {
incentivePoolBalance := basics.MicroAlgos{Raw: 1000 * uint64(proto.RewardsRateRefreshInterval)}
// make sure that RewardsRate stays the same
- state := prev.NextRewardsState(prev.Round()+1, proto, incentivePoolBalance, 0)
+ state := prev.NextRewardsState(prev.Round()+1, proto, incentivePoolBalance, 0, log)
require.Equal(t, prev.RewardsRate, state.RewardsRate)
require.Equal(t, prev.BlockHeader.RewardsRecalculationRound, state.RewardsRecalculationRound)
+
+ assert.Zero(t, buf.Len())
}
func TestRewardsRateRefresh(t *testing.T) {
partitiontest.PartitionTest(t)
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
var prev Block
prev.RewardsLevel = 1
prev.RewardsRate = 10
@@ -337,9 +375,11 @@ func TestRewardsRateRefresh(t *testing.T) {
incentivePoolBalance := basics.MicroAlgos{Raw: 1000 * uint64(proto.RewardsRateRefreshInterval)}
// make sure that RewardsRate was recomputed
nextRound := prev.Round() + 1
- state := prev.NextRewardsState(nextRound, proto, incentivePoolBalance, 0)
+ state := prev.NextRewardsState(nextRound, proto, incentivePoolBalance, 0, log)
require.Equal(t, (incentivePoolBalance.Raw-proto.MinBalance)/uint64(proto.RewardsRateRefreshInterval), state.RewardsRate)
require.Equal(t, nextRound+basics.Round(proto.RewardsRateRefreshInterval), state.RewardsRecalculationRound)
+
+ assert.Zero(t, buf.Len())
}
func TestEncodeDecodeSignedTxn(t *testing.T) {
@@ -412,8 +452,13 @@ func TestInitialRewardsRateCalculation(t *testing.T) {
partitiontest.PartitionTest(t)
consensusParams := config.Consensus[protocol.ConsensusCurrentVersion]
+ consensusParams.RewardsCalculationFix = false
runTest := func() bool {
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
incentivePoolBalance := uint64(125000000000000)
totalRewardUnits := uint64(10000000000)
require.GreaterOrEqual(t, incentivePoolBalance, consensusParams.MinBalance)
@@ -429,7 +474,7 @@ func TestInitialRewardsRateCalculation(t *testing.T) {
curRewardsState.RewardsRate = incentivePoolBalance / uint64(consensusParams.RewardsRateRefreshInterval)
}
for rnd := 1; rnd < int(consensusParams.RewardsRateRefreshInterval+2); rnd++ {
- nextRewardState := curRewardsState.NextRewardsState(basics.Round(rnd), consensusParams, basics.MicroAlgos{Raw: incentivePoolBalance}, totalRewardUnits)
+ nextRewardState := curRewardsState.NextRewardsState(basics.Round(rnd), consensusParams, basics.MicroAlgos{Raw: incentivePoolBalance}, totalRewardUnits, log)
// adjust the incentive pool balance
var ot basics.OverflowTracker
@@ -450,6 +495,8 @@ func TestInitialRewardsRateCalculation(t *testing.T) {
// prepare for the next iteration
curRewardsState = nextRewardState
}
+
+ assert.Zero(t, buf.Len())
return true
}
@@ -461,3 +508,264 @@ func TestInitialRewardsRateCalculation(t *testing.T) {
consensusParams.InitialRewardsRateCalculation = true
require.True(t, runTest())
}
+
+func performRewardsRateCalculation(
+ t *testing.T, consensusParams config.ConsensusParams,
+ curRewardsState RewardsState,
+ incentivePoolBalance uint64, totalRewardUnits uint64, startingRound uint64, overspends bool, logs bool) {
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+ defer func() {
+ require.Equal(t, logs, buf.Len() != 0)
+ }()
+
+ require.GreaterOrEqual(t, incentivePoolBalance, consensusParams.MinBalance)
+
+ for rnd := startingRound; rnd < startingRound+uint64(consensusParams.RewardsRateRefreshInterval)*3; rnd++ {
+ nextRewardState := curRewardsState.NextRewardsState(basics.Round(rnd), consensusParams, basics.MicroAlgos{Raw: incentivePoolBalance}, totalRewardUnits, log)
+ // adjust the incentive pool balance
+ var ot basics.OverflowTracker
+
+ // get number of rewards per unit
+ rewardsPerUnit := ot.Sub(nextRewardState.RewardsLevel, curRewardsState.RewardsLevel)
+ require.False(t, ot.Overflowed)
+
+ // subtract the total dispersed funds from the pool balance
+ incentivePoolBalance = ot.Sub(incentivePoolBalance, ot.Mul(totalRewardUnits, rewardsPerUnit))
+ if ot.Overflowed {
+ require.True(t, overspends)
+ return
+ }
+
+ if incentivePoolBalance < consensusParams.MinBalance {
+ require.True(t, overspends)
+ return
+ }
+
+ // prepare for the next iteration
+ curRewardsState = nextRewardState
+ }
+
+ require.False(t, overspends)
+}
+
+func TestNextRewardsRateWithFix(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ proto, ok := config.Consensus[protocol.ConsensusCurrentVersion]
+ require.True(t, ok)
+ proto.RewardsCalculationFix = true
+
+ tests := []struct {
+ name string
+ rewardsRate uint64
+ rewardsLevel uint64
+ rewardsResidue uint64
+ rewardsRecalculationRound basics.Round
+ incentivePoolBalance uint64
+ totalRewardUnits uint64
+ startingRound uint64
+ logs bool
+ }{
+ {"zero_rate", 0, 215332, 0, 18500000, proto.MinBalance, 6756334087, 18063999, false},
+ // 3 subtests below use parameters found in the block header `startingRound` - 1.
+ {"mainnet_0", 24000000, 215332, 545321700, 18500000, 10464550021728, 6756334087,
+ 18063999, true},
+ {"mainnet_1", 24000000, 215332, 521321700, 18500000, 10464550021728, 6756334078,
+ 18063998, true},
+ {"mainnet_2", 24000000, 215332, 425321700, 18500000, 10464550021728, 6756334079,
+ 18063994, true},
+ {"no_residue", 0, 0, 0, 1000000,
+ proto.MinBalance + 500000000000 /* 5*10^11 */, 1, 1000000, false},
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ curRewardsState := RewardsState{
+ RewardsLevel: test.rewardsLevel,
+ RewardsResidue: test.rewardsResidue,
+ RewardsRecalculationRound: test.rewardsRecalculationRound,
+ RewardsRate: test.rewardsRate,
+ }
+
+ performRewardsRateCalculation(
+ t, proto, curRewardsState, test.incentivePoolBalance, test.totalRewardUnits,
+ test.startingRound, false, test.logs)
+ })
+ }
+}
+
+func TestNextRewardsRateFailsWithoutFix(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ proto, ok := config.Consensus[protocol.ConsensusCurrentVersion]
+ require.True(t, ok)
+ proto.RewardsCalculationFix = false
+
+ curRewardsState := RewardsState{
+ RewardsLevel: 0,
+ RewardsResidue: 0,
+ RewardsRecalculationRound: 1000000,
+ RewardsRate: 0,
+ }
+
+ performRewardsRateCalculation(
+ t, proto, curRewardsState, proto.MinBalance+500000000000,
+ 1, 1000000, true, false)
+}
+
+func TestNextRewardsRateWithFixUsesNewRate(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ proto, ok := config.Consensus[protocol.ConsensusCurrentVersion]
+ require.True(t, ok)
+ proto.RewardsCalculationFix = true
+ proto.MinBalance = 1
+ proto.RewardsRateRefreshInterval = 10
+
+ state := RewardsState{
+ RewardsLevel: 4,
+ RewardsRate: 80,
+ RewardsResidue: 2,
+ RewardsRecalculationRound: 100,
+ }
+
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
+ newState := state.NextRewardsState(
+ state.RewardsRecalculationRound, proto, basics.MicroAlgos{Raw: 113}, 10, log)
+
+ expected := RewardsState{
+ RewardsLevel: 5,
+ RewardsRate: 11,
+ RewardsResidue: 3,
+ RewardsRecalculationRound: 110,
+ }
+ assert.Equal(t, expected, newState)
+
+ assert.Zero(t, buf.Len())
+}
+
+func TestNextRewardsRateWithFixPoolBalanceInsufficient(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ proto, ok := config.Consensus[protocol.ConsensusCurrentVersion]
+ require.True(t, ok)
+ proto.RewardsCalculationFix = true
+ proto.MinBalance = 10
+
+ state := RewardsState{
+ RewardsLevel: 4,
+ RewardsRate: 80,
+ RewardsResidue: 21,
+ RewardsRecalculationRound: 100,
+ }
+
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
+ newState := state.NextRewardsState(
+ state.RewardsRecalculationRound, proto, basics.MicroAlgos{Raw: 19}, 10, log)
+
+ expected := RewardsState{
+ RewardsLevel: 6,
+ RewardsRate: 0,
+ RewardsResidue: 1,
+ RewardsRecalculationRound: 100 + basics.Round(proto.RewardsRateRefreshInterval),
+ }
+ assert.Equal(t, expected, newState)
+
+ assert.Contains(
+ t, string(buf.Bytes()), "overflowed when trying to refresh RewardsRate")
+}
+
+func TestNextRewardsRateWithFixMaxSpentOverOverflow(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ proto, ok := config.Consensus[protocol.ConsensusCurrentVersion]
+ require.True(t, ok)
+ proto.RewardsCalculationFix = true
+ proto.MinBalance = 10
+
+ state := RewardsState{
+ RewardsLevel: 4,
+ RewardsRate: 80,
+ RewardsResidue: math.MaxUint64,
+ RewardsRecalculationRound: 100,
+ }
+
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
+ newState := state.NextRewardsState(
+ state.RewardsRecalculationRound, proto, basics.MicroAlgos{Raw: 9009}, 10, log)
+
+ expected := RewardsState{
+ RewardsLevel: 4 + math.MaxUint64/10,
+ RewardsRate: 0,
+ RewardsResidue: math.MaxUint64 % 10,
+ RewardsRecalculationRound: 100 + basics.Round(proto.RewardsRateRefreshInterval),
+ }
+ assert.Equal(t, expected, newState)
+
+ assert.Contains(
+ t, string(buf.Bytes()),
+ "overflowed when trying to accumulate MinBalance(10) and "+
+ "RewardsResidue(18446744073709551615)")
+}
+
+func TestNextRewardsRateWithFixRewardsWithResidueOverflow(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ proto, ok := config.Consensus[protocol.ConsensusCurrentVersion]
+ require.True(t, ok)
+ proto.RewardsCalculationFix = true
+ proto.MinBalance = 10
+
+ state := RewardsState{
+ RewardsLevel: 4,
+ RewardsRate: 80,
+ RewardsResidue: math.MaxUint64,
+ RewardsRecalculationRound: 100,
+ }
+
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
+ newState := state.NextRewardsState(
+ state.RewardsRecalculationRound-1, proto, basics.MicroAlgos{Raw: 0}, 1, log)
+ assert.Equal(t, state, newState)
+
+ assert.Contains(t, string(buf.Bytes()), "could not compute next reward level")
+}
+
+func TestNextRewardsRateWithFixNextRewardLevelOverflow(t *testing.T) {
+ partitiontest.PartitionTest(t)
+
+ proto, ok := config.Consensus[protocol.ConsensusCurrentVersion]
+ require.True(t, ok)
+ proto.RewardsCalculationFix = true
+ proto.MinBalance = 10
+
+ state := RewardsState{
+ RewardsLevel: math.MaxUint64,
+ RewardsRate: 0,
+ RewardsResidue: 1,
+ RewardsRecalculationRound: 100,
+ }
+
+ var buf bytes.Buffer
+ log := logging.NewLogger()
+ log.SetOutput(&buf)
+
+ newState := state.NextRewardsState(
+ state.RewardsRecalculationRound-1, proto, basics.MicroAlgos{Raw: 1000}, 1, log)
+ assert.Equal(t, state, newState)
+
+ assert.Contains(t, string(buf.Bytes()), "could not compute next reward level")
+}
diff --git a/ledger/internal/eval.go b/ledger/internal/eval.go
index 336fcb943..4bba4a0a4 100644
--- a/ledger/internal/eval.go
+++ b/ledger/internal/eval.go
@@ -526,7 +526,7 @@ func StartEvaluator(l LedgerForEvaluator, hdr bookkeeping.BlockHeader, evalOpts
if eval.proto.SupportGenesisHash {
eval.block.BlockHeader.GenesisHash = eval.genesisHash
}
- eval.block.BlockHeader.RewardsState = eval.prevHeader.NextRewardsState(hdr.Round, proto, incentivePoolData.MicroAlgos, prevTotals.RewardUnits())
+ eval.block.BlockHeader.RewardsState = eval.prevHeader.NextRewardsState(hdr.Round, proto, incentivePoolData.MicroAlgos, prevTotals.RewardUnits(), logging.Base())
}
// set the eval state with the current header
eval.state = makeRoundCowState(base, eval.block.BlockHeader, proto, eval.prevHeader.TimeStamp, prevTotals, evalOpts.PaysetHint)
@@ -538,7 +538,7 @@ func StartEvaluator(l LedgerForEvaluator, hdr bookkeeping.BlockHeader, evalOpts
}
// Check that the rewards rate, level and residue match expected values
- expectedRewardsState := eval.prevHeader.NextRewardsState(hdr.Round, proto, incentivePoolData.MicroAlgos, prevTotals.RewardUnits())
+ expectedRewardsState := eval.prevHeader.NextRewardsState(hdr.Round, proto, incentivePoolData.MicroAlgos, prevTotals.RewardUnits(), logging.Base())
if eval.block.RewardsState != expectedRewardsState {
return nil, fmt.Errorf("bad rewards state: %+v != %+v", eval.block.RewardsState, expectedRewardsState)
}
diff --git a/ledger/ledger_test.go b/ledger/ledger_test.go
index b28965755..c88999761 100644
--- a/ledger/ledger_test.go
+++ b/ledger/ledger_test.go
@@ -120,7 +120,7 @@ func makeNewEmptyBlock(t *testing.T, l *Ledger, GenesisID string, initAccounts m
Round: l.Latest() + 1,
Branch: lastBlock.Hash(),
TimeStamp: 0,
- RewardsState: lastBlock.NextRewardsState(l.Latest()+1, proto, poolBal.MicroAlgos, totalRewardUnits),
+ RewardsState: lastBlock.NextRewardsState(l.Latest()+1, proto, poolBal.MicroAlgos, totalRewardUnits, logging.Base()),
UpgradeState: lastBlock.UpgradeState,
// Seed: does not matter,
// UpgradeVote: empty,
@@ -219,7 +219,7 @@ func TestLedgerBlockHeaders(t *testing.T) {
Round: l.Latest() + 1,
Branch: lastBlock.Hash(),
TimeStamp: 0,
- RewardsState: lastBlock.NextRewardsState(l.Latest()+1, proto, poolBal.MicroAlgos, totalRewardUnits),
+ RewardsState: lastBlock.NextRewardsState(l.Latest()+1, proto, poolBal.MicroAlgos, totalRewardUnits, logging.Base()),
UpgradeState: lastBlock.UpgradeState,
// Seed: does not matter,
// UpgradeVote: empty,
@@ -1216,7 +1216,7 @@ func testLedgerSingleTxApplyData(t *testing.T, version protocol.ConsensusVersion
Round: l.Latest() + 1,
Branch: lastBlock.Hash(),
TimeStamp: 0,
- RewardsState: lastBlock.NextRewardsState(l.Latest()+1, proto, poolBal.MicroAlgos, totalRewardUnits),
+ RewardsState: lastBlock.NextRewardsState(l.Latest()+1, proto, poolBal.MicroAlgos, totalRewardUnits, logging.Base()),
UpgradeState: lastBlock.UpgradeState,
// Seed: does not matter,
// UpgradeVote: empty,