mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 13:16:42 +00:00
eth/filters: logs subscribe donot support to criteria
Signed-off-by: jsvisa <delweng@gmail.com>
This commit is contained in:
parent
89cce937ab
commit
5cb56120b4
1 changed files with 44 additions and 48 deletions
|
|
@ -37,21 +37,8 @@ import (
|
|||
var (
|
||||
errInvalidTopic = errors.New("invalid topic(s)")
|
||||
errFilterNotFound = errors.New("filter not found")
|
||||
errInvalidBlockRange = errors.New("invalid block range params")
|
||||
errUnknownBlock = errors.New("unknown block")
|
||||
errBlockHashWithRange = errors.New("can't specify fromBlock/toBlock with blockHash")
|
||||
errPendingLogsUnsupported = errors.New("pending logs are not supported")
|
||||
errExceedMaxTopics = errors.New("exceed max topics")
|
||||
errExceedMaxAddresses = errors.New("exceed max addresses")
|
||||
)
|
||||
|
||||
const (
|
||||
// The maximum number of addresses allowed in a filter criteria
|
||||
maxAddresses = 1000
|
||||
// The maximum number of topic criteria allowed, vm.LOG4 - vm.LOG0
|
||||
maxTopics = 4
|
||||
// The maximum number of allowed topics within a topic criteria
|
||||
maxSubTopics = 1000
|
||||
errInvalidToBlock = errors.New("log subscription does not support history block range")
|
||||
errInvalidFromBlock = errors.New("invalid from block")
|
||||
)
|
||||
|
||||
// filter is a helper struct that holds meta information over the filter type
|
||||
|
|
@ -280,27 +267,38 @@ func (api *FilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc.Subsc
|
|||
}
|
||||
|
||||
// logs is the inner implmention of logs filter
|
||||
// from: nil, to: nil -> only live
|
||||
// from: blockNum | safe | finalized, to: nil -> historical from from and then toggle live
|
||||
// every other case should fail with an error
|
||||
func (api *FilterAPI) logs(ctx context.Context, notifier notifier, rpcSub *rpc.Subscription, crit FilterCriteria) error {
|
||||
isLiveFilter := true
|
||||
if crit.FromBlock != nil {
|
||||
isLiveFilter = crit.FromBlock.Sign() < 0
|
||||
var from, to rpc.BlockNumber
|
||||
if crit.FromBlock == nil {
|
||||
from = rpc.LatestBlockNumber
|
||||
} else {
|
||||
from = rpc.BlockNumber(crit.FromBlock.Int64())
|
||||
}
|
||||
if crit.ToBlock == nil {
|
||||
to = rpc.LatestBlockNumber
|
||||
} else {
|
||||
to = rpc.BlockNumber(crit.ToBlock.Int64())
|
||||
}
|
||||
|
||||
if to != rpc.LatestBlockNumber {
|
||||
return errInvalidToBlock
|
||||
}
|
||||
|
||||
switch from {
|
||||
case rpc.LatestBlockNumber:
|
||||
// do live filter only
|
||||
if isLiveFilter {
|
||||
return api.liveLogs(ctx, notifier, rpcSub, crit)
|
||||
case rpc.SafeBlockNumber, rpc.FinalizedBlockNumber:
|
||||
header, err := api.sys.backend.HeaderByNumber(ctx, from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if toBlock is limited and handled, no need to subscribe live logs anymore
|
||||
if toBlock := crit.ToBlock; toBlock != nil {
|
||||
if header := api.sys.backend.CurrentHeader(); header != nil && toBlock.Sign() > 0 && toBlock.Cmp(header.Number) <= 0 {
|
||||
return errors.New("historical only log subscription is not supported")
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
// do historical sync first
|
||||
_, err := api.histLogs(ctx, notifier, rpcSub, crit)
|
||||
_, err := api.histLogs(ctx, notifier, rpcSub, header.Number.Int64(), crit)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -308,6 +306,9 @@ func (api *FilterAPI) logs(ctx context.Context, notifier notifier, rpcSub *rpc.S
|
|||
api.liveLogs(ctx, notifier, rpcSub, crit)
|
||||
}()
|
||||
return nil
|
||||
default:
|
||||
return errInvalidFromBlock
|
||||
}
|
||||
}
|
||||
|
||||
// liveLogs only retrieves live logs
|
||||
|
|
@ -339,13 +340,12 @@ func (api *FilterAPI) liveLogs(ctx context.Context, notify notifier, rpcSub *rpc
|
|||
}
|
||||
|
||||
// histLogs only retrieves the logs older than current header
|
||||
func (api *FilterAPI) histLogs(ctx context.Context, notifier notifier, rpcSub *rpc.Subscription, crit FilterCriteria) (int64, error) {
|
||||
func (api *FilterAPI) histLogs(ctx context.Context, notifier notifier, rpcSub *rpc.Subscription, n int64, crit FilterCriteria) (int64, error) {
|
||||
// the ctx will be canceled after this callback(filter.Logs) is called
|
||||
// and we are run in a background goroutine, use a new context instead
|
||||
var (
|
||||
cctx = context.Background()
|
||||
rmLogsCh = make(chan []*types.Log)
|
||||
n = crit.FromBlock.Int64()
|
||||
)
|
||||
for {
|
||||
// get the latest block header
|
||||
|
|
@ -358,16 +358,12 @@ func (api *FilterAPI) histLogs(ctx context.Context, notifier notifier, rpcSub *r
|
|||
return head, nil
|
||||
}
|
||||
|
||||
to := big.NewInt(head)
|
||||
if toBlock := crit.ToBlock; toBlock != nil && toBlock.Sign() > 0 && toBlock.Cmp(to) < 0 {
|
||||
to = toBlock
|
||||
}
|
||||
// do historical sync from n to min(head, to)
|
||||
f := api.sys.NewRangeFilter(n, to.Int64(), crit.Addresses, crit.Topics)
|
||||
// do historical sync from n to head
|
||||
f := api.sys.NewRangeFilter(n, head, crit.Addresses, crit.Topics)
|
||||
logChan, errChan := f.rangeLogsAsync(cctx)
|
||||
|
||||
// subscribe rmLogs
|
||||
query := ethereum.FilterQuery{FromBlock: big.NewInt(n), ToBlock: to, Addresses: crit.Addresses, Topics: crit.Topics}
|
||||
query := ethereum.FilterQuery{FromBlock: big.NewInt(n), ToBlock: big.NewInt(head), Addresses: crit.Addresses, Topics: crit.Topics}
|
||||
rmLogsSub, err := api.events.SubscribeLogs(query, rmLogsCh)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
|
|
|||
Loading…
Reference in a new issue