From 2edd3decd1066696a08a90b48e2cfcee11b90323 Mon Sep 17 00:00:00 2001 From: Tolik Zinovyev Date: Wed, 19 Jan 2022 16:13:57 -0500 Subject: 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. --- config/consensus.go | 5 + daemon/algod/api/server/v2/test/handlers_test.go | 2 +- data/bookkeeping/block.go | 25 +- data/bookkeeping/block_test.go | 322 ++++++++++++++++++++++- ledger/internal/eval.go | 4 +- ledger/ledger_test.go | 6 +- 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, -- cgit v1.2.3