Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

IS-916: fix beta2 calculation bug #39

Merged
merged 1 commit into from
Dec 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const (
AccountDBNameFormat = "calculate_%d_%d_%d"
BackupDBNamePrefix = "backup_"
BackupDBNameFormat = BackupDBNamePrefix + "%d_%d" // CalcBH_accountDBIndex

Revision8 uint64 = 8
RevisionMin = Revision8
RevisionMax = Revision8
)

type IScoreDB struct {
Expand Down
29 changes: 17 additions & 12 deletions core/msg_calculate.go
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ func calculatePRepReward(ctx *Context, to uint64) (uint64, *common.HexInt, []byt
if s < prep.BlockHeight {
s = prep.BlockHeight
}
if i+1 < len(ctx.PRep) && ctx.PRep[i+1].BlockHeight < to {
if i+1 < len(ctx.PRep) && ctx.PRep[i+1].BlockHeight < end {
e = ctx.PRep[i+1].BlockHeight
}
//log.Printf("[P-Rep reward] : s, e : %d - %d", s, e)
Expand All @@ -836,7 +836,7 @@ func calculatePRepReward(ctx *Context, to uint64) (uint64, *common.HexInt, []byt
}

// calculate P-Rep reward for Governance variable and write to calculate DB
account, reward, hash := setPRepReward(ctx, s, e, prep)
account, reward, hash := setPRepReward(ctx, s, e, prep, to)
h.Write(hash)
totalReward.Add(&totalReward.Int, &reward.Int)
newAccount += account
Expand All @@ -848,7 +848,7 @@ func calculatePRepReward(ctx *Context, to uint64) (uint64, *common.HexInt, []byt
return newAccount, totalReward, stateHash
}

func setPRepReward(ctx *Context, start uint64, end uint64, prep *PRep) (uint64, *common.HexInt, []byte) {
func setPRepReward(ctx *Context, start uint64, end uint64, prep *PRep, blockHeight uint64) (uint64, *common.HexInt, []byte) {
type reward struct {
iScore common.HexInt
blockHeight uint64
Expand Down Expand Up @@ -882,12 +882,12 @@ func setPRepReward(ctx *Context, start uint64, end uint64, prep *PRep) (uint64,

// update rewards
for i, dgInfo:= range prep.List {
var reward common.HexInt
reward.Mul(&rewardRate.Int, &dgInfo.DelegatedAmount.Int)
reward.Div(&reward.Int, &prep.TotalDelegation.Int)
rewards[i].iScore.Add(&rewards[i].iScore.Int, &reward.Int)
var iScore common.HexInt
iScore.Mul(&rewardRate.Int, &dgInfo.DelegatedAmount.Int)
iScore.Div(&iScore.Int, &prep.TotalDelegation.Int)
rewards[i].iScore.Add(&rewards[i].iScore.Int, &iScore.Int)
rewards[i].blockHeight = e
//log.Printf("[P-Rep reward] deletation: %s, reward: %s,%d\n",
//log.Printf("[P-Rep reward] delegation: %s, reward: %s,%d\n",
// dgInfo.String(), rewards[i].IScore.String(), rewards[i].blockHeight)
}
}
Expand All @@ -914,22 +914,27 @@ func setPRepReward(ctx *Context, start uint64, end uint64, prep *PRep) (uint64,

// update I-Score
ia.IScore.Add(&ia.IScore.Int, &rewards[i].iScore.Int)
ia.BlockHeight = rewards[i].blockHeight

// do not update block height of IA
if ctx.Revision < Revision8 {
ia.BlockHeight = rewards[i].blockHeight
}
} else {
// there is no account in DB
ia = new(IScoreAccount)
ia.IScore.Set(&rewards[i].iScore.Int)
ia.BlockHeight = end // Set blockHeight to end
if ctx.Revision >= Revision8 {
ia.BlockHeight = blockHeight
} else {
ia.BlockHeight = end // Set blockHeight to end
}

newAccount++
}

// write to account DB
if ia != nil {
ia.Address = dgInfo.Address
//log.Printf("[P-Rep reward] Write to DB %s, increased reward: %s", ia.String(), rewards[i].IScore.String())
//log.Printf("[P-Rep reward] Write to DB %s, increased reward: %s", ia.String(), rewards[i].iScore.String())
bucket.Set(ia.ID(), ia.Bytes())
h.Write(ia.BytesForHash())
totalReward.Add(&totalReward.Int, &rewards[i].iScore.Int)
Expand Down
82 changes: 71 additions & 11 deletions core/msg_calculate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package core

import (
"encoding/binary"
"fmt"
"log"
"os"
"sort"
Expand Down Expand Up @@ -333,25 +334,41 @@ func TestMsgCalc_CalculateIISSBlockProduce(t *testing.T) {

}

func setRevision(ctx *Context, revision uint64) {
ctx.Revision = revision
}

func TestMsgCalc_CalculatePRepReward(t *testing.T) {
for revision := RevisionMin - 1; revision <= RevisionMax; revision++ {
t.Run(fmt.Sprintf("Revision:%d", revision), func(t *testing.T) {
testCalculatePRepReward(t, revision)
})
}
}

func testCalculatePRepReward(t *testing.T, revision uint64) {
const (
BlockHeight0 uint64 = 0
BlockHeight1 uint64 = 10
BlockHeight2 uint64 = 20

TotalDelegation0 = 10
DelegationA0 = 4
DelegationB0 = 6
TotalDelegation1 = 20
DelegationC0 = 10
TotalDelegation0 = DelegationA0 + DelegationB0 + DelegationC0

DelegationA1 = 14
DelegationB1 = 6
TotalDelegation1 = DelegationA1 + DelegationB1
)

ctx := initTest(1)
defer finalizeTest(ctx)
setRevision(ctx, revision)

prepA := *common.NewAddressFromString("hxaa")
prepB := *common.NewAddressFromString("hxbb")
prepC := *common.NewAddressFromString("hxcc")

// set GV
gv := new(GovernanceVariable)
Expand Down Expand Up @@ -389,6 +406,12 @@ func TestMsgCalc_CalculatePRepReward(t *testing.T) {
prep.List = append(prep.List, *dInfo)
ctx.PRep = append(ctx.PRep, prep)

dInfo = new(PRepDelegationInfo)
dInfo.Address = prepC
dInfo.DelegatedAmount.SetUint64(DelegationC0)
prep.List = append(prep.List, *dInfo)
ctx.PRep = append(ctx.PRep, prep)

// P-Rep 1
prep = new(PRep)
prep.BlockHeight = BlockHeight1
Expand All @@ -408,7 +431,7 @@ func TestMsgCalc_CalculatePRepReward(t *testing.T) {

// calculate P-Rep reward
account, stats, hash := calculatePRepReward(ctx, BlockHeight2)
assert.Equal(t, uint64(2), account)
assert.Equal(t, uint64(3), account)

calcDB := ctx.DB.getCalculateDB(prepA)
bucket, _ := calcDB.GetBucket(db.PrefixIScore)
Expand All @@ -422,7 +445,12 @@ func TestMsgCalc_CalculatePRepReward(t *testing.T) {
reward0.Mul(&reward0.Int, &common.NewHexIntFromUint64(DelegationA0).Int)
reward0.Div(&reward0.Int, &common.NewHexIntFromUint64(TotalDelegation0).Int)

iaPRepA1 := newIScoreAccount(prepA, BlockHeight1, reward0)
var iaPRepA0 *IScoreAccount
if ctx.Revision < Revision8 {
iaPRepA0 = newIScoreAccount(prepA, BlockHeight1, reward0)
} else {
iaPRepA0 = newIScoreAccount(prepA, BlockHeight2, reward0)
}

period = common.NewHexIntFromUint64(BlockHeight2 - BlockHeight1)
gv = ctx.getGVByBlockHeight(BlockHeight2)
Expand All @@ -432,7 +460,7 @@ func TestMsgCalc_CalculatePRepReward(t *testing.T) {

reward.Add(&reward0.Int, &reward1.Int)

iaPRepA2 := newIScoreAccount(prepA, BlockHeight2, reward)
iaPRepA1 := newIScoreAccount(prepA, BlockHeight2, reward)

bs, _ := bucket.Get(prepA.Bytes())
ia, _ := NewIScoreAccountFromBytes(bs)
Expand All @@ -448,7 +476,12 @@ func TestMsgCalc_CalculatePRepReward(t *testing.T) {
reward0.Mul(&reward0.Int, &common.NewHexIntFromUint64(DelegationB0).Int)
reward0.Div(&reward0.Int, &common.NewHexIntFromUint64(TotalDelegation0).Int)

iaPRepB1 := newIScoreAccount(prepB, BlockHeight1, reward0)
var iaPRepB0 *IScoreAccount
if ctx.Revision < Revision8 {
iaPRepB0 = newIScoreAccount(prepB, BlockHeight1, reward0)
} else {
iaPRepB0 = newIScoreAccount(prepB, BlockHeight2, reward0)
}

period = common.NewHexIntFromUint64(BlockHeight2 - BlockHeight1)
gv = ctx.getGVByBlockHeight(BlockHeight2)
Expand All @@ -458,7 +491,7 @@ func TestMsgCalc_CalculatePRepReward(t *testing.T) {

reward.Add(&reward0.Int, &reward1.Int)

iaPRepB2 := newIScoreAccount(prepB, BlockHeight2, reward)
iaPRepB1 := newIScoreAccount(prepB, BlockHeight2, reward)

bs, _ = bucket.Get(prepB.Bytes())
ia, _ = NewIScoreAccountFromBytes(bs)
Expand All @@ -467,6 +500,32 @@ func TestMsgCalc_CalculatePRepReward(t *testing.T) {

totalReward.Add(&totalReward.Int, &reward.Int)

// check prepC
period = common.NewHexIntFromUint64(BlockHeight1 - BlockHeight0)
gv = ctx.getGVByBlockHeight(BlockHeight1)
reward0.Mul(&gv.PRepReward.Int, &period.Int)
reward0.Mul(&reward0.Int, &common.NewHexIntFromUint64(DelegationC0).Int)
reward0.Div(&reward0.Int, &common.NewHexIntFromUint64(TotalDelegation0).Int)

var iaPRepC0 *IScoreAccount
if ctx.Revision < Revision8 {
iaPRepC0 = newIScoreAccount(prepC, BlockHeight1, reward0)
} else {
iaPRepC0 = newIScoreAccount(prepC, BlockHeight2, reward0)
}

bs, _ = bucket.Get(prepC.Bytes())
ia, _ = NewIScoreAccountFromBytes(bs)
assert.Equal(t, 0, reward0.Cmp(&ia.IScore.Int))
if ctx.Revision < Revision8 {
assert.Equal(t, BlockHeight1, ia.BlockHeight)
} else {
assert.Equal(t, BlockHeight2, ia.BlockHeight)
}


totalReward.Add(&totalReward.Int, &reward0.Int)

// check stats
assert.Equal(t, 0, totalReward.Cmp(&stats.Int))

Expand All @@ -476,13 +535,14 @@ func TestMsgCalc_CalculatePRepReward(t *testing.T) {
stateHash2 := make([]byte, 64)

h1 := sha3.NewShake256()
h1.Write(iaPRepA1.BytesForHash())
h1.Write(iaPRepB1.BytesForHash())
h1.Write(iaPRepA0.BytesForHash())
h1.Write(iaPRepB0.BytesForHash())
h1.Write(iaPRepC0.BytesForHash())
h1.Read(stateHash1)

h2 := sha3.NewShake256()
h2.Write(iaPRepA2.BytesForHash())
h2.Write(iaPRepB2.BytesForHash())
h2.Write(iaPRepA1.BytesForHash())
h2.Write(iaPRepB1.BytesForHash())
h2.Read(stateHash2)

h := sha3.NewShake256()
Expand Down