Merge pull request #2223 from filecoin-project/feat/miner-msg-select-use-gas-price-is-more-better
miner: Use gas price when selecting messages
This commit is contained in:
commit
18199ff323
@ -4,11 +4,14 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
big2 "math/big"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
address "github.com/filecoin-project/go-address"
|
address "github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
@ -482,10 +485,19 @@ func SelectMessages(ctx context.Context, al ActorLookup, ts *types.TipSet, msgs
|
|||||||
fallback: al,
|
fallback: al,
|
||||||
}).StateGetActor
|
}).StateGetActor
|
||||||
|
|
||||||
out := make([]*types.SignedMessage, 0, build.BlockMessageLimit)
|
type senderMeta struct {
|
||||||
|
lastReward abi.TokenAmount
|
||||||
|
lastGasLimit int64
|
||||||
|
|
||||||
|
gasReward []abi.TokenAmount
|
||||||
|
gasLimit []int64
|
||||||
|
|
||||||
|
msgs []*types.SignedMessage
|
||||||
|
}
|
||||||
|
|
||||||
inclNonces := make(map[address.Address]uint64)
|
inclNonces := make(map[address.Address]uint64)
|
||||||
inclBalances := make(map[address.Address]types.BigInt)
|
inclBalances := make(map[address.Address]big.Int)
|
||||||
inclCount := make(map[address.Address]int)
|
outBySender := make(map[address.Address]*senderMeta)
|
||||||
|
|
||||||
tooLowFundMsgs := 0
|
tooLowFundMsgs := 0
|
||||||
tooHighNonceMsgs := 0
|
tooHighNonceMsgs := 0
|
||||||
@ -494,6 +506,10 @@ func SelectMessages(ctx context.Context, al ActorLookup, ts *types.TipSet, msgs
|
|||||||
vmValid := time.Duration(0)
|
vmValid := time.Duration(0)
|
||||||
getbal := time.Duration(0)
|
getbal := time.Duration(0)
|
||||||
|
|
||||||
|
sort.Slice(msgs, func(i, j int) bool {
|
||||||
|
return msgs[i].Message.Nonce < msgs[j].Message.Nonce
|
||||||
|
})
|
||||||
|
|
||||||
for _, msg := range msgs {
|
for _, msg := range msgs {
|
||||||
vmstart := time.Now()
|
vmstart := time.Now()
|
||||||
|
|
||||||
@ -549,11 +565,78 @@ func SelectMessages(ctx context.Context, al ActorLookup, ts *types.TipSet, msgs
|
|||||||
|
|
||||||
inclNonces[from] = msg.Message.Nonce + 1
|
inclNonces[from] = msg.Message.Nonce + 1
|
||||||
inclBalances[from] = types.BigSub(inclBalances[from], msg.Message.RequiredFunds())
|
inclBalances[from] = types.BigSub(inclBalances[from], msg.Message.RequiredFunds())
|
||||||
inclCount[from]++
|
sm := outBySender[from]
|
||||||
|
if sm == nil {
|
||||||
|
sm = &senderMeta{
|
||||||
|
lastReward: big.Zero(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out = append(out, msg)
|
sm.gasLimit = append(sm.gasLimit, sm.lastGasLimit+msg.Message.GasLimit)
|
||||||
if len(out) >= build.BlockMessageLimit {
|
sm.lastGasLimit = sm.gasLimit[len(sm.gasLimit)-1]
|
||||||
break
|
|
||||||
|
estimatedReward := big.Mul(types.NewInt(uint64(msg.Message.GasLimit)), msg.Message.GasPrice)
|
||||||
|
// TODO: estimatedReward = estimatedReward * (guessActualGasUse(msg) / msg.GasLimit)
|
||||||
|
|
||||||
|
sm.gasReward = append(sm.gasReward, big.Add(sm.lastReward, estimatedReward))
|
||||||
|
sm.lastReward = sm.gasReward[len(sm.gasReward)-1]
|
||||||
|
|
||||||
|
sm.msgs = append(sm.msgs, msg)
|
||||||
|
|
||||||
|
outBySender[from] = sm
|
||||||
|
}
|
||||||
|
|
||||||
|
gasLimitLeft := int64(build.BlockGasLimit)
|
||||||
|
|
||||||
|
out := make([]*types.SignedMessage, 0, build.BlockMessageLimit)
|
||||||
|
{
|
||||||
|
for {
|
||||||
|
var bestSender address.Address
|
||||||
|
var nBest int
|
||||||
|
var bestGasToReward float64
|
||||||
|
|
||||||
|
// TODO: This is O(n^2)-ish, could use something like container/heap to cache this math
|
||||||
|
for sender, meta := range outBySender {
|
||||||
|
for n := range meta.msgs {
|
||||||
|
if meta.gasLimit[n] > gasLimitLeft {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if n+len(out) > build.BlockMessageLimit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
gasToReward, _ := new(big2.Float).SetInt(meta.gasReward[n].Int).Float64()
|
||||||
|
gasToReward /= float64(meta.gasLimit[n])
|
||||||
|
|
||||||
|
if gasToReward >= bestGasToReward {
|
||||||
|
bestSender = sender
|
||||||
|
nBest = n + 1
|
||||||
|
bestGasToReward = gasToReward
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nBest == 0 {
|
||||||
|
break // block gas limit reached
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
out = append(out, outBySender[bestSender].msgs[:nBest]...)
|
||||||
|
gasLimitLeft -= outBySender[bestSender].gasLimit[nBest-1]
|
||||||
|
|
||||||
|
outBySender[bestSender].msgs = outBySender[bestSender].msgs[nBest:]
|
||||||
|
outBySender[bestSender].gasLimit = outBySender[bestSender].gasLimit[nBest:]
|
||||||
|
outBySender[bestSender].gasReward = outBySender[bestSender].gasReward[nBest:]
|
||||||
|
|
||||||
|
if len(outBySender[bestSender].msgs) == 0 {
|
||||||
|
delete(outBySender, bestSender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(out) >= build.BlockMessageLimit {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user