diff --git a/build/mining_reward_test.go b/build/mining_reward_test.go new file mode 100644 index 000000000..9629623ed --- /dev/null +++ b/build/mining_reward_test.go @@ -0,0 +1,12 @@ +package build + +import ( + "math/big" + "testing" +) + +func TestEncodeMiningRewardInitial(t *testing.T) { + i := &big.Int{} + i.SetString("153686558225539943338", 10) + t.Logf("%#v", i.Bytes()) +} diff --git a/build/params.go b/build/params.go index d165fa6c6..0ee462a68 100644 --- a/build/params.go +++ b/build/params.go @@ -29,6 +29,9 @@ const CollateralPrecision = 100 const TotalFilecoin = 2000000000 const MiningRewardTotal = 1400000000 + +var MiningRewardInitialAttoFilBytes = []byte{0x8, 0x54, 0xd4, 0x56, 0x70, 0x99, 0xb2, 0x4b, 0xaa} + const FilecoinPrecision = 1000000000000000000 // six years diff --git a/chain/gen/mining.go b/chain/gen/mining.go index fb35cce4f..a691c5db5 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -42,9 +42,13 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal if err != nil { return nil, xerrors.Errorf("failed to get miner worker: %w", err) } + networkBalance, err := vmi.ActorBalance(actors.NetworkAddress) + if err != nil { + return nil, xerrors.Errorf("failed to get network balance: %w", err) + } // apply miner reward - if err := vmi.TransferFunds(actors.NetworkAddress, owner, vm.MiningRewardForBlock(height)); err != nil { + if err := vmi.TransferFunds(actors.NetworkAddress, owner, vm.MiningReward(networkBalance)); err != nil { return nil, err } diff --git a/chain/sync.go b/chain/sync.go index a7eae3c3b..2cf6239fa 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -441,8 +441,13 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err if err != nil { return xerrors.Errorf("getting miner owner for block miner failed: %w", err) } + networkBalance, err := vmi.ActorBalance(actors.NetworkAddress) + if err != nil { + return xerrors.Errorf("getting network balance") + } - if err := vmi.TransferFunds(actors.NetworkAddress, owner, vm.MiningRewardForBlock(h.Height)); err != nil { + if err := vmi.TransferFunds(actors.NetworkAddress, owner, + vm.MiningReward(networkBalance)); err != nil { return xerrors.Errorf("fund transfer failed: %w", err) } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 791496678..3cd88a2c9 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -3,7 +3,6 @@ package vm import ( "context" "fmt" - "math" "math/big" "github.com/filecoin-project/go-lotus/build" @@ -634,6 +633,18 @@ func DepositFunds(act *types.Actor, amt types.BigInt) { act.Balance = types.BigAdd(act.Balance, amt) } +// MiningReward returns correct mining reward +// coffer is amount of FIL in NetworkAddress +func MiningReward(coffer types.BigInt) types.BigInt { + i := &big.Int{} + i.SetBytes(build.MiningRewardInitialAttoFilBytes) + IV := types.BigInt{i} + res := types.BigMul(IV, coffer) + res = types.BigDiv(res, types.FromFil(build.MiningRewardTotal)) + return res +} + +/* func MiningRewardForBlock(height uint64) types.BigInt { //decay := e^(ln(0.5) / (HalvingPeriodBlocks / AdjustmentPeriod) @@ -654,3 +665,4 @@ func MiningRewardForBlock(height uint64) types.BigInt { return types.BigInt{reward} } +*/ diff --git a/chain/vm/vm_test.go b/chain/vm/vm_test.go index 0cf9e53e0..b1fcc34c4 100644 --- a/chain/vm/vm_test.go +++ b/chain/vm/vm_test.go @@ -2,6 +2,7 @@ package vm import ( "fmt" + "os" "testing" "github.com/filecoin-project/go-lotus/build" @@ -9,14 +10,38 @@ import ( ) func TestBlockReward(t *testing.T) { + coffer := types.FromFil(build.MiningRewardTotal) sum := types.NewInt(0) - for i := 0; i < 500000000; i += 60 { - sum = types.BigAdd(sum, MiningRewardForBlock(uint64(i))) + N := build.HalvingPeriodBlocks + for i := 0; i < N; i++ { + if i%20000 == 0 { + fmt.Fprintf(os.Stderr, "%.1f%%\r", float64(i)/float64(N)*100) + } + + a := MiningReward(coffer) + sum = types.BigAdd(sum, a) + coffer = types.BigSub(coffer, a) } - sum = types.BigMul(sum, types.NewInt(60)) + //sum = types.BigMul(sum, types.NewInt(60)) - fmt.Println(sum) + fmt.Println("After a halving period") + fmt.Printf("Total reward: %d\n", build.MiningRewardTotal) + fmt.Printf("Remaining: %s\n", types.BigDiv(coffer, types.NewInt(build.FilecoinPrecision))) + fmt.Printf("Given out: %s\n", types.BigDiv(sum, types.NewInt(build.FilecoinPrecision))) - fmt.Println(types.BigDiv(sum, types.NewInt(build.FilecoinPrecision))) + for i := 0; i < N; i++ { + if i%20000 == 0 { + fmt.Fprintf(os.Stderr, "%.1f%%\r", float64(i)/float64(N)*100) + } + + a := MiningReward(coffer) + sum = types.BigAdd(sum, a) + coffer = types.BigSub(coffer, a) + } + + fmt.Println("Next halving period") + fmt.Printf("Total reward: %d\n", build.MiningRewardTotal) + fmt.Printf("Remaining: %s\n", types.BigDiv(coffer, types.NewInt(build.FilecoinPrecision))) + fmt.Printf("Given out: %s\n", types.BigDiv(sum, types.NewInt(build.FilecoinPrecision))) }