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.
This commit is contained in:
vyzo 2020-08-06 18:37:28 +03:00
parent 7a8c74fee8
commit 1e80e3ae65
3 changed files with 37 additions and 6 deletions

View File

@ -44,7 +44,7 @@ func (mp *MessagePool) pruneMessages(ctx context.Context, ts *types.TipSet) erro
} }
// Sort the chains // 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]) return chains[i].Before(chains[j])
}) })

View File

@ -60,7 +60,7 @@ func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedM
} }
// 2. Sort the chains // 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]) return chains[i].Before(chains[j])
}) })
@ -373,7 +373,7 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6
merged := 0 merged := 0
for i := len(chains) - 1; i > 0; i-- { 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].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].gasReward = new(big.Int).Add(chains[i-1].gasReward, chains[i].gasReward)
chains[i-1].gasLimit += chains[i].gasLimit chains[i-1].gasLimit += chains[i].gasLimit

View File

@ -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 // test3a: 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 // merge them in two chains, one with 9 messages and one with the last message
mset = make(map[uint64]*types.SignedMessage) mset = make(map[uint64]*types.SignedMessage)
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(1+i%3)) m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(1+i%3))
mset[uint64(i)] = m 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) chains = mp.createMessageChains(a1, mset, ts)
if len(chains) != 4 { if len(chains) != 4 {
t.Fatal("expected 4 chains") 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)) 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 _, chain := range chains {
for _, m := range chain.msgs { for _, m := range chain.msgs {
if m.Message.Nonce != uint64(nextNonce) { if m.Message.Nonce != uint64(nextNonce) {