From 054fc4a61480c69ac8dac6d0c384ff181d2a518d Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 16 Aug 2020 09:57:53 +0300 Subject: [PATCH 1/2] add client command for mpool config --- cli/mpool.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/cli/mpool.go b/cli/mpool.go index dff4a8110..62ab06dae 100644 --- a/cli/mpool.go +++ b/cli/mpool.go @@ -24,6 +24,7 @@ var mpoolCmd = &cli.Command{ mpoolStat, mpoolReplaceCmd, mpoolFindCmd, + mpoolConfig, }, } @@ -415,3 +416,48 @@ var mpoolFindCmd = &cli.Command{ return nil }, } + +var mpoolConfig = &cli.Command{ + Name: "config", + Usage: "get or set current mpool configuration", + ArgsUsage: "[new-config]", + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() > 1 { + return cli.ShowCommandHelp(cctx, cctx.Command.Name) + } + + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := ReqContext(cctx) + + if cctx.Args().Len() == 0 { + cfg, err := api.MpoolGetConfig(ctx) + if err != nil { + return err + } + + bytes, err := json.Marshal(cfg) + if err != nil { + return err + } + + fmt.Println(string(bytes)) + } else { + cfg := new(types.MpoolConfig) + bytes := []byte(cctx.Args().Get(0)) + + err := json.Unmarshal(bytes, cfg) + if err != nil { + return err + } + + return api.MpoolSetConfig(ctx, cfg) + } + + return nil + }, +} From aa679a735972444d00b8a52104d8083ba42484ed Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 16 Aug 2020 10:57:17 +0300 Subject: [PATCH 2/2] add message pool documentation --- documentation/en/.library.json | 12 ++- documentation/en/mpool.md | 155 +++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 documentation/en/mpool.md diff --git a/documentation/en/.library.json b/documentation/en/.library.json index 55681b90b..4d348c145 100644 --- a/documentation/en/.library.json +++ b/documentation/en/.library.json @@ -75,8 +75,16 @@ "slug": "en+arch", "github": "en/architecture.md", "value": null, - "posts": [] - }, { + "posts": [ + { + "title": "The Message Pool", + "slug": "en+mpool", + "github": "en/mpool.md", + "value": null + } + ] + }, + { "title": "Storage Mining", "slug": "en+mining", "github": "en/mining.md", diff --git a/documentation/en/mpool.md b/documentation/en/mpool.md new file mode 100644 index 000000000..5ce9742f1 --- /dev/null +++ b/documentation/en/mpool.md @@ -0,0 +1,155 @@ +# The Message Pool + +The Message Pool (mpool) is the component of lotus that handles +pending messages for inclusion in the chain. Messages are added to the +mpool either directly for locally published messages or through pubsub +propagation. Whenever a miner is ready to create a block for a +tipset, it invokes the mpool selection algorithm which selects an +appropriate set of messages such that it optimizes miner reward and +chain capacity. + +## API + +The full node API defines the following methods for interacting with the mpool: +``` + MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) + MpoolSelect(context.Context, types.TipSetKey, float64) ([]*types.SignedMessage, error) + MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error) + MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error) + MpoolGetNonce(context.Context, address.Address) (uint64, error) + MpoolSub(context.Context) (<-chan MpoolUpdate, error) + MpoolGetConfig(context.Context) (*types.MpoolConfig, error) + MpoolSetConfig(context.Context, *types.MpoolConfig) error +``` + +### MpoolPending + +Returns the list of messages that are pending for a tipset. + +### MpoolSelect + +Selects and returns a list of pending messages for inclusion in the next block. + +### MpoolPush + +Pushes a signed message to the mpool; returns the CID of the message. + +### MpoolPushMessage + +Atomically assigns a nonce, signs, and pushes a message to the mpool. + +The MaxFee field of the spec argument is only used when +GasFeeCap/GasPremium fields aren't specified in the message. When +maxFee is set to 0, MpoolPushMessage will guess appropriate fee based +on current chain conditions. + +### MpoolGetNonce + +Returns the next nonce for the specified sender. Note that this method may not be atomic. +Use `MpoolPushMessage` instead. + +### MpoolSub + +Returns a channel to receive notifications about updates to the message pool. +Note that the context *must* be cancelled when the caller is done with the subscription. + +### MpoolGetConfig + +Returns (a copy of) the current mpool configuration. + +### MpoolSetConfig + +Sets the mpool configuration to (a copy of) the supplied configuration object. + + +## Command Line Interfae + +The lotus command line interface defines an `mpool` command which +allows a user to interact with the mpool. + +The following commands are supported: +``` +lotus mpool pending [--local] +lotus mpool sub +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 pending +Prints the pending messages in the mpool, as returned by the `MpoolPending` API call. +If `--local` is specified, it only prints pending messages for addresses in the local wallet. + +### lotus mpool sub +Subscribes to mpool changes using the `MpoolSub` API call and prints the stream of mpool +updates. + +### lotus mpool stat +Prints various mpool statistics. +If `--local` is specified then only prints statistics for addresses in the local wallet. + +### lotus mpool replace +Replaces a message in the mpool. + +### lotus mpool find +Searches for messages in the mpool. + +### lotus mpool config +Gets or sets the current mpool configuration. + +## Configuration + +The mpool a few parameters that can be configured by the user, either through the API +or the command line interface. + +The config struct is defined as follows: +``` +type MpoolConfig struct { + PriorityAddrs []address.Address + SizeLimitHigh int + SizeLimitLow int + ReplaceByFeeRatio float64 + PruneCooldown time.Duration + GasLimitOverestimation float64 +} + +``` + +The meaning of these fields is as follows: +- `PriorityAddrs` -- these are the addresses of actors whose pending messages should always + be included in a block during message selection, regardless of profitability. + Miners should configure their own worker addresses so that they include their own messages + when they produce a new block. +- `SizeLimitHigh` -- this is the maximum number of pending messages before triggering a + prune in the message pool. Note that messages from priority addresses are never pruned. +- `SizeLimitLow` -- this is the number of pending messages that should be kept after a prune. +- `ReplaceByFeeRatio` -- this is the gas fee ratio for replacing messages in the mpool. + Whenever a message is replaced, the `GasPremium` must be increased by this ratio. +- `PruneCooldown` -- this is the period of time to wait before triggering a new prune. +- `GasLimitOverestimation` -- this is a parameter that controls the gas limit overestimation for new messages. + + +## Message Selection + +A few words regarding message selection are pertinent. In message +selection, a miner selects a set of messages from the pending messages +for inclusion to the next block in order to maximize its reward. The +problem however is NP-hard (it's an instance of knapsack packing), +further confounded by the fact that miners don't communicate their +tickets to each other. So at best we can approximate the optimal +selection in a reasonable amount of time. + +The mpool employs a sophisticated algorithm for selecting messages for +inclusion, given the ticket quality of a miner. The ticket quality +reflects the probability that a block will execute in the +tipset. Given the ticket quality the algorithm computes the +probability of each block, and picks dependent chains of messages such +that the reward is maximized, while also optimizing the capacity of +the chain. If the ticket quality is sufficiently high, then a greedy +selection algorithm is used instead that simply picks dependent chains of +maximum reward. Note that pending message chains from priority addresses +are always selected, regardless of their profitability. + +For algorithm details, please prefer to the implementation in +`chain/messagepool/selection.go`.