|
|
|
@ -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 |
|
|
|
|
} |
|
|
|
|