Merge pull request #2764 from filecoin-project/feat/burn-above-estimate
Burn sclaing amount dependon on how much overestimation there was
This commit is contained in:
commit
e60af00ec4
@ -2,7 +2,6 @@ package validation
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
@ -37,6 +36,7 @@ func (a *Applier) ApplyMessage(epoch abi.ChainEpoch, message *vtypes.Message) (v
|
|||||||
lm := toLotusMsg(message)
|
lm := toLotusMsg(message)
|
||||||
receipt, penalty, reward, err := a.applyMessage(epoch, lm)
|
receipt, penalty, reward, err := a.applyMessage(epoch, lm)
|
||||||
return vtypes.ApplyMessageResult{
|
return vtypes.ApplyMessageResult{
|
||||||
|
Msg: *message,
|
||||||
Receipt: receipt,
|
Receipt: receipt,
|
||||||
Penalty: penalty,
|
Penalty: penalty,
|
||||||
Reward: reward,
|
Reward: reward,
|
||||||
@ -57,6 +57,7 @@ func (a *Applier) ApplySignedMessage(epoch abi.ChainEpoch, msg *vtypes.SignedMes
|
|||||||
// TODO: Validate the sig first
|
// TODO: Validate the sig first
|
||||||
receipt, penalty, reward, err := a.applyMessage(epoch, lm)
|
receipt, penalty, reward, err := a.applyMessage(epoch, lm)
|
||||||
return vtypes.ApplyMessageResult{
|
return vtypes.ApplyMessageResult{
|
||||||
|
Msg: msg.Message,
|
||||||
Receipt: receipt,
|
Receipt: receipt,
|
||||||
Penalty: penalty,
|
Penalty: penalty,
|
||||||
Reward: reward,
|
Reward: reward,
|
||||||
@ -176,8 +177,8 @@ func toLotusMsg(msg *vtypes.Message) *types.Message {
|
|||||||
Nonce: msg.CallSeqNum,
|
Nonce: msg.CallSeqNum,
|
||||||
Method: msg.Method,
|
Method: msg.Method,
|
||||||
|
|
||||||
Value: types.BigInt{Int: msg.Value.Int},
|
Value: msg.Value,
|
||||||
GasPrice: types.BigInt{Int: msg.GasPrice.Int},
|
GasPrice: msg.GasPrice,
|
||||||
GasLimit: msg.GasLimit,
|
GasLimit: msg.GasLimit,
|
||||||
|
|
||||||
Params: msg.Params,
|
Params: msg.Params,
|
||||||
|
44
chain/vm/burn.go
Normal file
44
chain/vm/burn.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package vm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
gasOveruseNum = 11
|
||||||
|
gasOveruseDenom = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
// ComputeGasOutputs computes amount of gas to be refunded and amount of gas to be burned
|
||||||
|
// Result is (refund, burn)
|
||||||
|
func ComputeGasOutputs(gasUsed, gasLimit int64) (int64, int64) {
|
||||||
|
if gasUsed == 0 {
|
||||||
|
return 0, gasLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
// over = gasLimit/gasUsed - 1 - 0.3
|
||||||
|
// over = min(over, 1)
|
||||||
|
// gasToBurn = (gasLimit - gasUsed) * over
|
||||||
|
|
||||||
|
// so to factor out division from `over`
|
||||||
|
// over*gasUsed = min(gasLimit - (13*gasUsed)/10, gasUsed)
|
||||||
|
// gasToBurn = ((gasLimit - gasUsed)*over*gasUsed) / gasUsed
|
||||||
|
over := gasLimit - (gasOveruseNum*gasUsed)/gasOveruseDenom
|
||||||
|
if over < 0 {
|
||||||
|
return gasLimit - gasUsed, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we want sharper scaling it goes here:
|
||||||
|
// over *= 2
|
||||||
|
|
||||||
|
if over > gasUsed {
|
||||||
|
over = gasUsed
|
||||||
|
}
|
||||||
|
|
||||||
|
// needs bigint, as it overflows in pathological case gasLimit > 2^32 gasUsed = gasLimit / 2
|
||||||
|
gasToBurn := big.NewInt(gasLimit - gasUsed)
|
||||||
|
gasToBurn = gasToBurn.Mul(gasToBurn, big.NewInt(over))
|
||||||
|
gasToBurn = gasToBurn.Div(gasToBurn, big.NewInt(gasUsed))
|
||||||
|
|
||||||
|
return gasLimit - gasUsed - gasToBurn.Int64(), gasToBurn.Int64()
|
||||||
|
}
|
39
chain/vm/burn_test.go
Normal file
39
chain/vm/burn_test.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package vm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGasBurn(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
used int64
|
||||||
|
limit int64
|
||||||
|
refund int64
|
||||||
|
burn int64
|
||||||
|
}{
|
||||||
|
{100, 200, 10, 90},
|
||||||
|
{100, 150, 30, 20},
|
||||||
|
{1000, 1300, 240, 60},
|
||||||
|
{500, 700, 140, 60},
|
||||||
|
{200, 200, 0, 0},
|
||||||
|
{20000, 21000, 1000, 0},
|
||||||
|
{0, 2000, 0, 2000},
|
||||||
|
{500, 651, 121, 30},
|
||||||
|
{500, 5000, 0, 4500},
|
||||||
|
{7499e6, 7500e6, 1000000, 0},
|
||||||
|
{7500e6 / 2, 7500e6, 375000000, 3375000000},
|
||||||
|
{1, 7500e6, 0, 7499999999},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(fmt.Sprintf("%v", test), func(t *testing.T) {
|
||||||
|
refund, toBurn := ComputeGasOutputs(test.used, test.limit)
|
||||||
|
assert.Equal(t, test.refund, refund, "refund")
|
||||||
|
assert.Equal(t, test.burn, toBurn, "burned")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -454,12 +454,22 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
if gasUsed < 0 {
|
if gasUsed < 0 {
|
||||||
gasUsed = 0
|
gasUsed = 0
|
||||||
}
|
}
|
||||||
|
gasRefund, gasToBurn := ComputeGasOutputs(gasUsed, msg.GasLimit)
|
||||||
|
|
||||||
// refund unused gas
|
// refund unused gas
|
||||||
refund := types.BigMul(types.NewInt(uint64(msg.GasLimit-gasUsed)), msg.GasPrice)
|
refund := types.BigMul(types.NewInt(uint64(gasRefund)), msg.GasPrice)
|
||||||
if err := vm.transferFromGasHolder(msg.From, gasHolder, refund); err != nil {
|
if err := vm.transferFromGasHolder(msg.From, gasHolder, refund); err != nil {
|
||||||
return nil, xerrors.Errorf("failed to refund gas")
|
return nil, xerrors.Errorf("failed to refund gas")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if gasToBurn > 0 {
|
||||||
|
// burn overallocated gas
|
||||||
|
burn := types.BigMul(types.NewInt(uint64(gasToBurn)), msg.GasPrice)
|
||||||
|
if err := vm.transferFromGasHolder(builtin.BurntFundsActorAddr, gasHolder, burn); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to burn over estimated gas")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gasReward := types.BigMul(msg.GasPrice, types.NewInt(uint64(gasUsed)))
|
gasReward := types.BigMul(msg.GasPrice, types.NewInt(uint64(gasUsed)))
|
||||||
if err := vm.transferFromGasHolder(builtin.RewardActorAddr, gasHolder, gasReward); err != nil {
|
if err := vm.transferFromGasHolder(builtin.RewardActorAddr, gasHolder, gasReward); err != nil {
|
||||||
return nil, xerrors.Errorf("failed to give miner gas reward: %w", err)
|
return nil, xerrors.Errorf("failed to give miner gas reward: %w", err)
|
||||||
|
2
go.mod
2
go.mod
@ -18,7 +18,7 @@ require (
|
|||||||
github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4
|
github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4
|
||||||
github.com/drand/kyber v1.1.1
|
github.com/drand/kyber v1.1.1
|
||||||
github.com/fatih/color v1.8.0
|
github.com/fatih/color v1.8.0
|
||||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200731192946-f90377ebe789
|
github.com/filecoin-project/chain-validation v0.0.6-0.20200805210314-9844c5869f53
|
||||||
github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d
|
github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d
|
||||||
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef
|
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef
|
||||||
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20200731171407-e559a0579161 // indirect
|
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20200731171407-e559a0579161 // indirect
|
||||||
|
4
go.sum
4
go.sum
@ -215,8 +215,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
|
|||||||
github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY=
|
github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY=
|
||||||
github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
|
github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
|
||||||
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
|
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
|
||||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200731192946-f90377ebe789 h1:/q6q6xNQWymV7qVXF2k5poF0QaWdJAqU00LacgANCuM=
|
github.com/filecoin-project/chain-validation v0.0.6-0.20200805210314-9844c5869f53 h1:XRrMct6lOMjVe11dOnurq6vsLayQQyotFJi0YW4Wp8E=
|
||||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200731192946-f90377ebe789/go.mod h1:JICNIbIEZ+qNJ/PQlHxjei6SaeBbW+yV2r4BcShsXfI=
|
github.com/filecoin-project/chain-validation v0.0.6-0.20200805210314-9844c5869f53/go.mod h1:JICNIbIEZ+qNJ/PQlHxjei6SaeBbW+yV2r4BcShsXfI=
|
||||||
github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
||||||
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
||||||
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U=
|
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U=
|
||||||
|
Loading…
Reference in New Issue
Block a user