diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index 09b888101f2..64add44d714 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -11,6 +11,7 @@ import ( "sync" "time" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" "github.com/hashicorp/go-multierror" lru "github.com/hashicorp/golang-lru" @@ -154,6 +155,11 @@ func newMsgSet(nonce uint64) *msgSet { } } +func ComputeMinRBF(curPrem abi.TokenAmount) abi.TokenAmount { + minPrice := types.BigAdd(curPrem, types.BigDiv(types.BigMul(curPrem, rbfNumBig), rbfDenomBig)) + return types.BigAdd(minPrice, types.NewInt(1)) +} + func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict bool) (bool, error) { nextNonce := ms.nextNonce nonceGap := false @@ -181,9 +187,7 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict bool) (boo if m.Cid() != exms.Cid() { // check if RBF passes - minPrice := exms.Message.GasPremium - minPrice = types.BigAdd(minPrice, types.BigDiv(types.BigMul(minPrice, rbfNumBig), rbfDenomBig)) - minPrice = types.BigAdd(minPrice, types.NewInt(1)) + minPrice := ComputeMinRBF(exms.Message.GasPremium) if types.BigCmp(m.Message.GasPremium, minPrice) >= 0 { log.Infow("add with RBF", "oldpremium", exms.Message.GasPremium, "newpremium", m.Message.GasPremium, "addr", m.Message.From, "nonce", m.Message.Nonce) diff --git a/cli/mpool.go b/cli/mpool.go index 6e335a24330..6561e2cbc26 100644 --- a/cli/mpool.go +++ b/cli/mpool.go @@ -11,7 +11,10 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/messagepool" "github.com/filecoin-project/lotus/chain/types" ) @@ -293,6 +296,10 @@ var mpoolReplaceCmd = &cli.Command{ Name: "gas-limit", Usage: "gas price for new message", }, + &cli.BoolFlag{ + Name: "auto", + Usage: "automatically reprice the specified message", + }, }, ArgsUsage: "[from] [nonce]", Action: func(cctx *cli.Context) error { @@ -342,15 +349,29 @@ var mpoolReplaceCmd = &cli.Command{ msg := found.Message - msg.GasLimit = cctx.Int64("gas-limit") - msg.GasPremium, err = types.BigFromString(cctx.String("gas-premium")) - if err != nil { - return fmt.Errorf("parsing gas-premium: %w", err) - } - // TODO: estimate fee cap here - msg.GasFeeCap, err = types.BigFromString(cctx.String("gas-feecap")) - if err != nil { - return fmt.Errorf("parsing gas-feecap: %w", err) + if cctx.Bool("auto") { + // msg.GasLimit = 0 // TODO: need to fix the way we estimate gas limits to account for the messages already being in the mempool + msg.GasFeeCap = abi.NewTokenAmount(0) + msg.GasPremium = abi.NewTokenAmount(0) + retm, err := api.GasEstimateMessageGas(ctx, &msg, &lapi.MessageSendSpec{}, types.EmptyTSK) + if err != nil { + return fmt.Errorf("failed to estimate gas values: %w", err) + } + msg.GasFeeCap = retm.GasFeeCap + + minRBF := messagepool.ComputeMinRBF(msg.GasPremium) + msg.GasPremium = big.Max(retm.GasPremium, minRBF) + } else { + msg.GasLimit = cctx.Int64("gas-limit") + msg.GasPremium, err = types.BigFromString(cctx.String("gas-premium")) + if err != nil { + return fmt.Errorf("parsing gas-premium: %w", err) + } + // TODO: estimate fee cap here + msg.GasFeeCap, err = types.BigFromString(cctx.String("gas-feecap")) + if err != nil { + return fmt.Errorf("parsing gas-feecap: %w", err) + } } smsg, err := api.WalletSignMessage(ctx, msg.From, &msg)