Skip to content

Commit b1228c7

Browse files
committed
all: add global block logs cache (25459)
1 parent a93c24b commit b1228c7

File tree

19 files changed

+289
-164
lines changed

19 files changed

+289
-164
lines changed

accounts/abi/bind/backends/simulated.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ type SimulatedBackend struct {
6666
pendingState *state.StateDB // Currently pending state that will be the active on request
6767
pendingReceipts types.Receipts // Currently receipts for the pending block
6868

69-
events *filters.EventSystem // Event system for filtering log events live
69+
events *filters.EventSystem // for filtering log events live
70+
filterSystem *filters.FilterSystem // for filtering database logs
7071

7172
config *params.ChainConfig
7273
}
@@ -95,9 +96,7 @@ func SimulateWalletAddressAndSignFn() (common.Address, func(account accounts.Acc
9596

9697
// XDC simulated backend for testing purpose.
9798
func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfig *params.ChainConfig) *SimulatedBackend {
98-
// database := ethdb.NewMemDatabase()
9999
database := rawdb.NewMemoryDatabase()
100-
101100
genesis := core.Genesis{
102101
GasLimit: gasLimit, // need this big, support initial smart contract
103102
Config: chainConfig,
@@ -128,7 +127,11 @@ func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfi
128127
blockchain: blockchain,
129128
config: genesis.Config,
130129
}
131-
backend.events = filters.NewEventSystem(&filterBackend{database, blockchain, backend}, false)
130+
131+
filterBackend := &filterBackend{database, blockchain, backend}
132+
backend.filterSystem = filters.NewFilterSystem(filterBackend, filters.Config{})
133+
backend.events = filters.NewEventSystem(backend.filterSystem, false)
134+
132135
blockchain.Client = backend
133136
backend.rollback()
134137
return backend
@@ -148,7 +151,11 @@ func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend {
148151
blockchain: blockchain,
149152
config: genesis.Config,
150153
}
151-
backend.events = filters.NewEventSystem(&filterBackend{database, blockchain, backend}, false)
154+
155+
filterBackend := &filterBackend{database, blockchain, backend}
156+
backend.filterSystem = filters.NewFilterSystem(filterBackend, filters.Config{})
157+
backend.events = filters.NewEventSystem(backend.filterSystem, false)
158+
152159
backend.rollback()
153160
return backend
154161
}
@@ -422,7 +429,7 @@ func (b *SimulatedBackend) FilterLogs(ctx context.Context, query XDPoSChain.Filt
422429
var filter *filters.Filter
423430
if query.BlockHash != nil {
424431
// Block filter requested, construct a single-shot filter
425-
filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain, b}, *query.BlockHash, query.Addresses, query.Topics)
432+
filter = b.filterSystem.NewBlockFilter(*query.BlockHash, query.Addresses, query.Topics)
426433
} else {
427434
// Initialize unset filter boundaried to run from genesis to chain head
428435
from := int64(0)
@@ -434,7 +441,7 @@ func (b *SimulatedBackend) FilterLogs(ctx context.Context, query XDPoSChain.Filt
434441
to = query.ToBlock.Int64()
435442
}
436443
// Construct the range filter
437-
filter = filters.NewRangeFilter(&filterBackend{b.database, b.blockchain, b}, from, to, query.Addresses, query.Topics)
444+
filter = b.filterSystem.NewRangeFilter(from, to, query.Addresses, query.Topics)
438445
}
439446
// Run the filter and return all the logs
440447
logs, err := filter.Logs(ctx)
@@ -551,15 +558,8 @@ func (fb *filterBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts
551558
return fb.backend.pendingBlock, fb.backend.pendingReceipts
552559
}
553560

