aboutsummaryrefslogtreecommitdiffstats
path: root/eth
diff options
context:
space:
mode:
Diffstat (limited to 'eth')
-rw-r--r--eth/filters/api.go19
-rw-r--r--eth/filters/filter.go27
-rw-r--r--eth/filters/filter_system.go76
-rw-r--r--eth/filters/filter_system_test.go50
4 files changed, 63 insertions, 109 deletions
diff --git a/eth/filters/api.go b/eth/filters/api.go
index d5dd57743..bbb34d3de 100644
--- a/eth/filters/api.go
+++ b/eth/filters/api.go
@@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
@@ -45,7 +46,7 @@ type filter struct {
deadline *time.Timer // filter is inactiv when deadline triggers
hashes []common.Hash
crit FilterCriteria
- logs []Log
+ logs []*vm.Log
s *Subscription // associated subscription in event system
}
@@ -241,7 +242,7 @@ func (api *PublicFilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc
var (
rpcSub = notifier.CreateSubscription()
- matchedLogs = make(chan []Log)
+ matchedLogs = make(chan []*vm.Log)
)
logsSub, err := api.events.SubscribeLogs(crit, matchedLogs)
@@ -292,14 +293,14 @@ type FilterCriteria struct {
//
// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter
func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) {
- logs := make(chan []Log)
+ logs := make(chan []*vm.Log)
logsSub, err := api.events.SubscribeLogs(crit, logs)
if err != nil {
return rpc.ID(""), err
}
api.filtersMu.Lock()
- api.filters[logsSub.ID] = &filter{typ: LogsSubscription, crit: crit, deadline: time.NewTimer(deadline), logs: make([]Log, 0), s: logsSub}
+ api.filters[logsSub.ID] = &filter{typ: LogsSubscription, crit: crit, deadline: time.NewTimer(deadline), logs: make([]*vm.Log, 0), s: logsSub}
api.filtersMu.Unlock()
go func() {
@@ -326,7 +327,7 @@ func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) {
// GetLogs returns logs matching the given argument that are stored within the state.
//
// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs
-func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]Log, error) {
+func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*vm.Log, error) {
if crit.FromBlock == nil {
crit.FromBlock = big.NewInt(rpc.LatestBlockNumber.Int64())
}
@@ -365,7 +366,7 @@ func (api *PublicFilterAPI) UninstallFilter(id rpc.ID) bool {
// If the filter could not be found an empty array of logs is returned.
//
// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterlogs
-func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]Log, error) {
+func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*vm.Log, error) {
api.filtersMu.Lock()
f, found := api.filters[id]
api.filtersMu.Unlock()
@@ -388,7 +389,7 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]Log
filter.SetAddresses(f.crit.Addresses)
filter.SetTopics(f.crit.Topics)
- logs, err:= filter.Find(ctx)
+ logs, err := filter.Find(ctx)
if err != nil {
return nil, err
}
@@ -440,9 +441,9 @@ func returnHashes(hashes []common.Hash) []common.Hash {
// returnLogs is a helper that will return an empty log array in case the given logs array is nil,
// otherwise the given logs array is returned.
-func returnLogs(logs []Log) []Log {
+func returnLogs(logs []*vm.Log) []*vm.Log {
if logs == nil {
- return []Log{}
+ return []*vm.Log{}
}
return logs
}
diff --git a/eth/filters/filter.go b/eth/filters/filter.go
index ce7383fb3..a695d7eb7 100644
--- a/eth/filters/filter.go
+++ b/eth/filters/filter.go
@@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
@@ -38,7 +39,7 @@ type Backend interface {
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
}
-// Filter can be used to retrieve and filter logs
+// Filter can be used to retrieve and filter logs.
type Filter struct {
backend Backend
useMipMap bool
@@ -85,7 +86,7 @@ func (f *Filter) SetTopics(topics [][]common.Hash) {
}
// Run filters logs with the current parameters set
-func (f *Filter) Find(ctx context.Context) ([]Log, error) {
+func (f *Filter) Find(ctx context.Context) ([]*vm.Log, error) {
head, _ := f.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber)
if head == nil {
return nil, nil
@@ -110,7 +111,7 @@ func (f *Filter) Find(ctx context.Context) ([]Log, error) {
return f.mipFind(beginBlockNo, endBlockNo, 0), nil
}
-func (f *Filter) mipFind(start, end uint64, depth int) (logs []Log) {
+func (f *Filter) mipFind(start, end uint64, depth int) (logs []*vm.Log) {
level := core.MIPMapLevels[depth]
// normalise numerator so we can work in level specific batches and
// work with the proper range checks
@@ -141,7 +142,7 @@ func (f *Filter) mipFind(start, end uint64, depth int) (logs []Log) {
return logs
}
-func (f *Filter) getLogs(ctx context.Context, start, end uint64) (logs []Log, err error) {
+func (f *Filter) getLogs(ctx context.Context, start, end uint64) (logs []*vm.Log, err error) {
for i := start; i <= end; i++ {
header, err := f.backend.HeaderByNumber(ctx, rpc.BlockNumber(i))
if header == nil || err != nil {
@@ -156,13 +157,9 @@ func (f *Filter) getLogs(ctx context.Context, start, end uint64) (logs []Log, er
if err != nil {
return nil, err
}
- var unfiltered []Log
+ var unfiltered []*vm.Log
for _, receipt := range receipts {
- rl := make([]Log, len(receipt.Logs))
- for i, l := range receipt.Logs {
- rl[i] = Log{l, false}
- }
- unfiltered = append(unfiltered, rl...)
+ unfiltered = append(unfiltered, ([]*vm.Log)(receipt.Logs)...)
}
logs = append(logs, filterLogs(unfiltered, nil, nil, f.addresses, f.topics)...)
}
@@ -181,15 +178,15 @@ func includes(addresses []common.Address, a common.Address) bool {
return false
}
-func filterLogs(logs []Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []Log {
- var ret []Log
- // Filter the logs for interesting stuff
+// filterLogs creates a slice of logs matching the given criteria.
+func filterLogs(logs []*vm.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*vm.Log {
+ var ret []*vm.Log
Logs:
for _, log := range logs {
- if fromBlock != nil && fromBlock.Int64() >= 0 && uint64(fromBlock.Int64()) > log.BlockNumber {
+ if fromBlock != nil && fromBlock.Int64() >= 0 && fromBlock.Uint64() > log.BlockNumber {
continue
}
- if toBlock != nil && toBlock.Int64() >= 0 && uint64(toBlock.Int64()) < log.BlockNumber {
+ if toBlock != nil && toBlock.Int64() >= 0 && toBlock.Uint64() < log.BlockNumber {
continue
}
diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go
index b59718aea..1b360cfdb 100644
--- a/eth/filters/filter_system.go
+++ b/eth/filters/filter_system.go
@@ -19,7 +19,6 @@
package filters
import (
- "encoding/json"
"errors"
"fmt"
"sync"
@@ -60,42 +59,12 @@ var (
ErrInvalidSubscriptionID = errors.New("invalid id")
)
-// Log is a helper that can hold additional information about vm.Log
-// necessary for the RPC interface.
-type Log struct {
- *vm.Log
- Removed bool `json:"removed"`
-}
-
-// MarshalJSON returns *l as the JSON encoding of l.
-func (l *Log) MarshalJSON() ([]byte, error) {
- fields := map[string]interface{}{
- "address": l.Address,
- "data": fmt.Sprintf("0x%x", l.Data),
- "blockNumber": nil,
- "logIndex": fmt.Sprintf("%#x", l.Index),
- "blockHash": nil,
- "transactionHash": l.TxHash,
- "transactionIndex": fmt.Sprintf("%#x", l.TxIndex),
- "topics": l.Topics,
- "removed": l.Removed,
- }
-
- // mined logs
- if l.BlockHash != (common.Hash{}) {
- fields["blockNumber"] = fmt.Sprintf("%#x", l.BlockNumber)
- fields["blockHash"] = l.BlockHash
- }
-
- return json.Marshal(fields)
-}
-
type subscription struct {
id rpc.ID
typ Type
created time.Time
logsCrit FilterCriteria
- logs chan []Log
+ logs chan []*vm.Log
hashes chan common.Hash
headers chan *types.Header
installed chan struct{} // closed when the filter is installed
@@ -182,7 +151,7 @@ func (es *EventSystem) subscribe(sub *subscription) *Subscription {
// SubscribeLogs creates a subscription that will write all logs matching the
// given criteria to the given logs channel. Default value for the from and to
// block is "latest". If the fromBlock > toBlock an error is returned.
-func (es *EventSystem) SubscribeLogs(crit FilterCriteria, logs chan []Log) (*Subscription, error) {
+func (es *EventSystem) SubscribeLogs(crit FilterCriteria, logs chan []*vm.Log) (*Subscription, error) {
var from, to rpc.BlockNumber
if crit.FromBlock == nil {
from = rpc.LatestBlockNumber
@@ -220,7 +189,7 @@ func (es *EventSystem) SubscribeLogs(crit FilterCriteria, logs chan []Log) (*Sub
// subscribeMinedPendingLogs creates a subscription that returned mined and
// pending logs that match the given criteria.
-func (es *EventSystem) subscribeMinedPendingLogs(crit FilterCriteria, logs chan []Log) *Subscription {
+func (es *EventSystem) subscribeMinedPendingLogs(crit FilterCriteria, logs chan []*vm.Log) *Subscription {
sub := &subscription{
id: rpc.NewID(),
typ: MinedAndPendingLogsSubscription,
@@ -238,7 +207,7 @@ func (es *EventSystem) subscribeMinedPendingLogs(crit FilterCriteria, logs chan
// subscribeLogs creates a subscription that will write all logs matching the
// given criteria to the given logs channel.
-func (es *EventSystem) subscribeLogs(crit FilterCriteria, logs chan []Log) *Subscription {
+func (es *EventSystem) subscribeLogs(crit FilterCriteria, logs chan []*vm.Log) *Subscription {
sub := &subscription{
id: rpc.NewID(),
typ: LogsSubscription,
@@ -256,7 +225,7 @@ func (es *EventSystem) subscribeLogs(crit FilterCriteria, logs chan []Log) *Subs
// subscribePendingLogs creates a subscription that writes transaction hashes for
// transactions that enter the transaction pool.
-func (es *EventSystem) subscribePendingLogs(crit FilterCriteria, logs chan []Log) *Subscription {
+func (es *EventSystem) subscribePendingLogs(crit FilterCriteria, logs chan []*vm.Log) *Subscription {
sub := &subscription{
id: rpc.NewID(),
typ: PendingLogsSubscription,
@@ -279,7 +248,7 @@ func (es *EventSystem) SubscribeNewHeads(headers chan *types.Header) *Subscripti
id: rpc.NewID(),
typ: BlocksSubscription,
created: time.Now(),
- logs: make(chan []Log),
+ logs: make(chan []*vm.Log),
hashes: make(chan common.Hash),
headers: headers,
installed: make(chan struct{}),
@@ -296,7 +265,7 @@ func (es *EventSystem) SubscribePendingTxEvents(hashes chan common.Hash) *Subscr
id: rpc.NewID(),
typ: PendingTransactionsSubscription,
created: time.Now(),
- logs: make(chan []Log),
+ logs: make(chan []*vm.Log),
hashes: hashes,
headers: make(chan *types.Header),
installed: make(chan struct{}),
@@ -319,7 +288,7 @@ func (es *EventSystem) broadcast(filters filterIndex, ev *event.Event) {
if len(e) > 0 {
for _, f := range filters[LogsSubscription] {
if ev.Time.After(f.created) {
- if matchedLogs := filterLogs(convertLogs(e, false), f.logsCrit.FromBlock, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics); len(matchedLogs) > 0 {
+ if matchedLogs := filterLogs(e, f.logsCrit.FromBlock, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics); len(matchedLogs) > 0 {
f.logs <- matchedLogs
}
}
@@ -328,7 +297,7 @@ func (es *EventSystem) broadcast(filters filterIndex, ev *event.Event) {
case core.RemovedLogsEvent:
for _, f := range filters[LogsSubscription] {
if ev.Time.After(f.created) {
- if matchedLogs := filterLogs(convertLogs(e.Logs, true), f.logsCrit.FromBlock, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics); len(matchedLogs) > 0 {
+ if matchedLogs := filterLogs(e.Logs, f.logsCrit.FromBlock, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics); len(matchedLogs) > 0 {
f.logs <- matchedLogs
}
}
@@ -336,7 +305,7 @@ func (es *EventSystem) broadcast(filters filterIndex, ev *event.Event) {
case core.PendingLogsEvent:
for _, f := range filters[PendingLogsSubscription] {
if ev.Time.After(f.created) {
- if matchedLogs := filterLogs(convertLogs(e.Logs, false), nil, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics); len(matchedLogs) > 0 {
+ if matchedLogs := filterLogs(e.Logs, nil, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics); len(matchedLogs) > 0 {
f.logs <- matchedLogs
}
}
@@ -401,25 +370,22 @@ func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func
}
// filter logs of a single header in light client mode
-func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common.Address, topics [][]common.Hash, remove bool) []Log {
- //fmt.Println("lightFilterLogs", header.Number.Uint64(), remove)
+func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common.Address, topics [][]common.Hash, remove bool) []*vm.Log {
if bloomFilter(header.Bloom, addresses, topics) {
- //fmt.Println("bloom match")
// Get the logs of the block
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
receipts, err := es.backend.GetReceipts(ctx, header.Hash())
if err != nil {
return nil
}
- var unfiltered []Log
+ var unfiltered []*vm.Log
for _, receipt := range receipts {
- rl := make([]Log, len(receipt.Logs))
- for i, l := range receipt.Logs {
- rl[i] = Log{l, remove}
+ for _, log := range receipt.Logs {
+ logcopy := *log
+ logcopy.Removed = remove
+ unfiltered = append(unfiltered, &logcopy)
}
- unfiltered = append(unfiltered, rl...)
}
-
logs := filterLogs(unfiltered, nil, nil, addresses, topics)
return logs
}
@@ -465,13 +431,3 @@ func (es *EventSystem) eventLoop() {
}
}
}
-
-// convertLogs is a helper utility that converts vm.Logs to []filter.Log.
-func convertLogs(in vm.Logs, removed bool) []Log {
-
- logs := make([]Log, len(in))
- for i, l := range in {
- logs[i] = Log{l, removed}
- }
- return logs
-}
diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go
index e8591a2e4..3ce0cf663 100644
--- a/eth/filters/filter_system_test.go
+++ b/eth/filters/filter_system_test.go
@@ -74,10 +74,10 @@ func TestBlockSubscription(t *testing.T) {
t.Parallel()
var (
- mux = new(event.TypeMux)
- db, _ = ethdb.NewMemDatabase()
+ mux = new(event.TypeMux)
+ db, _ = ethdb.NewMemDatabase()
backend = &testBackend{mux, db}
- api = NewPublicFilterAPI(backend, false)
+ api = NewPublicFilterAPI(backend, false)
genesis = core.WriteGenesisBlockForTesting(db)
chain, _ = core.GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *core.BlockGen) {})
@@ -128,10 +128,10 @@ func TestPendingTxFilter(t *testing.T) {
t.Parallel()
var (
- mux = new(event.TypeMux)
- db, _ = ethdb.NewMemDatabase()
+ mux = new(event.TypeMux)
+ db, _ = ethdb.NewMemDatabase()
backend = &testBackend{mux, db}
- api = NewPublicFilterAPI(backend, false)
+ api = NewPublicFilterAPI(backend, false)
transactions = []*types.Transaction{
types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), new(big.Int), new(big.Int), nil),
@@ -178,10 +178,10 @@ func TestPendingTxFilter(t *testing.T) {
// If not it must return an error.
func TestLogFilterCreation(t *testing.T) {
var (
- mux = new(event.TypeMux)
- db, _ = ethdb.NewMemDatabase()
+ mux = new(event.TypeMux)
+ db, _ = ethdb.NewMemDatabase()
backend = &testBackend{mux, db}
- api = NewPublicFilterAPI(backend, false)
+ api = NewPublicFilterAPI(backend, false)
testCases = []struct {
crit FilterCriteria
@@ -223,10 +223,10 @@ func TestInvalidLogFilterCreation(t *testing.T) {
t.Parallel()
var (
- mux = new(event.TypeMux)
- db, _ = ethdb.NewMemDatabase()
+ mux = new(event.TypeMux)
+ db, _ = ethdb.NewMemDatabase()
backend = &testBackend{mux, db}
- api = NewPublicFilterAPI(backend, false)
+ api = NewPublicFilterAPI(backend, false)
)
// different situations where log filter creation should fail.
@@ -249,10 +249,10 @@ func TestLogFilter(t *testing.T) {
t.Parallel()
var (
- mux = new(event.TypeMux)
- db, _ = ethdb.NewMemDatabase()
+ mux = new(event.TypeMux)
+ db, _ = ethdb.NewMemDatabase()
backend = &testBackend{mux, db}
- api = NewPublicFilterAPI(backend, false)
+ api = NewPublicFilterAPI(backend, false)
firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
@@ -321,14 +321,14 @@ func TestLogFilter(t *testing.T) {
}
for i, tt := range testCases {
- var fetched []Log
+ var fetched []*vm.Log
for { // fetch all expected logs
results, err := api.GetFilterChanges(tt.id)
if err != nil {
t.Fatalf("Unable to fetch logs: %v", err)
}
- fetched = append(fetched, results.([]Log)...)
+ fetched = append(fetched, results.([]*vm.Log)...)
if len(fetched) >= len(tt.expected) {
break
}
@@ -345,7 +345,7 @@ func TestLogFilter(t *testing.T) {
if fetched[l].Removed {
t.Errorf("expected log not to be removed for log %d in case %d", l, i)
}
- if !reflect.DeepEqual(fetched[l].Log, tt.expected[l]) {
+ if !reflect.DeepEqual(fetched[l], tt.expected[l]) {
t.Errorf("invalid log on index %d for case %d", l, i)
}
}
@@ -357,10 +357,10 @@ func TestPendingLogsSubscription(t *testing.T) {
t.Parallel()
var (
- mux = new(event.TypeMux)
- db, _ = ethdb.NewMemDatabase()
+ mux = new(event.TypeMux)
+ db, _ = ethdb.NewMemDatabase()
backend = &testBackend{mux, db}
- api = NewPublicFilterAPI(backend, false)
+ api = NewPublicFilterAPI(backend, false)
firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
@@ -397,7 +397,7 @@ func TestPendingLogsSubscription(t *testing.T) {
testCases = []struct {
crit FilterCriteria
expected vm.Logs
- c chan []Log
+ c chan []*vm.Log
sub *Subscription
}{
// match all
@@ -423,7 +423,7 @@ func TestPendingLogsSubscription(t *testing.T) {
// on slow machines this could otherwise lead to missing events when the subscription is created after
// (some) events are posted.
for i := range testCases {
- testCases[i].c = make(chan []Log)
+ testCases[i].c = make(chan []*vm.Log)
testCases[i].sub, _ = api.events.SubscribeLogs(testCases[i].crit, testCases[i].c)
}
@@ -431,7 +431,7 @@ func TestPendingLogsSubscription(t *testing.T) {
i := n
tt := test
go func() {
- var fetched []Log
+ var fetched []*vm.Log
fetchLoop:
for {
logs := <-tt.c
@@ -449,7 +449,7 @@ func TestPendingLogsSubscription(t *testing.T) {
if fetched[l].Removed {
t.Errorf("expected log not to be removed for log %d in case %d", l, i)
}
- if !reflect.DeepEqual(fetched[l].Log, tt.expected[l]) {
+ if !reflect.DeepEqual(fetched[l], tt.expected[l]) {
t.Errorf("invalid log on index %d for case %d", l, i)
}
}