From 648130eec5ece682cacd239a0c4ea8122361c987 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sat, 29 Aug 2020 15:55:19 +0300 Subject: [PATCH 1/2] don't include negative performing chains in priority message selection --- chain/messagepool/repub.go | 2 +- chain/messagepool/selection.go | 42 ++++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/chain/messagepool/repub.go b/chain/messagepool/repub.go index ba375cab888..acbf23892b8 100644 --- a/chain/messagepool/repub.go +++ b/chain/messagepool/repub.go @@ -108,7 +108,7 @@ func (mp *MessagePool) republishPendingMessages() error { // we can't fit the current chain but there is gas to spare // trim it and push it down - chain.Trim(gasLimit, mp, baseFee, ts, false) + chain.Trim(gasLimit, mp, baseFee, ts) for j := i; j < len(chains)-1; j++ { if chains[j].Before(chains[j+1]) { break diff --git a/chain/messagepool/selection.go b/chain/messagepool/selection.go index b39eb01cb89..7f7babba0bd 100644 --- a/chain/messagepool/selection.go +++ b/chain/messagepool/selection.go @@ -217,7 +217,7 @@ tailLoop: for gasLimit >= minGas && last < len(chains) { // trim if necessary if chains[last].gasLimit > gasLimit { - chains[last].Trim(gasLimit, mp, baseFee, ts, false) + chains[last].Trim(gasLimit, mp, baseFee, ts) } // push down if it hasn't been invalidated @@ -284,7 +284,7 @@ tailLoop: } // dependencies fit, just trim it - chain.Trim(gasLimit-depGasLimit, mp, baseFee, ts, false) + chain.Trim(gasLimit-depGasLimit, mp, baseFee, ts) last += i continue tailLoop } @@ -389,7 +389,7 @@ func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.S tailLoop: for gasLimit >= minGas && last < len(chains) { // trim - chains[last].Trim(gasLimit, mp, baseFee, ts, false) + chains[last].Trim(gasLimit, mp, baseFee, ts) // push down if it hasn't been invalidated if chains[last].valid { @@ -462,15 +462,27 @@ func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[ui } } + if len(chains) == 0 { + return nil, gasLimit + } + // 2. Sort the chains sort.Slice(chains, func(i, j int) bool { return chains[i].Before(chains[j]) }) - // 3. Merge chains until the block limit; we are willing to include negative performing chains - // as these are messages from our own miners + if len(chains) != 0 && chains[0].gasPerf < 0 { + log.Warnw("all priority messages in mpool have negative gas performance", "bestGasPerf", chains[0].gasPerf) + return nil, gasLimit + } + + // 3. Merge chains until the block limit, as long as they have non-negative gas performance last := len(chains) for i, chain := range chains { + if chain.gasPerf < 0 { + break + } + if chain.gasLimit <= gasLimit { gasLimit -= chain.gasLimit result = append(result, chain.msgs...) @@ -484,8 +496,8 @@ func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[ui tailLoop: for gasLimit >= minGas && last < len(chains) { - // trim, without discarding negative performing messages - chains[last].Trim(gasLimit, mp, baseFee, ts, true) + // trim, discarding negative performing messages + chains[last].Trim(gasLimit, mp, baseFee, ts) // push down if it hasn't been invalidated if chains[last].valid { @@ -503,6 +515,12 @@ tailLoop: if !chain.valid { continue } + + // if gasPerf < 0 we have no more profitable chains + if chain.gasPerf < 0 { + break tailLoop + } + // does it fit in the bock? if chain.gasLimit <= gasLimit { gasLimit -= chain.gasLimit @@ -515,9 +533,9 @@ tailLoop: continue tailLoop } - // the merge loop ended after processing all the chains and we probably still have gas to spare - // -- mark the end. - last = len(chains) + // the merge loop ended after processing all the chains and we probably still have gas to spare; + // end the loop + break } return result, gasLimit @@ -755,9 +773,9 @@ func (mc *msgChain) Before(other *msgChain) bool { (mc.gasPerf == other.gasPerf && mc.gasReward.Cmp(other.gasReward) > 0) } -func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt, ts *types.TipSet, priority bool) { +func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt, ts *types.TipSet) { i := len(mc.msgs) - 1 - for i >= 0 && (mc.gasLimit > gasLimit || (!priority && mc.gasPerf < 0)) { + for i >= 0 && (mc.gasLimit > gasLimit || mc.gasPerf < 0) { gasReward := mp.getGasReward(mc.msgs[i], baseFee, ts) mc.gasReward = new(big.Int).Sub(mc.gasReward, gasReward) mc.gasLimit -= mc.msgs[i].Message.GasLimit From fba3ed7b4d73b6cb903176ec9a7048e1b70b6ed0 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sat, 29 Aug 2020 15:56:31 +0300 Subject: [PATCH 2/2] update documentation about priority addresses --- documentation/en/mpool.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/en/mpool.md b/documentation/en/mpool.md index bbb7f244054..65e7ce2d716 100644 --- a/documentation/en/mpool.md +++ b/documentation/en/mpool.md @@ -133,7 +133,7 @@ type MpoolConfig struct { 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. + be included in a block during message selection, as long as they are profitable. Miners should configure their own worker addresses so that they include their own messages when they produce a new block. Default is empty.