forked from cerc-io/plugeth
all: move main transaction pool into a subpool (#27463)
* all: move main transaction pool into a subpool * go.mod: remove superfluous updates * core/txpool: review fixes, handle txs rejected by all subpools * core/txpool: typos
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
// Copyright 2023 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package event
|
||||
|
||||
// JoinSubscriptions joins multiple subscriptions to be able to track them as
|
||||
// one entity and collectively cancel them of consume any errors from them.
|
||||
func JoinSubscriptions(subs ...Subscription) Subscription {
|
||||
return NewSubscription(func(unsubbed <-chan struct{}) error {
|
||||
// Unsubscribe all subscriptions before returning
|
||||
defer func() {
|
||||
for _, sub := range subs {
|
||||
sub.Unsubscribe()
|
||||
}
|
||||
}()
|
||||
// Wait for an error on any of the subscriptions and propagate up
|
||||
errc := make(chan error, len(subs))
|
||||
for i := range subs {
|
||||
go func(sub Subscription) {
|
||||
select {
|
||||
case err := <-sub.Err():
|
||||
if err != nil {
|
||||
errc <- err
|
||||
}
|
||||
case <-unsubbed:
|
||||
}
|
||||
}(subs[i])
|
||||
}
|
||||
|
||||
select {
|
||||
case err := <-errc:
|
||||
return err
|
||||
case <-unsubbed:
|
||||
return nil
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
// Copyright 2023 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package event
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestMultisub(t *testing.T) {
|
||||
// Create a double subscription and ensure events propagate through
|
||||
var (
|
||||
feed1 Feed
|
||||
feed2 Feed
|
||||
)
|
||||
sink1 := make(chan int, 1)
|
||||
sink2 := make(chan int, 1)
|
||||
|
||||
sub1 := feed1.Subscribe(sink1)
|
||||
sub2 := feed2.Subscribe(sink2)
|
||||
|
||||
sub := JoinSubscriptions(sub1, sub2)
|
||||
|
||||
feed1.Send(1)
|
||||
select {
|
||||
case n := <-sink1:
|
||||
if n != 1 {
|
||||
t.Errorf("sink 1 delivery mismatch: have %d, want %d", n, 1)
|
||||
}
|
||||
default:
|
||||
t.Error("sink 1 missing delivery")
|
||||
}
|
||||
|
||||
feed2.Send(2)
|
||||
select {
|
||||
case n := <-sink2:
|
||||
if n != 2 {
|
||||
t.Errorf("sink 2 delivery mismatch: have %d, want %d", n, 2)
|
||||
}
|
||||
default:
|
||||
t.Error("sink 2 missing delivery")
|
||||
}
|
||||
// Unsubscribe and ensure no more events are delivered
|
||||
sub.Unsubscribe()
|
||||
select {
|
||||
case <-sub.Err():
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
t.Error("multisub didn't propagate closure")
|
||||
}
|
||||
|
||||
feed1.Send(11)
|
||||
select {
|
||||
case n := <-sink1:
|
||||
t.Errorf("sink 1 unexpected delivery: %d", n)
|
||||
default:
|
||||
}
|
||||
|
||||
feed2.Send(22)
|
||||
select {
|
||||
case n := <-sink2:
|
||||
t.Errorf("sink 2 unexpected delivery: %d", n)
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func TestMutisubPartialUnsubscribe(t *testing.T) {
|
||||
// Create a double subscription but terminate one half, ensuring no error
|
||||
// is propagated yet up to the outer subscription
|
||||
var (
|
||||
feed1 Feed
|
||||
feed2 Feed
|
||||
)
|
||||
sink1 := make(chan int, 1)
|
||||
sink2 := make(chan int, 1)
|
||||
|
||||
sub1 := feed1.Subscribe(sink1)
|
||||
sub2 := feed2.Subscribe(sink2)
|
||||
|
||||
sub := JoinSubscriptions(sub1, sub2)
|
||||
|
||||
sub1.Unsubscribe()
|
||||
select {
|
||||
case <-sub.Err():
|
||||
t.Error("multisub propagated closure")
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
}
|
||||
// Ensure that events cross only the second feed
|
||||
feed1.Send(1)
|
||||
select {
|
||||
case n := <-sink1:
|
||||
t.Errorf("sink 1 unexpected delivery: %d", n)
|
||||
default:
|
||||
}
|
||||
|
||||
feed2.Send(2)
|
||||
select {
|
||||
case n := <-sink2:
|
||||
if n != 2 {
|
||||
t.Errorf("sink 2 delivery mismatch: have %d, want %d", n, 2)
|
||||
}
|
||||
default:
|
||||
t.Error("sink 2 missing delivery")
|
||||
}
|
||||
// Unsubscribe and ensure no more events are delivered
|
||||
sub.Unsubscribe()
|
||||
select {
|
||||
case <-sub.Err():
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
t.Error("multisub didn't propagate closure")
|
||||
}
|
||||
|
||||
feed1.Send(11)
|
||||
select {
|
||||
case n := <-sink1:
|
||||
t.Errorf("sink 1 unexpected delivery: %d", n)
|
||||
default:
|
||||
}
|
||||
|
||||
feed2.Send(22)
|
||||
select {
|
||||
case n := <-sink2:
|
||||
t.Errorf("sink 2 unexpected delivery: %d", n)
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultisubFullUnsubscribe(t *testing.T) {
|
||||
// Create a double subscription and terminate the multi sub, ensuring an
|
||||
// error is propagated up.
|
||||
var (
|
||||
feed1 Feed
|
||||
feed2 Feed
|
||||
)
|
||||
sink1 := make(chan int, 1)
|
||||
sink2 := make(chan int, 1)
|
||||
|
||||
sub1 := feed1.Subscribe(sink1)
|
||||
sub2 := feed2.Subscribe(sink2)
|
||||
|
||||
sub := JoinSubscriptions(sub1, sub2)
|
||||
sub.Unsubscribe()
|
||||
select {
|
||||
case <-sub.Err():
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
t.Error("multisub didn't propagate closure")
|
||||
}
|
||||
// Ensure no more events are delivered
|
||||
feed1.Send(1)
|
||||
select {
|
||||
case n := <-sink1:
|
||||
t.Errorf("sink 1 unexpected delivery: %d", n)
|
||||
default:
|
||||
}
|
||||
|
||||
feed2.Send(2)
|
||||
select {
|
||||
case n := <-sink2:
|
||||
t.Errorf("sink 2 unexpected delivery: %d", n)
|
||||
default:
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user