554-
func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
555-
receipts := core.GetBlockReceipts(fb.db, hash, core.GetBlockNumber(fb.db, hash))
556-
if receipts == nil {
557-
return nil, nil
558-
}
559-
logs := make([][]*types.Log, len(receipts))
560-
for i, receipt := range receipts {
561-
logs[i] = receipt.Logs
562-
}
561+
func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash, number uint64) ([][]*types.Log, error) {
562+
logs := rawdb.ReadLogs(fb.db, hash, number)
563563
return logs, nil
564564
}
565565

cmd/XDC/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ var (
9393
//utils.CacheDatabaseFlag,
9494
//utils.CacheGCFlag,
9595
//utils.TrieCacheGenFlag,
96+
utils.CacheLogSizeFlag,
9697
utils.ListenPortFlag,
9798
utils.MaxPeersFlag,
9899
utils.MaxPendingPeersFlag,

cmd/utils/flags.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ import (
4040
"github.com/XinFinOrg/XDPoSChain/crypto"
4141
"github.com/XinFinOrg/XDPoSChain/eth/downloader"
4242
"github.com/XinFinOrg/XDPoSChain/eth/ethconfig"
43+
"github.com/XinFinOrg/XDPoSChain/eth/filters"
4344
"github.com/XinFinOrg/XDPoSChain/eth/gasprice"
4445
"github.com/XinFinOrg/XDPoSChain/ethdb"
46+
"github.com/XinFinOrg/XDPoSChain/internal/ethapi"
4547
"github.com/XinFinOrg/XDPoSChain/log"
4648
"github.com/XinFinOrg/XDPoSChain/metrics"
4749
"github.com/XinFinOrg/XDPoSChain/metrics/exp"
@@ -52,6 +54,7 @@ import (
5254
"github.com/XinFinOrg/XDPoSChain/p2p/nat"
5355
"github.com/XinFinOrg/XDPoSChain/p2p/netutil"
5456
"github.com/XinFinOrg/XDPoSChain/params"
57+
"github.com/XinFinOrg/XDPoSChain/rpc"
5558
whisper "github.com/XinFinOrg/XDPoSChain/whisper/whisperv6"
5659
"gopkg.in/urfave/cli.v1"
5760
)
@@ -313,6 +316,11 @@ var (
313316
Usage: "Percentage of cache memory allowance to use for trie pruning",
314317
Value: 25,
315318
}
319+
CacheLogSizeFlag = &cli.IntFlag{
320+
Name: "cache.blocklogs",
321+
Usage: "Size (in number of blocks) of the log cache for filtering",
322+
Value: ethconfig.Defaults.FilterLogCacheSize,
323+
}
316324
// Miner settings
317325
StakingEnabledFlag = cli.BoolFlag{
318326
Name: "mine",
@@ -1208,6 +1216,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
12081216
if ctx.GlobalIsSet(GasPriceFlag.Name) {
12091217
cfg.GasPrice = GlobalBig(ctx, GasPriceFlag.Name)
12101218
}
1219+
if ctx.IsSet(CacheLogSizeFlag.Name) {
1220+
cfg.FilterLogCacheSize = ctx.Int(CacheLogSizeFlag.Name)
1221+
}
12111222
if ctx.GlobalIsSet(VMEnableDebugFlag.Name) {
12121223
// TODO(fjl): force-enable this in --dev mode
12131224
cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
@@ -1407,6 +1418,19 @@ func WalkMatch(root, pattern string) ([]string, error) {
14071418
return matches, nil
14081419
}
14091420

1421+
// RegisterFilterAPI adds the eth log filtering RPC API to the node.
1422+
func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconfig.Config) *filters.FilterSystem {
1423+
isLightClient := ethcfg.SyncMode == downloader.LightSync
1424+
filterSystem := filters.NewFilterSystem(backend, filters.Config{
1425+
LogCacheSize: ethcfg.FilterLogCacheSize,
1426+
})
1427+
stack.RegisterAPIs([]rpc.API{{
1428+
Namespace: "eth",
1429+
Service: filters.NewFilterAPI(filterSystem, isLightClient),
1430+
}})
1431+
return filterSystem
1432+
}
1433+
14101434
func SetupMetrics(ctx *cli.Context) {
14111435
if metrics.Enabled {
14121436
log.Info("Enabling metrics collection")

cmd/utils/utils.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ func RegisterShhService(stack *node.Node, cfg *whisper.Config) {
4747
}
4848
}
4949

50-
// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to
51-
// th egiven node.
50+
// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to the node.
5251
func RegisterEthStatsService(stack *node.Node, url string) {
5352
if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
5453
// Retrieve both eth and les services

core/chain_makers.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,15 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
113113
}
114114
}
115115

116+
// AddUncheckedTx forcefully adds a transaction to the block without any
117+
// validation.
118+
//
119+
// AddUncheckedTx will cause consensus failures when used during real
120+
// chain processing. This is best used in conjunction with raw block insertion.
121+
func (b *BlockGen) AddUncheckedTx(tx *types.Transaction) {
122+
b.txs = append(b.txs, tx)
123+
}
124+
116125
// Number returns the block number of the block being generated.
117126
func (b *BlockGen) Number() *big.Int {
118127
return new(big.Int).Set(b.header.Number)

eth/api_backend.go

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -234,17 +234,8 @@ func (b *EthApiBackend) GetReceipts(ctx context.Context, blockHash common.Hash)
234234
return core.GetBlockReceipts(b.eth.chainDb, blockHash, core.GetBlockNumber(b.eth.chainDb, blockHash)), nil
235235
}
236236

237-
func (b *EthApiBackend) GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) {
238-
db := b.eth.ChainDb()
239-
number := rawdb.ReadHeaderNumber(db, blockHash)
240-
if number == nil {
241-
return nil, errors.New("failed to get block number from hash")
242-
}
243-
logs := rawdb.ReadLogs(db, blockHash, *number)
244-
if logs == nil {
245-
return nil, errors.New("failed to get logs for block")
246-
}
247-
return logs, nil
237+
func (b *EthApiBackend) GetLogs(ctx context.Context, hash common.Hash, number uint64) ([][]*types.Log, error) {
238+
return rawdb.ReadLogs(b.eth.chainDb, hash, number), nil
248239
}
249240

250241
func (b *EthApiBackend) GetTd(blockHash common.Hash) *big.Int {

eth/backend.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"runtime"
2525
"sync"
2626
"sync/atomic"
27-
"time"
2827

2928
"github.com/XinFinOrg/XDPoSChain/XDCx"
3029
"github.com/XinFinOrg/XDPoSChain/XDCxlending"
@@ -401,7 +400,7 @@ func (s *Ethereum) APIs() []rpc.API {
401400
}, {
402401
Namespace: "eth",
403402
Version: "1.0",
404-
Service: filters.NewFilterAPI(s.ApiBackend, true, 5*time.Minute),
403+
Service: filters.NewFilterAPI(filters.NewFilterSystem(s.ApiBackend, filters.Config{LogCacheSize: s.config.FilterLogCacheSize}), true),
405404
Public: true,
406405
}, {
407406
Namespace: "admin",

eth/ethconfig/config.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@ var Defaults = Config{
6060
DatasetsInMem: 1,
6161
DatasetsOnDisk: 2,
6262
},
63-
NetworkId: 88,
64-
LightPeers: 100,
65-
DatabaseCache: 768,
66-
TrieCache: 256,
67-
TrieTimeout: 5 * time.Minute,
68-
GasPrice: big.NewInt(0.25 * params.Shannon),
63+
NetworkId: 88,
64+
LightPeers: 100,
65+
DatabaseCache: 768,
66+
TrieCache: 256,
67+
TrieTimeout: 5 * time.Minute,
68+
FilterLogCacheSize: 32,
69+
GasPrice: big.NewInt(0.25 * params.Shannon),
6970

7071
TxPool: core.DefaultTxPoolConfig,
7172
RPCGasCap: 25000000,
@@ -111,6 +112,9 @@ type Config struct {
111112
TrieCache int
112113
TrieTimeout time.Duration
113114

115+
// This is the number of blocks for which logs will be cached in the filter system.
116+
FilterLogCacheSize int
117+
114118
// Mining-related options
115119
Etherbase common.Address `toml:",omitempty"`
116120
MinerThreads int `toml:",omitempty"`

eth/ethconfig/gen_config.go

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

eth/filters/api.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ type filter struct {
5454
// FilterAPI offers support to create and manage filters. This will allow external clients to retrieve various
5555
// information related to the Ethereum protocol such als blocks, transactions and logs.
5656
type FilterAPI struct {
57-
backend Backend
57+
sys *FilterSystem
5858
chainDb ethdb.Database
5959
events *EventSystem
6060
filtersMu sync.Mutex
@@ -63,15 +63,15 @@ type FilterAPI struct {
6363
}
6464

6565
// NewFilterAPI returns a new FilterAPI instance.
66-
func NewFilterAPI(backend Backend, lightMode bool, timeout time.Duration) *FilterAPI {
66+
func NewFilterAPI(system *FilterSystem, lightMode bool) *FilterAPI {
6767
api := &FilterAPI{
68-
backend: backend,
69-
chainDb: backend.ChainDb(),
70-
events: NewEventSystem(backend, lightMode),
68+
sys: system,
69+
chainDb: system.backend.ChainDb(),
70+
events: NewEventSystem(system, lightMode),
7171
filters: make(map[rpc.ID]*filter),
72-
timeout: timeout,
72+
timeout: system.cfg.Timeout,
7373
}
74-
go api.timeoutLoop(timeout)
74+
go api.timeoutLoop(system.cfg.Timeout)
7575

7676
return api
7777
}
@@ -341,7 +341,7 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type
341341
var filter *Filter
342342
if crit.BlockHash != nil {
343343
// Block filter requested, construct a single-shot filter
344-
filter = NewBlockFilter(api.backend, *crit.BlockHash, crit.Addresses, crit.Topics)
344+
filter = api.sys.NewBlockFilter(*crit.BlockHash, crit.Addresses, crit.Topics)
345345
} else {
346346
// Convert the RPC block numbers into internal representations
347347
begin := rpc.LatestBlockNumber.Int64()
@@ -353,7 +353,7 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type
353353
end = crit.ToBlock.Int64()
354354
}
355355
// Construct the range filter
356-
filter = NewRangeFilter(api.backend, begin, end, crit.Addresses, crit.Topics)
356+
filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics)
357357
}
358358
// Run the filter and return all the logs
359359
logs, err := filter.Logs(ctx)
@@ -396,7 +396,7 @@ func (api *FilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*types.Lo
396396
var filter *Filter
397397
if f.crit.BlockHash != nil {
398398
// Block filter requested, construct a single-shot filter
399-
filter = NewBlockFilter(api.backend, *f.crit.BlockHash, f.crit.Addresses, f.crit.Topics)
399+
filter = api.sys.NewBlockFilter(*f.crit.BlockHash, f.crit.Addresses, f.crit.Topics)
400400
} else {
401401
// Convert the RPC block numbers into internal representations
402402
begin := rpc.LatestBlockNumber.Int64()
@@ -408,7 +408,7 @@ func (api *FilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*types.Lo
408408
end = f.crit.ToBlock.Int64()
409409
}
410410
// Construct the range filter
411-
filter = NewRangeFilter(api.backend, begin, end, f.crit.Addresses, f.crit.Topics)
411+
filter = api.sys.NewRangeFilter(begin, end, f.crit.Addresses, f.crit.Topics)
412412
}
413413
// Run the filter and return all the logs
414414
logs, err := filter.Logs(ctx)

0 commit comments

Comments
 (0)