avoid floating point math

This commit is contained in:
whyrusleeping 2019-09-12 17:12:45 -07:00
parent 197a2a3025
commit 2d5b88ce84
2 changed files with 23 additions and 10 deletions

View File

@ -3,7 +3,6 @@ package actors
import (
"context"
"fmt"
"math"
"github.com/filecoin-project/go-lotus/build"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
@ -727,17 +726,9 @@ func (sma StorageMinerActor) SlashConsensusFault(act *types.Actor, vmctx types.V
// current GROWTH_RATE results in SLASHER_SHARE reaches 1 after 30 blocks
// TODO: define arithmetic precision and rounding for this operation
blockElapsed := vmctx.BlockHeight() - params.AtHeight
growthRate := 1.26
initialShare := 0.001
// REVIEW: floating point precision loss anyone?
slasherPortion := initialShare * math.Pow(growthRate, float64(blockElapsed))
if slasherPortion > 1 {
slasherPortion = 1
}
slasherShare := slasherShare(params.SlashedCollateral, blockElapsed)
const precision = 1000000
slasherShare := types.BigDiv(types.BigMul(types.NewInt(uint64(precision*slasherPortion)), slashedCollateral), types.NewInt(precision))
burnPortion := types.BigSub(slashedCollateral, slasherShare)
_, err := vmctx.Send(vmctx.Message().From, 0, slasherShare, nil)
@ -759,3 +750,24 @@ func (sma StorageMinerActor) SlashConsensusFault(act *types.Actor, vmctx types.V
return nil, nil
}
func slasherShare(total types.BigInt, elapsed uint64) types.BigInt {
// [int(pow(1.26, n) * 10) for n in range(30)]
fracs := []uint64{10, 12, 15, 20, 25, 31, 40, 50, 63, 80, 100, 127, 160, 201, 254, 320, 403, 508, 640, 807, 1017, 1281, 1614, 2034, 2563, 3230, 4070, 5128, 6462, 8142}
const precision = 10000
var frac uint64
if elapsed >= uint64(len(fracs)) {
frac = precision
} else {
frac = fracs[elapsed]
}
return types.BigDiv(
types.BigMul(
types.NewInt(frac),
total,
),
types.NewInt(precision),
)
}

View File

@ -5,6 +5,7 @@ import (
"os"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/types"
gen "github.com/whyrusleeping/cbor-gen"
)