Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
707ac67b
Commit
707ac67b
authored
Feb 06, 2016
by
Jeffrey Wilcke
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2106 from obscuren/out-of-bound-logs
eth/filters: added notifications for out of bound log events
parents
7d2d141b
68dda349
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
132 additions
and
26 deletions
+132
-26
api.go
eth/filters/api.go
+27
-19
filter.go
eth/filters/filter.go
+1
-1
filter_system.go
eth/filters/filter_system.go
+17
-6
filter_system_test.go
eth/filters/filter_system_test.go
+87
-0
No files found.
eth/filters/api.go
View file @
707ac67b
...
...
@@ -206,12 +206,12 @@ func (s *PublicFilterAPI) newLogFilter(earliest, latest int64, addresses []commo
filter
.
SetEndBlock
(
latest
)
filter
.
SetAddresses
(
addresses
)
filter
.
SetTopics
(
topics
)
filter
.
Log
sCallback
=
func
(
logs
vm
.
Logs
)
{
filter
.
Log
Callback
=
func
(
log
*
vm
.
Log
,
removed
bool
)
{
s
.
logMu
.
Lock
()
defer
s
.
logMu
.
Unlock
()
if
queue
:=
s
.
logQueue
[
id
];
queue
!=
nil
{
queue
.
add
(
logs
...
)
queue
.
add
(
vmlog
{
log
,
removed
}
)
}
}
...
...
@@ -365,14 +365,14 @@ func (s *PublicFilterAPI) NewFilter(args NewFilterArgs) (string, error) {
}
// GetLogs returns the logs matching the given argument.
func
(
s
*
PublicFilterAPI
)
GetLogs
(
args
NewFilterArgs
)
vm
.
Logs
{
func
(
s
*
PublicFilterAPI
)
GetLogs
(
args
NewFilterArgs
)
[]
vmlog
{
filter
:=
New
(
s
.
chainDb
)
filter
.
SetBeginBlock
(
args
.
FromBlock
.
Int64
())
filter
.
SetEndBlock
(
args
.
ToBlock
.
Int64
())
filter
.
SetAddresses
(
args
.
Addresses
)
filter
.
SetTopics
(
args
.
Topics
)
return
returnLogs
(
filter
.
Find
()
)
return
toRPCLogs
(
filter
.
Find
(),
false
)
}
// UninstallFilter removes the filter with the given filter id.
...
...
@@ -447,7 +447,7 @@ func (s *PublicFilterAPI) transactionFilterChanged(id int) []common.Hash {
}
// logFilterChanged returns a collection of logs for the log filter with the given id.
func
(
s
*
PublicFilterAPI
)
logFilterChanged
(
id
int
)
vm
.
Logs
{
func
(
s
*
PublicFilterAPI
)
logFilterChanged
(
id
int
)
[]
vmlog
{
s
.
logMu
.
Lock
()
defer
s
.
logMu
.
Unlock
()
...
...
@@ -458,17 +458,17 @@ func (s *PublicFilterAPI) logFilterChanged(id int) vm.Logs {
}
// GetFilterLogs returns the logs for the filter with the given id.
func
(
s
*
PublicFilterAPI
)
GetFilterLogs
(
filterId
string
)
vm
.
Logs
{
func
(
s
*
PublicFilterAPI
)
GetFilterLogs
(
filterId
string
)
[]
vmlog
{
id
,
ok
:=
s
.
filterMapping
[
filterId
]
if
!
ok
{
return
returnLogs
(
nil
)
return
toRPCLogs
(
nil
,
false
)
}
if
filter
:=
s
.
filterManager
.
Get
(
id
);
filter
!=
nil
{
return
returnLogs
(
filter
.
Find
()
)
return
toRPCLogs
(
filter
.
Find
(),
false
)
}
return
returnLogs
(
nil
)
return
toRPCLogs
(
nil
,
false
)
}
// GetFilterChanges returns the logs for the filter with the given id since last time is was called.
...
...
@@ -488,28 +488,33 @@ func (s *PublicFilterAPI) GetFilterChanges(filterId string) interface{} {
case
transactionFilterTy
:
return
returnHashes
(
s
.
transactionFilterChanged
(
id
))
case
logFilterTy
:
return
returnLogs
(
s
.
logFilterChanged
(
id
)
)
return
s
.
logFilterChanged
(
id
)
}
return
[]
interface
{}{}
}
type
vmlog
struct
{
*
vm
.
Log
Removed
bool
`json:"removed"`
}
type
logQueue
struct
{
mu
sync
.
Mutex
logs
vm
.
Logs
logs
[]
vmlog
timeout
time
.
Time
id
int
}
func
(
l
*
logQueue
)
add
(
logs
...
*
vm
.
L
og
)
{
func
(
l
*
logQueue
)
add
(
logs
...
vml
og
)
{
l
.
mu
.
Lock
()
defer
l
.
mu
.
Unlock
()
l
.
logs
=
append
(
l
.
logs
,
logs
...
)
}
func
(
l
*
logQueue
)
get
()
vm
.
Logs
{
func
(
l
*
logQueue
)
get
()
[]
vmlog
{
l
.
mu
.
Lock
()
defer
l
.
mu
.
Unlock
()
...
...
@@ -556,13 +561,16 @@ func newFilterId() (string, error) {
return
"0x"
+
hex
.
EncodeToString
(
subid
[
:
]),
nil
}
// returnLogs is a helper that will return an empty logs array case the given logs is nil, otherwise is will return the
// given logs. The RPC interfaces defines that always an array is returned.
func
returnLogs
(
logs
vm
.
Logs
)
vm
.
Logs
{
if
logs
==
nil
{
return
vm
.
Logs
{}
// toRPCLogs is a helper that will convert a vm.Logs array to an structure which
// can hold additional information about the logs such as whether it was deleted.
// Additionally when nil is given it will by default instead create an empty slice
// instead. This is required by the RPC specification.
func
toRPCLogs
(
logs
vm
.
Logs
,
removed
bool
)
[]
vmlog
{
convertedLogs
:=
make
([]
vmlog
,
len
(
logs
))
for
i
,
log
:=
range
logs
{
convertedLogs
[
i
]
=
vmlog
{
Log
:
log
,
Removed
:
removed
}
}
return
l
ogs
return
convertedL
ogs
}
// returnHashes is a helper that will return an empty hash array case the given hash array is nil, otherwise is will
...
...
eth/filters/filter.go
View file @
707ac67b
...
...
@@ -39,7 +39,7 @@ type Filter struct {
BlockCallback
func
(
*
types
.
Block
,
vm
.
Logs
)
TransactionCallback
func
(
*
types
.
Transaction
)
Log
sCallback
func
(
vm
.
Logs
)
Log
Callback
func
(
*
vm
.
Log
,
bool
)
}
// Create a new filter which uses a bloom filter on blocks to figure out whether a particular block
...
...
eth/filters/filter_system.go
View file @
707ac67b
...
...
@@ -46,6 +46,7 @@ func NewFilterSystem(mux *event.TypeMux) *FilterSystem {
}
fs
.
sub
=
mux
.
Subscribe
(
//core.PendingBlockEvent{},
core
.
RemovedLogEvent
{},
core
.
ChainEvent
{},
core
.
TxPreEvent
{},
vm
.
Logs
(
nil
),
...
...
@@ -96,7 +97,7 @@ func (fs *FilterSystem) filterLoop() {
case
core
.
ChainEvent
:
fs
.
filterMu
.
RLock
()
for
id
,
filter
:=
range
fs
.
filters
{
if
filter
.
BlockCallback
!=
nil
&&
fs
.
created
[
id
]
.
Before
(
event
.
Time
)
{
if
filter
.
BlockCallback
!=
nil
&&
!
fs
.
created
[
id
]
.
After
(
event
.
Time
)
{
filter
.
BlockCallback
(
ev
.
Block
,
ev
.
Logs
)
}
}
...
...
@@ -105,7 +106,7 @@ func (fs *FilterSystem) filterLoop() {
case
core
.
TxPreEvent
:
fs
.
filterMu
.
RLock
()
for
id
,
filter
:=
range
fs
.
filters
{
if
filter
.
TransactionCallback
!=
nil
&&
fs
.
created
[
id
]
.
Before
(
event
.
Time
)
{
if
filter
.
TransactionCallback
!=
nil
&&
!
fs
.
created
[
id
]
.
After
(
event
.
Time
)
{
filter
.
TransactionCallback
(
ev
.
Tx
)
}
}
...
...
@@ -114,10 +115,20 @@ func (fs *FilterSystem) filterLoop() {
case
vm
.
Logs
:
fs
.
filterMu
.
RLock
()
for
id
,
filter
:=
range
fs
.
filters
{
if
filter
.
LogsCallback
!=
nil
&&
fs
.
created
[
id
]
.
Before
(
event
.
Time
)
{
msgs
:=
filter
.
FilterLogs
(
ev
)
if
len
(
msgs
)
>
0
{
filter
.
LogsCallback
(
msgs
)
if
filter
.
LogCallback
!=
nil
&&
!
fs
.
created
[
id
]
.
After
(
event
.
Time
)
{
for
_
,
log
:=
range
filter
.
FilterLogs
(
ev
)
{
filter
.
LogCallback
(
log
,
false
)
}
}
}
fs
.
filterMu
.
RUnlock
()
case
core
.
RemovedLogEvent
:
fs
.
filterMu
.
RLock
()
for
id
,
filter
:=
range
fs
.
filters
{
if
filter
.
LogCallback
!=
nil
&&
!
fs
.
created
[
id
]
.
After
(
event
.
Time
)
{
for
_
,
removedLog
:=
range
ev
.
Logs
{
filter
.
LogCallback
(
removedLog
,
true
)
}
}
}
...
...
eth/filters/filter_system_test.go
0 → 100644
View file @
707ac67b
package
filters
import
(
"testing"
"time"
"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/event"
)
func
TestCallbacks
(
t
*
testing
.
T
)
{
var
(
mux
event
.
TypeMux
fs
=
NewFilterSystem
(
&
mux
)
blockDone
=
make
(
chan
struct
{})
txDone
=
make
(
chan
struct
{})
logDone
=
make
(
chan
struct
{})
removedLogDone
=
make
(
chan
struct
{})
)
blockFilter
:=
&
Filter
{
BlockCallback
:
func
(
*
types
.
Block
,
vm
.
Logs
)
{
close
(
blockDone
)
},
}
txFilter
:=
&
Filter
{
TransactionCallback
:
func
(
*
types
.
Transaction
)
{
close
(
txDone
)
},
}
logFilter
:=
&
Filter
{
LogCallback
:
func
(
l
*
vm
.
Log
,
oob
bool
)
{
if
!
oob
{
close
(
logDone
)
}
},
}
removedLogFilter
:=
&
Filter
{
LogCallback
:
func
(
l
*
vm
.
Log
,
oob
bool
)
{
if
oob
{
close
(
removedLogDone
)
}
},
}
fs
.
Add
(
blockFilter
)
fs
.
Add
(
txFilter
)
fs
.
Add
(
logFilter
)
fs
.
Add
(
removedLogFilter
)
mux
.
Post
(
core
.
ChainEvent
{})
mux
.
Post
(
core
.
TxPreEvent
{})
mux
.
Post
(
core
.
RemovedLogEvent
{
vm
.
Logs
{
&
vm
.
Log
{}}})
mux
.
Post
(
vm
.
Logs
{
&
vm
.
Log
{}})
const
dura
=
5
*
time
.
Second
failTimer
:=
time
.
NewTimer
(
dura
)
select
{
case
<-
blockDone
:
case
<-
failTimer
.
C
:
t
.
Error
(
"block filter failed to trigger (timeout)"
)
}
failTimer
.
Reset
(
dura
)
select
{
case
<-
txDone
:
case
<-
failTimer
.
C
:
t
.
Error
(
"transaction filter failed to trigger (timeout)"
)
}
failTimer
.
Reset
(
dura
)
select
{
case
<-
logDone
:
case
<-
failTimer
.
C
:
t
.
Error
(
"log filter failed to trigger (timeout)"
)
}
failTimer
.
Reset
(
dura
)
select
{
case
<-
removedLogDone
:
case
<-
failTimer
.
C
:
t
.
Error
(
"removed log filter failed to trigger (timeout)"
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment