Skip to content

Commit 589ab65

Browse files
authored
Fix and Test BlockReward (#4618)
1 parent 4a3566a commit 589ab65

File tree

2 files changed

+96
-10
lines changed

2 files changed

+96
-10
lines changed

consensus/scheme/rolldpos/chainmanager.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,7 @@ func (cm *chainManager) CommitBlock(blk *block.Block) error {
257257
}
258258

259259
func (cm *chainManager) Start(ctx context.Context) error {
260-
head, err := cm.bc.BlockHeaderByHeight(cm.bc.TipHeight())
261-
if err != nil {
262-
return errors.Wrap(err, "failed to get the head block")
263-
}
264-
cm.pool.Init(head.HashBlock())
260+
cm.pool.Init(cm.bc.TipHash())
265261
return nil
266262
}
267263

e2etest/rewarding_test.go

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"math/big"
77
"math/rand"
88
"os"
9+
"slices"
910
"strconv"
1011
"sync"
1112
"testing"
@@ -26,8 +27,10 @@ import (
2627
"github.com/iotexproject/iotex-core/v2/action/protocol"
2728
accountutil "github.com/iotexproject/iotex-core/v2/action/protocol/account/util"
2829
"github.com/iotexproject/iotex-core/v2/action/protocol/rewarding"
30+
"github.com/iotexproject/iotex-core/v2/action/protocol/rewarding/rewardingpb"
2931
"github.com/iotexproject/iotex-core/v2/api"
3032
"github.com/iotexproject/iotex-core/v2/blockchain"
33+
"github.com/iotexproject/iotex-core/v2/blockchain/block"
3134
"github.com/iotexproject/iotex-core/v2/blockchain/genesis"
3235
"github.com/iotexproject/iotex-core/v2/config"
3336
"github.com/iotexproject/iotex-core/v2/pkg/log"
@@ -81,9 +84,23 @@ func TestBlockReward(t *testing.T) {
8184
cfg.Consensus.RollDPoS.FSM.AcceptProposalEndorsementTTL = 300 * time.Millisecond
8285
cfg.Consensus.RollDPoS.FSM.AcceptLockEndorsementTTL = 300 * time.Millisecond
8386
cfg.Consensus.RollDPoS.FSM.CommitTTL = 100 * time.Millisecond
87+
cfg.DardanellesUpgrade.AcceptBlockTTL = 300 * time.Millisecond
88+
cfg.DardanellesUpgrade.AcceptProposalEndorsementTTL = 300 * time.Millisecond
89+
cfg.DardanellesUpgrade.AcceptLockEndorsementTTL = 300 * time.Millisecond
90+
cfg.DardanellesUpgrade.CommitTTL = 100 * time.Millisecond
91+
cfg.DardanellesUpgrade.BlockInterval = time.Second
92+
cfg.Chain.MintTimeout = 100 * time.Millisecond
8493
cfg.Chain.ProducerPrivKey = identityset.PrivateKey(0).HexString()
8594
cfg.Network.Port = testutil.RandomPort()
8695
cfg.Genesis.PollMode = "lifeLong"
96+
cfg.Genesis.AleutianBlockHeight = 0
97+
cfg.Genesis.DardanellesBlockHeight = 1 // enable block reward
98+
cfg.Genesis.GreenlandBlockHeight = 6
99+
cfg.Genesis.KamchatkaBlockHeight = 7
100+
cfg.Genesis.VanuatuBlockHeight = 8 // enable dynamic fee
101+
cfg.Genesis.ToBeEnabledBlockHeight = 10 // enable wake block reward
102+
testutil.NormalizeGenesisHeights(&cfg.Genesis.Blockchain)
103+
block.LoadGenesisHash(&cfg.Genesis)
87104

88105
svr, err := itx.NewServer(cfg)
89106
require.NoError(t, err)
@@ -92,6 +109,35 @@ func TestBlockReward(t *testing.T) {
92109
require.NoError(t, svr.Stop(context.Background()))
93110
}()
94111

112+
inject := func(ctx context.Context, tps int) {
113+
actpool := svr.ChainService(cfg.Chain.ID).ActionPool()
114+
senderSK := identityset.PrivateKey(1)
115+
amount := big.NewInt(100)
116+
gasLimit := uint64(100000)
117+
gasPrice := big.NewInt(unit.Qev * 2)
118+
nonce, err := actpool.GetPendingNonce(senderSK.PublicKey().Address().String())
119+
require.NoError(t, err)
120+
ticker := time.NewTicker(time.Second / time.Duration(tps))
121+
defer ticker.Stop()
122+
for {
123+
select {
124+
case <-ticker.C:
125+
tx, err := action.SignedTransfer(identityset.Address(10).String(), senderSK, nonce, amount, nil, gasLimit, gasPrice, action.WithChainID(cfg.Chain.ID))
126+
require.NoError(t, err)
127+
if err = actpool.Add(ctx, tx); err != nil {
128+
t.Log("failed to add action to actpool", zap.Error(err))
129+
} else {
130+
nonce++
131+
}
132+
case <-ctx.Done():
133+
return
134+
}
135+
}
136+
}
137+
ctxInject, cancel := context.WithCancel(context.Background())
138+
defer cancel()
139+
go inject(ctxInject, 10)
140+
95141
require.NoError(t, testutil.WaitUntil(100*time.Millisecond, 20*time.Second, func() (b bool, e error) {
96142
return svr.ChainService(1).Blockchain().TipHeight() >= 5, nil
97143
}))
@@ -120,19 +166,63 @@ func TestBlockReward(t *testing.T) {
120166
require.NoError(t, err)
121167
assert.True(t, balance.Cmp(big.NewInt(0).Mul(blockReward, big.NewInt(5))) <= 0)
122168

123-
for i := 1; i <= 5; i++ {
124-
blk, err := svr.ChainService(1).BlockDAO().GetBlockByHeight(uint64(i))
169+
checkBlockReward := func(blockHeight uint64) {
170+
blk, err := svr.ChainService(1).BlockDAO().GetBlockByHeight(uint64(blockHeight))
125171
require.NoError(t, err)
126172
ok := false
127-
var gr *action.GrantReward
128-
for _, act := range blk.Body.Actions {
173+
var (
174+
gr *action.GrantReward
175+
idx int
176+
)
177+
for k, act := range blk.Body.Actions {
129178
gr, ok = act.Action().(*action.GrantReward)
130179
if ok {
131-
assert.Equal(t, uint64(i), gr.Height())
180+
idx = k
181+
require.NoError(t, err)
182+
assert.Equal(t, uint64(blockHeight), gr.Height())
132183
break
133184
}
134185
}
135186
assert.True(t, ok)
187+
receipts, err := svr.ChainService(1).BlockDAO().GetReceipts(uint64(blockHeight))
188+
require.NoError(t, err)
189+
require.Len(t, receipts[idx].Logs(), 1)
190+
rewardLogs, err := rewarding.UnmarshalRewardLog(receipts[idx].Logs()[0].Data)
191+
require.NoError(t, err)
192+
193+
rewards := make(map[rewardingpb.RewardLog_RewardType]*big.Int)
194+
rewards[rewardingpb.RewardLog_BLOCK_REWARD] = big.NewInt(0)
195+
rewards[rewardingpb.RewardLog_PRIORITY_BONUS] = big.NewInt(0)
196+
for _, txLog := range rewardLogs.Logs {
197+
amount, ok := big.NewInt(0).SetString(txLog.Amount, 10)
198+
require.True(t, ok)
199+
rewards[txLog.Type] = amount
200+
}
201+
202+
switch {
203+
case blockHeight < cfg.Genesis.VanuatuBlockHeight:
204+
// fixed block reward
205+
assert.Equal(t, cfg.Genesis.DardanellesBlockReward().String(), rewards[rewardingpb.RewardLog_BLOCK_REWARD].String())
206+
assert.Equal(t, big.NewInt(0).String(), rewards[rewardingpb.RewardLog_PRIORITY_BONUS].String())
207+
case blockHeight < cfg.Genesis.ToBeEnabledBlockHeight:
208+
// fixed block reward + priority bonus
209+
require.True(t, rewards[rewardingpb.RewardLog_PRIORITY_BONUS].Sign() > 0, "blockHeight %d", blockHeight)
210+
assert.Equal(t, cfg.Genesis.DardanellesBlockReward().String(), rewards[rewardingpb.RewardLog_BLOCK_REWARD].String())
211+
assert.Equal(t, slices.ContainsFunc(blk.Actions, func(e *action.SealedEnvelope) bool { return !action.IsSystemAction(e) }), rewards[rewardingpb.RewardLog_PRIORITY_BONUS].Sign() > 0)
212+
default:
213+
// dynamic block reward + priority bonus
214+
require.True(t, rewards[rewardingpb.RewardLog_PRIORITY_BONUS].Sign() > 0)
215+
assert.Equal(t, slices.ContainsFunc(blk.Actions, func(e *action.SealedEnvelope) bool { return !action.IsSystemAction(e) }), rewards[rewardingpb.RewardLog_PRIORITY_BONUS].Sign() > 0)
216+
total := new(big.Int).Add(rewards[rewardingpb.RewardLog_BLOCK_REWARD], rewards[rewardingpb.RewardLog_PRIORITY_BONUS])
217+
assert.Equal(t, true, total.Cmp(cfg.Genesis.WakeBlockReward()) >= 0)
218+
}
219+
}
220+
221+
require.NoError(t, testutil.WaitUntil(100*time.Millisecond, 20*time.Second, func() (b bool, e error) {
222+
return svr.ChainService(1).Blockchain().TipHeight() >= 11, nil
223+
}))
224+
for i := 1; i <= 11; i++ {
225+
checkBlockReward(uint64(i))
136226
}
137227
}
138228

0 commit comments

Comments
 (0)