|
|
@@ -39,23 +39,20 @@ import (
|
|
|
)
|
|
|
|
|
|
type testBackend struct {
|
|
|
- mux *event.TypeMux
|
|
|
- db ethdb.Database
|
|
|
- sections uint64
|
|
|
- txFeed *event.Feed
|
|
|
- rmLogsFeed *event.Feed
|
|
|
- logsFeed *event.Feed
|
|
|
- chainFeed *event.Feed
|
|
|
+ mux *event.TypeMux
|
|
|
+ db ethdb.Database
|
|
|
+ sections uint64
|
|
|
+ txFeed event.Feed
|
|
|
+ logsFeed event.Feed
|
|
|
+ rmLogsFeed event.Feed
|
|
|
+ pendingLogsFeed event.Feed
|
|
|
+ chainFeed event.Feed
|
|
|
}
|
|
|
|
|
|
func (b *testBackend) ChainDb() ethdb.Database {
|
|
|
return b.db
|
|
|
}
|
|
|
|
|
|
-func (b *testBackend) EventMux() *event.TypeMux {
|
|
|
- return b.mux
|
|
|
-}
|
|
|
-
|
|
|
func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
|
|
|
var (
|
|
|
hash common.Hash
|
|
|
@@ -116,6 +113,10 @@ func (b *testBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript
|
|
|
return b.logsFeed.Subscribe(ch)
|
|
|
}
|
|
|
|
|
|
+func (b *testBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription {
|
|
|
+ return b.pendingLogsFeed.Subscribe(ch)
|
|
|
+}
|
|
|
+
|
|
|
func (b *testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
|
|
|
return b.chainFeed.Subscribe(ch)
|
|
|
}
|
|
|
@@ -160,13 +161,8 @@ func TestBlockSubscription(t *testing.T) {
|
|
|
t.Parallel()
|
|
|
|
|
|
var (
|
|
|
- mux = new(event.TypeMux)
|
|
|
db = rawdb.NewMemoryDatabase()
|
|
|
- txFeed = new(event.Feed)
|
|
|
- rmLogsFeed = new(event.Feed)
|
|
|
- logsFeed = new(event.Feed)
|
|
|
- chainFeed = new(event.Feed)
|
|
|
- backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
|
|
|
+ backend = &testBackend{db: db}
|
|
|
api = NewPublicFilterAPI(backend, false)
|
|
|
genesis = new(core.Genesis).MustCommit(db)
|
|
|
chain, _ = core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {})
|
|
|
@@ -205,7 +201,7 @@ func TestBlockSubscription(t *testing.T) {
|
|
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
for _, e := range chainEvents {
|
|
|
- chainFeed.Send(e)
|
|
|
+ backend.chainFeed.Send(e)
|
|
|
}
|
|
|
|
|
|
<-sub0.Err()
|
|
|
@@ -217,14 +213,9 @@ func TestPendingTxFilter(t *testing.T) {
|
|
|
t.Parallel()
|
|
|
|
|
|
var (
|
|
|
- mux = new(event.TypeMux)
|
|
|
- db = rawdb.NewMemoryDatabase()
|
|
|
- txFeed = new(event.Feed)
|
|
|
- rmLogsFeed = new(event.Feed)
|
|
|
- logsFeed = new(event.Feed)
|
|
|
- chainFeed = new(event.Feed)
|
|
|
- backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
|
|
|
- api = NewPublicFilterAPI(backend, false)
|
|
|
+ db = rawdb.NewMemoryDatabase()
|
|
|
+ backend = &testBackend{db: db}
|
|
|
+ api = NewPublicFilterAPI(backend, false)
|
|
|
|
|
|
transactions = []*types.Transaction{
|
|
|
types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
|
|
|
@@ -240,7 +231,7 @@ func TestPendingTxFilter(t *testing.T) {
|
|
|
fid0 := api.NewPendingTransactionFilter()
|
|
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
- txFeed.Send(core.NewTxsEvent{Txs: transactions})
|
|
|
+ backend.txFeed.Send(core.NewTxsEvent{Txs: transactions})
|
|
|
|
|
|
timeout := time.Now().Add(1 * time.Second)
|
|
|
for {
|
|
|
@@ -277,14 +268,9 @@ func TestPendingTxFilter(t *testing.T) {
|
|
|
// If not it must return an error.
|
|
|
func TestLogFilterCreation(t *testing.T) {
|
|
|
var (
|
|
|
- mux = new(event.TypeMux)
|
|
|
- db = rawdb.NewMemoryDatabase()
|
|
|
- txFeed = new(event.Feed)
|
|
|
- rmLogsFeed = new(event.Feed)
|
|
|
- logsFeed = new(event.Feed)
|
|
|
- chainFeed = new(event.Feed)
|
|
|
- backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
|
|
|
- api = NewPublicFilterAPI(backend, false)
|
|
|
+ db = rawdb.NewMemoryDatabase()
|
|
|
+ backend = &testBackend{db: db}
|
|
|
+ api = NewPublicFilterAPI(backend, false)
|
|
|
|
|
|
testCases = []struct {
|
|
|
crit FilterCriteria
|
|
|
@@ -326,14 +312,9 @@ func TestInvalidLogFilterCreation(t *testing.T) {
|
|
|
t.Parallel()
|
|
|
|
|
|
var (
|
|
|
- mux = new(event.TypeMux)
|
|
|
- db = rawdb.NewMemoryDatabase()
|
|
|
- txFeed = new(event.Feed)
|
|
|
- rmLogsFeed = new(event.Feed)
|
|
|
- logsFeed = new(event.Feed)
|
|
|
- chainFeed = new(event.Feed)
|
|
|
- backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
|
|
|
- api = NewPublicFilterAPI(backend, false)
|
|
|
+ db = rawdb.NewMemoryDatabase()
|
|
|
+ backend = &testBackend{db: db}
|
|
|
+ api = NewPublicFilterAPI(backend, false)
|
|
|
)
|
|
|
|
|
|
// different situations where log filter creation should fail.
|
|
|
@@ -353,15 +334,10 @@ func TestInvalidLogFilterCreation(t *testing.T) {
|
|
|
|
|
|
func TestInvalidGetLogsRequest(t *testing.T) {
|
|
|
var (
|
|
|
- mux = new(event.TypeMux)
|
|
|
- db = rawdb.NewMemoryDatabase()
|
|
|
- txFeed = new(event.Feed)
|
|
|
- rmLogsFeed = new(event.Feed)
|
|
|
- logsFeed = new(event.Feed)
|
|
|
- chainFeed = new(event.Feed)
|
|
|
- backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
|
|
|
- api = NewPublicFilterAPI(backend, false)
|
|
|
- blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
|
|
|
+ db = rawdb.NewMemoryDatabase()
|
|
|
+ backend = &testBackend{db: db}
|
|
|
+ api = NewPublicFilterAPI(backend, false)
|
|
|
+ blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
|
|
|
)
|
|
|
|
|
|
// Reason: Cannot specify both BlockHash and FromBlock/ToBlock)
|
|
|
@@ -383,14 +359,9 @@ func TestLogFilter(t *testing.T) {
|
|
|
t.Parallel()
|
|
|
|
|
|
var (
|
|
|
- mux = new(event.TypeMux)
|
|
|
- db = rawdb.NewMemoryDatabase()
|
|
|
- txFeed = new(event.Feed)
|
|
|
- rmLogsFeed = new(event.Feed)
|
|
|
- logsFeed = new(event.Feed)
|
|
|
- chainFeed = new(event.Feed)
|
|
|
- backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
|
|
|
- api = NewPublicFilterAPI(backend, false)
|
|
|
+ db = rawdb.NewMemoryDatabase()
|
|
|
+ backend = &testBackend{db: db}
|
|
|
+ api = NewPublicFilterAPI(backend, false)
|
|
|
|
|
|
firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
|
|
|
secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
|
|
|
@@ -400,7 +371,7 @@ func TestLogFilter(t *testing.T) {
|
|
|
secondTopic = common.HexToHash("0x2222222222222222222222222222222222222222222222222222222222222222")
|
|
|
notUsedTopic = common.HexToHash("0x9999999999999999999999999999999999999999999999999999999999999999")
|
|
|
|
|
|
- // posted twice, once as vm.Logs and once as core.PendingLogsEvent
|
|
|
+ // posted twice, once as regular logs and once as pending logs.
|
|
|
allLogs = []*types.Log{
|
|
|
{Address: firstAddr},
|
|
|
{Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 1},
|
|
|
@@ -453,11 +424,11 @@ func TestLogFilter(t *testing.T) {
|
|
|
|
|
|
// raise events
|
|
|
time.Sleep(1 * time.Second)
|
|
|
- if nsend := logsFeed.Send(allLogs); nsend == 0 {
|
|
|
- t.Fatal("Shoud have at least one subscription")
|
|
|
+ if nsend := backend.logsFeed.Send(allLogs); nsend == 0 {
|
|
|
+ t.Fatal("Logs event not delivered")
|
|
|
}
|
|
|
- if err := mux.Post(core.PendingLogsEvent{Logs: allLogs}); err != nil {
|
|
|
- t.Fatal(err)
|
|
|
+ if nsend := backend.pendingLogsFeed.Send(allLogs); nsend == 0 {
|
|
|
+ t.Fatal("Pending logs event not delivered")
|
|
|
}
|
|
|
|
|
|
for i, tt := range testCases {
|
|
|
@@ -502,14 +473,9 @@ func TestPendingLogsSubscription(t *testing.T) {
|
|
|
t.Parallel()
|
|
|
|
|
|
var (
|
|
|
- mux = new(event.TypeMux)
|
|
|
- db = rawdb.NewMemoryDatabase()
|
|
|
- txFeed = new(event.Feed)
|
|
|
- rmLogsFeed = new(event.Feed)
|
|
|
- logsFeed = new(event.Feed)
|
|
|
- chainFeed = new(event.Feed)
|
|
|
- backend = &testBackend{mux, db, 0, txFeed, rmLogsFeed, logsFeed, chainFeed}
|
|
|
- api = NewPublicFilterAPI(backend, false)
|
|
|
+ db = rawdb.NewMemoryDatabase()
|
|
|
+ backend = &testBackend{db: db}
|
|
|
+ api = NewPublicFilterAPI(backend, false)
|
|
|
|
|
|
firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
|
|
|
secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
|
|
|
@@ -521,26 +487,18 @@ func TestPendingLogsSubscription(t *testing.T) {
|
|
|
fourthTopic = common.HexToHash("0x4444444444444444444444444444444444444444444444444444444444444444")
|
|
|
notUsedTopic = common.HexToHash("0x9999999999999999999999999999999999999999999999999999999999999999")
|
|
|
|
|
|
- allLogs = []core.PendingLogsEvent{
|
|
|
- {Logs: []*types.Log{{Address: firstAddr, Topics: []common.Hash{}, BlockNumber: 0}}},
|
|
|
- {Logs: []*types.Log{{Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 1}}},
|
|
|
- {Logs: []*types.Log{{Address: secondAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 2}}},
|
|
|
- {Logs: []*types.Log{{Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 3}}},
|
|
|
- {Logs: []*types.Log{{Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 4}}},
|
|
|
- {Logs: []*types.Log{
|
|
|
+ allLogs = [][]*types.Log{
|
|
|
+ {{Address: firstAddr, Topics: []common.Hash{}, BlockNumber: 0}},
|
|
|
+ {{Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 1}},
|
|
|
+ {{Address: secondAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 2}},
|
|
|
+ {{Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 3}},
|
|
|
+ {{Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 4}},
|
|
|
+ {
|
|
|
{Address: thirdAddress, Topics: []common.Hash{firstTopic}, BlockNumber: 5},
|
|
|
{Address: thirdAddress, Topics: []common.Hash{thirdTopic}, BlockNumber: 5},
|
|
|
{Address: thirdAddress, Topics: []common.Hash{fourthTopic}, BlockNumber: 5},
|
|
|
{Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 5},
|
|
|
- }},
|
|
|
- }
|
|
|
-
|
|
|
- convertLogs = func(pl []core.PendingLogsEvent) []*types.Log {
|
|
|
- var logs []*types.Log
|
|
|
- for _, l := range pl {
|
|
|
- logs = append(logs, l.Logs...)
|
|
|
- }
|
|
|
- return logs
|
|
|
+ },
|
|
|
}
|
|
|
|
|
|
testCases = []struct {
|
|
|
@@ -550,21 +508,52 @@ func TestPendingLogsSubscription(t *testing.T) {
|
|
|
sub *Subscription
|
|
|
}{
|
|
|
// match all
|
|
|
- {ethereum.FilterQuery{}, convertLogs(allLogs), nil, nil},
|
|
|
+ {
|
|
|
+ ethereum.FilterQuery{}, flattenLogs(allLogs),
|
|
|
+ nil, nil,
|
|
|
+ },
|
|
|
// match none due to no matching addresses
|
|
|
- {ethereum.FilterQuery{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}}, []*types.Log{}, nil, nil},
|
|
|
+ {
|
|
|
+ ethereum.FilterQuery{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}},
|
|
|
+ nil,
|
|
|
+ nil, nil,
|
|
|
+ },
|
|
|
// match logs based on addresses, ignore topics
|
|
|
- {ethereum.FilterQuery{Addresses: []common.Address{firstAddr}}, append(convertLogs(allLogs[:2]), allLogs[5].Logs[3]), nil, nil},
|
|
|
+ {
|
|
|
+ ethereum.FilterQuery{Addresses: []common.Address{firstAddr}},
|
|
|
+ append(flattenLogs(allLogs[:2]), allLogs[5][3]),
|
|
|
+ nil, nil,
|
|
|
+ },
|
|
|
// match none due to no matching topics (match with address)
|
|
|
- {ethereum.FilterQuery{Addresses: []common.Address{secondAddr}, Topics: [][]common.Hash{{notUsedTopic}}}, []*types.Log{}, nil, nil},
|
|
|
+ {
|
|
|
+ ethereum.FilterQuery{Addresses: []common.Address{secondAddr}, Topics: [][]common.Hash{{notUsedTopic}}},
|
|
|
+ nil, nil, nil,
|
|
|
+ },
|
|
|
// match logs based on addresses and topics
|
|
|
- {ethereum.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, append(convertLogs(allLogs[3:5]), allLogs[5].Logs[0]), nil, nil},
|
|
|
+ {
|
|
|
+ ethereum.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}},
|
|
|
+ append(flattenLogs(allLogs[3:5]), allLogs[5][0]),
|
|
|
+ nil, nil,
|
|
|
+ },
|
|
|
// match logs based on multiple addresses and "or" topics
|
|
|
- {ethereum.FilterQuery{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, append(convertLogs(allLogs[2:5]), allLogs[5].Logs[0]), nil, nil},
|
|
|
+ {
|
|
|
+ ethereum.FilterQuery{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}},
|
|
|
+ append(flattenLogs(allLogs[2:5]), allLogs[5][0]),
|
|
|
+ nil,
|
|
|
+ nil,
|
|
|
+ },
|
|
|
// block numbers are ignored for filters created with New***Filter, these return all logs that match the given criteria when the state changes
|
|
|
- {ethereum.FilterQuery{Addresses: []common.Address{firstAddr}, FromBlock: big.NewInt(2), ToBlock: big.NewInt(3)}, append(convertLogs(allLogs[:2]), allLogs[5].Logs[3]), nil, nil},
|
|
|
+ {
|
|
|
+ ethereum.FilterQuery{Addresses: []common.Address{firstAddr}, FromBlock: big.NewInt(2), ToBlock: big.NewInt(3)},
|
|
|
+ append(flattenLogs(allLogs[:2]), allLogs[5][3]),
|
|
|
+ nil, nil,
|
|
|
+ },
|
|
|
// multiple pending logs, should match only 2 topics from the logs in block 5
|
|
|
- {ethereum.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, fourthTopic}}}, []*types.Log{allLogs[5].Logs[0], allLogs[5].Logs[2]}, nil, nil},
|
|
|
+ {
|
|
|
+ ethereum.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, fourthTopic}}},
|
|
|
+ []*types.Log{allLogs[5][0], allLogs[5][2]},
|
|
|
+ nil, nil,
|
|
|
+ },
|
|
|
}
|
|
|
)
|
|
|
|
|
|
@@ -607,10 +596,15 @@ func TestPendingLogsSubscription(t *testing.T) {
|
|
|
|
|
|
// raise events
|
|
|
time.Sleep(1 * time.Second)
|
|
|
- // allLogs are type of core.PendingLogsEvent
|
|
|
- for _, l := range allLogs {
|
|
|
- if err := mux.Post(l); err != nil {
|
|
|
- t.Fatal(err)
|
|
|
- }
|
|
|
+ for _, ev := range allLogs {
|
|
|
+ backend.pendingLogsFeed.Send(ev)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func flattenLogs(pl [][]*types.Log) []*types.Log {
|
|
|
+ var logs []*types.Log
|
|
|
+ for _, l := range pl {
|
|
|
+ logs = append(logs, l...)
|
|
|
}
|
|
|
+ return logs
|
|
|
}
|