From 1e80e3ae654f5debfc3cad3fbd7dad3b30767852 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 6 Aug 2020 18:37:28 +0300 Subject: [PATCH] create maximal chains Merge chains when gasPerf is non-descreasing (instead of increasing) to create maximal chains. This also obviates the need for stable sort, as the chains are guaranteed to be in decreasing order for the same actor. --- chain/messagepool/pruning.go | 2 +- chain/messagepool/selection.go | 4 ++-- chain/messagepool/selection_test.go | 37 ++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/chain/messagepool/pruning.go b/chain/messagepool/pruning.go index a4dce3e6d..11719049d 100644 --- a/chain/messagepool/pruning.go +++ b/chain/messagepool/pruning.go @@ -44,7 +44,7 @@ func (mp *MessagePool) pruneMessages(ctx context.Context, ts *types.TipSet) erro } // Sort the chains - sort.SliceStable(chains, func(i, j int) bool { + sort.Slice(chains, func(i, j int) bool { return chains[i].Before(chains[j]) }) diff --git a/chain/messagepool/selection.go b/chain/messagepool/selection.go index e14efe8d1..38f9477f4 100644 --- a/chain/messagepool/selection.go +++ b/chain/messagepool/selection.go @@ -60,7 +60,7 @@ func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedM } // 2. Sort the chains - sort.SliceStable(chains, func(i, j int) bool { + sort.Slice(chains, func(i, j int) bool { return chains[i].Before(chains[j]) }) @@ -373,7 +373,7 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6 merged := 0 for i := len(chains) - 1; i > 0; i-- { - if chains[i].gasPerf > chains[i-1].gasPerf { + if chains[i].gasPerf >= chains[i-1].gasPerf { chains[i-1].msgs = append(chains[i-1].msgs, chains[i].msgs...) chains[i-1].gasReward = new(big.Int).Add(chains[i-1].gasReward, chains[i].gasReward) chains[i-1].gasLimit += chains[i].gasLimit diff --git a/chain/messagepool/selection_test.go b/chain/messagepool/selection_test.go index 0bef30d00..bc382bb43 100644 --- a/chain/messagepool/selection_test.go +++ b/chain/messagepool/selection_test.go @@ -127,14 +127,45 @@ func TestMessageChains(t *testing.T) { } } - // test3: 10 messages from a1 to a2, with gasPerf increasing in groups of 3; it should - // make 4 chains, the first 3 with 3 messages and the last with a single message + // test3a: 10 messages from a1 to a2, with gasPerf increasing in groups of 3; it should + // merge them in two chains, one with 9 messages and one with the last message mset = make(map[uint64]*types.SignedMessage) for i := 0; i < 10; i++ { m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(1+i%3)) mset[uint64(i)] = m } + chains = mp.createMessageChains(a1, mset, ts) + if len(chains) != 2 { + t.Fatal("expected 1 chain") + } + + if len(chains[0].msgs) != 9 { + t.Fatalf("expected 9 messages in the chain but got %d", len(chains[0].msgs)) + } + if len(chains[1].msgs) != 1 { + t.Fatalf("expected 1 messages in the chain but got %d", len(chains[1].msgs)) + } + nextNonce := 0 + for _, chain := range chains { + for _, m := range chain.msgs { + if m.Message.Nonce != uint64(nextNonce) { + t.Fatalf("expected nonce %d but got %d", nextNonce, m.Message.Nonce) + } + nextNonce++ + } + } + + // test3b: 10 messages from a1 to a2, with gasPerf decreasing in groups of 3 with a bias for the + // earlier chains; it should make 4 chains, the first 3 with 3 messages and the last with + // a single message + mset = make(map[uint64]*types.SignedMessage) + for i := 0; i < 10; i++ { + bias := (12 - i) / 3 + m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(1+i%3+bias)) + mset[uint64(i)] = m + } + chains = mp.createMessageChains(a1, mset, ts) if len(chains) != 4 { t.Fatal("expected 4 chains") @@ -148,7 +179,7 @@ func TestMessageChains(t *testing.T) { t.Fatalf("expected %d message in chain %d but got %d", expectedLen, i, len(chain.msgs)) } } - nextNonce := 0 + nextNonce = 0 for _, chain := range chains { for _, m := range chain.msgs { if m.Message.Nonce != uint64(nextNonce) {