diff --git a/api/api_full.go b/api/api_full.go index 7cc88fa80..9a8643146 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -185,7 +185,7 @@ type FullNode interface { MpoolSub(context.Context) (<-chan MpoolUpdate, error) // MpoolClear clears all pending messages from the mpool - MpoolClear(context.Context) error + MpoolClear(context.Context, bool) error // MpoolGetConfig returns (a copy of) the current mpool config MpoolGetConfig(context.Context) (*types.MpoolConfig, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 219aea495..05f22139a 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -107,7 +107,7 @@ type FullNodeStruct struct { MpoolSelect func(context.Context, types.TipSetKey, float64) ([]*types.SignedMessage, error) `perm:"read"` MpoolPending func(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"` - MpoolClear func(context.Context) error `perm:"write"` + MpoolClear func(context.Context, bool) error `perm:"write"` MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"` MpoolPushMessage func(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"` @@ -496,8 +496,8 @@ func (c *FullNodeStruct) MpoolPending(ctx context.Context, tsk types.TipSetKey) return c.Internal.MpoolPending(ctx, tsk) } -func (c *FullNodeStruct) MpoolClear(ctx context.Context) error { - return c.Internal.MpoolClear(ctx) +func (c *FullNodeStruct) MpoolClear(ctx context.Context, localonly bool) error { + return c.Internal.MpoolClear(ctx, localonly) } func (c *FullNodeStruct) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) { diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index 817641ebe..684aa80aa 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -974,7 +974,7 @@ func (mp *MessagePool) loadLocal() error { return nil } -func (mp *MessagePool) Clear() { +func (mp *MessagePool) Clear(localonly bool) { mp.lk.Lock() defer mp.lk.Unlock() @@ -991,9 +991,14 @@ func (mp *MessagePool) Clear() { log.Warnf("error deleting local message: %s", err) } } + + delete(mp.pending, a) } // clear the maps - mp.pending = make(map[address.Address]*msgSet) mp.republished = nil + if !localonly { + mp.pending = make(map[address.Address]*msgSet) + } + } diff --git a/cli/mpool.go b/cli/mpool.go index 3ec77a647..e6f0bacc7 100644 --- a/cli/mpool.go +++ b/cli/mpool.go @@ -87,6 +87,12 @@ var mpoolPending = &cli.Command{ var mpoolClear = &cli.Command{ Name: "clear", Usage: "Clear all pending messages from the mpool (USE WITH CARE)", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "local", + Usage: "clear local messages only", + }, + }, Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) if err != nil { @@ -94,9 +100,10 @@ var mpoolClear = &cli.Command{ } defer closer() - ctx := ReqContext(cctx) + local := cctx.Bool("local") - return api.MpoolClear(ctx) + ctx := ReqContext(cctx) + return api.MpoolClear(ctx, local) }, } diff --git a/documentation/en/mpool.md b/documentation/en/mpool.md index ebca03fcb..d26120d8e 100644 --- a/documentation/en/mpool.md +++ b/documentation/en/mpool.md @@ -20,7 +20,7 @@ The full node API defines the following methods for interacting with the mpool: MpoolSub(context.Context) (<-chan MpoolUpdate, error) MpoolGetConfig(context.Context) (*types.MpoolConfig, error) MpoolSetConfig(context.Context, *types.MpoolConfig) error - MpoolClear(context.Context) error + MpoolClear(context.Context, localonly bool) error ``` ### MpoolPending @@ -64,7 +64,8 @@ Sets the mpool configuration to (a copy of) the supplied configuration object. ### MpoolClear -Unconditionally clears all pending messages from the mpool. +Clears pending messages from the mpool; if `localonly` is `true` then only local messages are cleared. + This should be used with extreme care and only in the case of errors during head changes that would leave the mpool in an inconsistent state. @@ -82,7 +83,7 @@ lotus mpool stat [--local] lotus mpool replace [--gas-feecap ] [--gas-premium ] [--gas-limit ] [from] [nonce] lotus mpool find [--from
] [--to
] [--method ] lotus mpool config [] -lotus mpool clear +lotus mpool clear [--local] ``` ### lotus mpool pending @@ -107,7 +108,9 @@ Searches for messages in the mpool. Gets or sets the current mpool configuration. ### lotus mpool clear -Unconditionally clears all pending messages from the mpool. +Unconditionally clears pending messages from the mpool. +If the `--local` flag is passed, then only local messages are cleared; otherwise all messages +are cleared. *Warning*: this command should only be used in the case of head change errors leaving the mpool in an inconsistent state. diff --git a/node/impl/full/mpool.go b/node/impl/full/mpool.go index bb4ce2b62..388eaa9d0 100644 --- a/node/impl/full/mpool.go +++ b/node/impl/full/mpool.go @@ -105,8 +105,8 @@ func (a *MpoolAPI) MpoolPending(ctx context.Context, tsk types.TipSetKey) ([]*ty } } -func (a *MpoolAPI) MpoolClear(ctx context.Context) error { - a.Mpool.Clear() +func (a *MpoolAPI) MpoolClear(ctx context.Context, localonly bool) error { + a.Mpool.Clear(localonly) return nil }