chg : moved TestBorFilters to tests/bor

This commit is contained in:
Shivam Sharma 2022-07-18 13:43:36 +05:30
parent 9aad8bf928
commit 43b18b7038
10 changed files with 614 additions and 169 deletions

View file

@ -34,6 +34,7 @@ protoc:
generate-mocks: generate-mocks:
go generate mockgen -destination=./tests/bor/mocks/IHeimdallClient.go -package=mocks ./consensus/bor IHeimdallClient go generate mockgen -destination=./tests/bor/mocks/IHeimdallClient.go -package=mocks ./consensus/bor IHeimdallClient
go generate mockgen -destination=./eth/filters/IBackend.go -package=filters ./eth/filters Backend
geth: geth:
$(GORUN) build/ci.go install ./cmd/geth $(GORUN) build/ci.go install ./cmd/geth

257
eth/filters/IBackend.go Normal file
View file

@ -0,0 +1,257 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ethereum/go-ethereum/eth/filters (interfaces: Backend)
// Package filters is a generated GoMock package.
package filters
import (
context "context"
reflect "reflect"
common "github.com/ethereum/go-ethereum/common"
core "github.com/ethereum/go-ethereum/core"
bloombits "github.com/ethereum/go-ethereum/core/bloombits"
types "github.com/ethereum/go-ethereum/core/types"
ethdb "github.com/ethereum/go-ethereum/ethdb"
event "github.com/ethereum/go-ethereum/event"
rpc "github.com/ethereum/go-ethereum/rpc"
gomock "github.com/golang/mock/gomock"
)
// MockBackend is a mock of Backend interface.
type MockBackend struct {
ctrl *gomock.Controller
recorder *MockBackendMockRecorder
}
// MockBackendMockRecorder is the mock recorder for MockBackend.
type MockBackendMockRecorder struct {
mock *MockBackend
}
// NewMockBackend creates a new mock instance.
func NewMockBackend(ctrl *gomock.Controller) *MockBackend {
mock := &MockBackend{ctrl: ctrl}
mock.recorder = &MockBackendMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockBackend) EXPECT() *MockBackendMockRecorder {
return m.recorder
}
// BloomStatus mocks base method.
func (m *MockBackend) BloomStatus() (uint64, uint64) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BloomStatus")
ret0, _ := ret[0].(uint64)
ret1, _ := ret[1].(uint64)
return ret0, ret1
}
// BloomStatus indicates an expected call of BloomStatus.
func (mr *MockBackendMockRecorder) BloomStatus() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BloomStatus", reflect.TypeOf((*MockBackend)(nil).BloomStatus))
}
// ChainDb mocks base method.
func (m *MockBackend) ChainDb() ethdb.Database {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ChainDb")
ret0, _ := ret[0].(ethdb.Database)
return ret0
}
// ChainDb indicates an expected call of ChainDb.
func (mr *MockBackendMockRecorder) ChainDb() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainDb", reflect.TypeOf((*MockBackend)(nil).ChainDb))
}
// GetBorBlockLogs mocks base method.
func (m *MockBackend) GetBorBlockLogs(arg0 context.Context, arg1 common.Hash) ([]*types.Log, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBorBlockLogs", arg0, arg1)
ret0, _ := ret[0].([]*types.Log)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetBorBlockLogs indicates an expected call of GetBorBlockLogs.
func (mr *MockBackendMockRecorder) GetBorBlockLogs(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBorBlockLogs", reflect.TypeOf((*MockBackend)(nil).GetBorBlockLogs), arg0, arg1)
}
// GetBorBlockReceipt mocks base method.
func (m *MockBackend) GetBorBlockReceipt(arg0 context.Context, arg1 common.Hash) (*types.Receipt, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBorBlockReceipt", arg0, arg1)
ret0, _ := ret[0].(*types.Receipt)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetBorBlockReceipt indicates an expected call of GetBorBlockReceipt.
func (mr *MockBackendMockRecorder) GetBorBlockReceipt(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBorBlockReceipt", reflect.TypeOf((*MockBackend)(nil).GetBorBlockReceipt), arg0, arg1)
}
// GetLogs mocks base method.
func (m *MockBackend) GetLogs(arg0 context.Context, arg1 common.Hash) ([][]*types.Log, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetLogs", arg0, arg1)
ret0, _ := ret[0].([][]*types.Log)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetLogs indicates an expected call of GetLogs.
func (mr *MockBackendMockRecorder) GetLogs(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogs", reflect.TypeOf((*MockBackend)(nil).GetLogs), arg0, arg1)
}
// GetReceipts mocks base method.
func (m *MockBackend) GetReceipts(arg0 context.Context, arg1 common.Hash) (types.Receipts, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetReceipts", arg0, arg1)
ret0, _ := ret[0].(types.Receipts)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetReceipts indicates an expected call of GetReceipts.
func (mr *MockBackendMockRecorder) GetReceipts(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetReceipts", reflect.TypeOf((*MockBackend)(nil).GetReceipts), arg0, arg1)
}
// HeaderByHash mocks base method.
func (m *MockBackend) HeaderByHash(arg0 context.Context, arg1 common.Hash) (*types.Header, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HeaderByHash", arg0, arg1)
ret0, _ := ret[0].(*types.Header)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// HeaderByHash indicates an expected call of HeaderByHash.
func (mr *MockBackendMockRecorder) HeaderByHash(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByHash", reflect.TypeOf((*MockBackend)(nil).HeaderByHash), arg0, arg1)
}
// HeaderByNumber mocks base method.
func (m *MockBackend) HeaderByNumber(arg0 context.Context, arg1 rpc.BlockNumber) (*types.Header, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HeaderByNumber", arg0, arg1)
ret0, _ := ret[0].(*types.Header)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// HeaderByNumber indicates an expected call of HeaderByNumber.
func (mr *MockBackendMockRecorder) HeaderByNumber(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByNumber", reflect.TypeOf((*MockBackend)(nil).HeaderByNumber), arg0, arg1)
}
// ServiceFilter mocks base method.
func (m *MockBackend) ServiceFilter(arg0 context.Context, arg1 *bloombits.MatcherSession) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "ServiceFilter", arg0, arg1)
}
// ServiceFilter indicates an expected call of ServiceFilter.
func (mr *MockBackendMockRecorder) ServiceFilter(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServiceFilter", reflect.TypeOf((*MockBackend)(nil).ServiceFilter), arg0, arg1)
}
// SubscribeChainEvent mocks base method.
func (m *MockBackend) SubscribeChainEvent(arg0 chan<- core.ChainEvent) event.Subscription {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SubscribeChainEvent", arg0)
ret0, _ := ret[0].(event.Subscription)
return ret0
}
// SubscribeChainEvent indicates an expected call of SubscribeChainEvent.
func (mr *MockBackendMockRecorder) SubscribeChainEvent(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeChainEvent", reflect.TypeOf((*MockBackend)(nil).SubscribeChainEvent), arg0)
}
// SubscribeLogsEvent mocks base method.
func (m *MockBackend) SubscribeLogsEvent(arg0 chan<- []*types.Log) event.Subscription {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SubscribeLogsEvent", arg0)
ret0, _ := ret[0].(event.Subscription)
return ret0
}
// SubscribeLogsEvent indicates an expected call of SubscribeLogsEvent.
func (mr *MockBackendMockRecorder) SubscribeLogsEvent(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeLogsEvent", reflect.TypeOf((*MockBackend)(nil).SubscribeLogsEvent), arg0)
}
// SubscribeNewTxsEvent mocks base method.
func (m *MockBackend) SubscribeNewTxsEvent(arg0 chan<- core.NewTxsEvent) event.Subscription {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SubscribeNewTxsEvent", arg0)
ret0, _ := ret[0].(event.Subscription)
return ret0
}
// SubscribeNewTxsEvent indicates an expected call of SubscribeNewTxsEvent.
func (mr *MockBackendMockRecorder) SubscribeNewTxsEvent(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeNewTxsEvent", reflect.TypeOf((*MockBackend)(nil).SubscribeNewTxsEvent), arg0)
}
// SubscribePendingLogsEvent mocks base method.
func (m *MockBackend) SubscribePendingLogsEvent(arg0 chan<- []*types.Log) event.Subscription {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SubscribePendingLogsEvent", arg0)
ret0, _ := ret[0].(event.Subscription)
return ret0
}
// SubscribePendingLogsEvent indicates an expected call of SubscribePendingLogsEvent.
func (mr *MockBackendMockRecorder) SubscribePendingLogsEvent(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribePendingLogsEvent", reflect.TypeOf((*MockBackend)(nil).SubscribePendingLogsEvent), arg0)
}
// SubscribeRemovedLogsEvent mocks base method.
func (m *MockBackend) SubscribeRemovedLogsEvent(arg0 chan<- core.RemovedLogsEvent) event.Subscription {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SubscribeRemovedLogsEvent", arg0)
ret0, _ := ret[0].(event.Subscription)
return ret0
}
// SubscribeRemovedLogsEvent indicates an expected call of SubscribeRemovedLogsEvent.
func (mr *MockBackendMockRecorder) SubscribeRemovedLogsEvent(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeRemovedLogsEvent", reflect.TypeOf((*MockBackend)(nil).SubscribeRemovedLogsEvent), arg0)
}
// SubscribeStateSyncEvent mocks base method.
func (m *MockBackend) SubscribeStateSyncEvent(arg0 chan<- core.StateSyncEvent) event.Subscription {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SubscribeStateSyncEvent", arg0)
ret0, _ := ret[0].(event.Subscription)
return ret0
}
// SubscribeStateSyncEvent indicates an expected call of SubscribeStateSyncEvent.
func (mr *MockBackendMockRecorder) SubscribeStateSyncEvent(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeStateSyncEvent", reflect.TypeOf((*MockBackend)(nil).SubscribeStateSyncEvent), arg0)
}

View file

@ -122,13 +122,13 @@ func benchmarkBloomBits(b *testing.B, sectionSize uint64) {
b.Log("Running filter benchmarks...") b.Log("Running filter benchmarks...")
start = time.Now() start = time.Now()
var backend *testBackend var backend *TestBackend
for i := 0; i < benchFilterCnt; i++ { for i := 0; i < benchFilterCnt; i++ {
if i%20 == 0 { if i%20 == 0 {
db.Close() db.Close()
db, _ = rawdb.NewLevelDBDatabase(benchDataDir, 128, 1024, "", false) db, _ = rawdb.NewLevelDBDatabase(benchDataDir, 128, 1024, "", false)
backend = &testBackend{db: db, sections: cnt} backend = &TestBackend{DB: db, sections: cnt}
} }
var addr common.Address var addr common.Address
addr[0] = byte(i) addr[0] = byte(i)
@ -173,7 +173,7 @@ func BenchmarkNoBloomBits(b *testing.B) {
b.Log("Running filter benchmarks...") b.Log("Running filter benchmarks...")
start := time.Now() start := time.Now()
backend := &testBackend{db: db} backend := &TestBackend{DB: db}
filter := NewRangeFilter(backend, 0, int64(*headNum), []common.Address{{}}, nil) filter := NewRangeFilter(backend, 0, int64(*headNum), []common.Address{{}}, nil)
filter.Logs(context.Background()) filter.Logs(context.Background())
d := time.Since(start) d := time.Since(start)

View file

@ -1,30 +0,0 @@
package filters
import (
"context"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
)
func (b *testBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) {
number := rawdb.ReadHeaderNumber(b.db, hash)
if number == nil {
return nil, nil
}
receipt := rawdb.ReadBorReceipt(b.db, hash, *number)
if receipt == nil {
return nil, nil
}
return receipt, nil
}
func (b *testBackend) GetBorBlockLogs(ctx context.Context, hash common.Hash) ([]*types.Log, error) {
receipt, err := b.GetBorBlockReceipt(ctx, hash)
if receipt == nil || err != nil {
return nil, nil
}
return receipt.Logs, nil
}

View file

@ -20,7 +20,7 @@ func TestBorFilters(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr = crypto.PubkeyToAddress(key1.PublicKey) addr = crypto.PubkeyToAddress(key1.PublicKey)

View file

@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
) )
//go:generate mockgen -destination=../../eth/filters/IBackend.go -package=filters . Backend
type Backend interface { type Backend interface {
ChainDb() ethdb.Database ChainDb() ethdb.Database
HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error)

View file

@ -20,7 +20,6 @@ import (
"context" "context"
"fmt" "fmt"
"math/big" "math/big"
"math/rand"
"reflect" "reflect"
"runtime" "runtime"
"testing" "testing"
@ -30,11 +29,8 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
) )
@ -44,126 +40,6 @@ var (
borLogs bool = true borLogs bool = true
) )
type testBackend struct {
mux *event.TypeMux
db ethdb.Database
sections uint64
txFeed event.Feed
logsFeed event.Feed
rmLogsFeed event.Feed
pendingLogsFeed event.Feed
chainFeed event.Feed
stateSyncFeed event.Feed
}
func (b *testBackend) ChainDb() ethdb.Database {
return b.db
}
func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
var (
hash common.Hash
num uint64
)
if blockNr == rpc.LatestBlockNumber {
hash = rawdb.ReadHeadBlockHash(b.db)
number := rawdb.ReadHeaderNumber(b.db, hash)
if number == nil {
return nil, nil
}
num = *number
} else {
num = uint64(blockNr)
hash = rawdb.ReadCanonicalHash(b.db, num)
}
return rawdb.ReadHeader(b.db, hash, num), nil
}
func (b *testBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
number := rawdb.ReadHeaderNumber(b.db, hash)
if number == nil {
return nil, nil
}
return rawdb.ReadHeader(b.db, hash, *number), nil
}
func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil {
return rawdb.ReadReceipts(b.db, hash, *number, params.TestChainConfig), nil
}
return nil, nil
}
func (b *testBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
number := rawdb.ReadHeaderNumber(b.db, hash)
if number == nil {
return nil, nil
}
receipts := rawdb.ReadReceipts(b.db, hash, *number, params.TestChainConfig)
logs := make([][]*types.Log, len(receipts))
for i, receipt := range receipts {
logs[i] = receipt.Logs
}
return logs, nil
}
func (b *testBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
return b.txFeed.Subscribe(ch)
}
func (b *testBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
return b.rmLogsFeed.Subscribe(ch)
}
func (b *testBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
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)
}
func (b *testBackend) BloomStatus() (uint64, uint64) {
return params.BloomBitsBlocks, b.sections
}
func (b *testBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
requests := make(chan chan *bloombits.Retrieval)
go session.Multiplex(16, 0, requests)
go func() {
for {
// Wait for a service request or a shutdown
select {
case <-ctx.Done():
return
case request := <-requests:
task := <-request
task.Bitsets = make([][]byte, len(task.Sections))
for i, section := range task.Sections {
if rand.Int()%4 != 0 { // Handle occasional missing deliveries
head := rawdb.ReadCanonicalHash(b.db, (section+1)*params.BloomBitsBlocks-1)
task.Bitsets[i], _ = rawdb.ReadBloomBits(b.db, task.Bit, section, head)
}
}
request <- task
}
}
}()
}
func (b *testBackend) SubscribeStateSyncEvent(ch chan<- core.StateSyncEvent) event.Subscription {
return b.stateSyncFeed.Subscribe(ch)
}
// TestBlockSubscription tests if a block subscription returns block hashes for posted chain events. // TestBlockSubscription tests if a block subscription returns block hashes for posted chain events.
// It creates multiple subscriptions: // It creates multiple subscriptions:
// - one at the start and should receive all posted chain events and a second (blockHashes) // - one at the start and should receive all posted chain events and a second (blockHashes)
@ -174,7 +50,7 @@ func TestBlockSubscription(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
api = NewPublicFilterAPI(backend, false, deadline, borLogs) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
genesis = (&core.Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db) genesis = (&core.Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
chain, _ = core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {}) chain, _ = core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {})
@ -226,7 +102,7 @@ func TestPendingTxFilter(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
api = NewPublicFilterAPI(backend, false, deadline, borLogs) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
transactions = []*types.Transaction{ transactions = []*types.Transaction{
@ -281,7 +157,7 @@ func TestPendingTxFilter(t *testing.T) {
func TestLogFilterCreation(t *testing.T) { func TestLogFilterCreation(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
api = NewPublicFilterAPI(backend, false, deadline, borLogs) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
testCases = []struct { testCases = []struct {
@ -325,7 +201,7 @@ func TestInvalidLogFilterCreation(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
api = NewPublicFilterAPI(backend, false, deadline, borLogs) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
) )
@ -347,7 +223,7 @@ func TestInvalidLogFilterCreation(t *testing.T) {
func TestInvalidGetLogsRequest(t *testing.T) { func TestInvalidGetLogsRequest(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
api = NewPublicFilterAPI(backend, false, deadline, borLogs) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
) )
@ -372,7 +248,7 @@ func TestLogFilter(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
api = NewPublicFilterAPI(backend, false, deadline, borLogs) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111") firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
@ -486,7 +362,7 @@ func TestPendingLogsSubscription(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
api = NewPublicFilterAPI(backend, false, deadline, borLogs) api = NewPublicFilterAPI(backend, false, deadline, borLogs)
firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111") firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
@ -670,7 +546,7 @@ func TestPendingTxFilterDeadlock(t *testing.T) {
var ( var (
db = rawdb.NewMemoryDatabase() db = rawdb.NewMemoryDatabase()
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
api = NewPublicFilterAPI(backend, false, timeout, borLogs) api = NewPublicFilterAPI(backend, false, timeout, borLogs)
done = make(chan struct{}) done = make(chan struct{})
) )

View file

@ -50,7 +50,7 @@ func BenchmarkFilters(b *testing.B) {
var ( var (
db, _ = rawdb.NewLevelDBDatabase(dir, 0, 0, "", false) db, _ = rawdb.NewLevelDBDatabase(dir, 0, 0, "", false)
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr1 = crypto.PubkeyToAddress(key1.PublicKey) addr1 = crypto.PubkeyToAddress(key1.PublicKey)
addr2 = common.BytesToAddress([]byte("jeff")) addr2 = common.BytesToAddress([]byte("jeff"))
@ -108,7 +108,7 @@ func TestFilters(t *testing.T) {
var ( var (
db, _ = rawdb.NewLevelDBDatabase(dir, 0, 0, "", false) db, _ = rawdb.NewLevelDBDatabase(dir, 0, 0, "", false)
backend = &testBackend{db: db} backend = &TestBackend{DB: db}
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr = crypto.PubkeyToAddress(key1.PublicKey) addr = crypto.PubkeyToAddress(key1.PublicKey)

157
eth/filters/test_backend.go Normal file
View file

@ -0,0 +1,157 @@
package filters
import (
context "context"
"math/rand"
common "github.com/ethereum/go-ethereum/common"
core "github.com/ethereum/go-ethereum/core"
bloombits "github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/rawdb"
types "github.com/ethereum/go-ethereum/core/types"
ethdb "github.com/ethereum/go-ethereum/ethdb"
event "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
rpc "github.com/ethereum/go-ethereum/rpc"
)
type TestBackend struct {
mux *event.TypeMux
DB ethdb.Database
sections uint64
txFeed event.Feed
logsFeed event.Feed
rmLogsFeed event.Feed
pendingLogsFeed event.Feed
chainFeed event.Feed
stateSyncFeed event.Feed
}
func (b *TestBackend) BloomStatus() (uint64, uint64) {
return params.BloomBitsBlocks, b.sections
}
func (b *TestBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) {
number := rawdb.ReadHeaderNumber(b.DB, hash)
if number == nil {
return nil, nil
}
receipt := rawdb.ReadBorReceipt(b.DB, hash, *number)
if receipt == nil {
return nil, nil
}
return receipt, nil
}
func (b *TestBackend) GetBorBlockLogs(ctx context.Context, hash common.Hash) ([]*types.Log, error) {
receipt, err := b.GetBorBlockReceipt(ctx, hash)
if receipt == nil || err != nil {
return nil, nil
}
return receipt.Logs, nil
}
func (b *TestBackend) ChainDb() ethdb.Database {
return b.DB
}
func (b *TestBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
var (
hash common.Hash
num uint64
)
if blockNr == rpc.LatestBlockNumber {
hash = rawdb.ReadHeadBlockHash(b.DB)
number := rawdb.ReadHeaderNumber(b.DB, hash)
if number == nil {
return nil, nil
}
num = *number
} else {
num = uint64(blockNr)
hash = rawdb.ReadCanonicalHash(b.DB, num)
}
return rawdb.ReadHeader(b.DB, hash, num), nil
}
func (b *TestBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
number := rawdb.ReadHeaderNumber(b.DB, hash)
if number == nil {
return nil, nil
}
return rawdb.ReadHeader(b.DB, hash, *number), nil
}
func (b *TestBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
if number := rawdb.ReadHeaderNumber(b.DB, hash); number != nil {
return rawdb.ReadReceipts(b.DB, hash, *number, params.TestChainConfig), nil
}
return nil, nil
}
func (b *TestBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
number := rawdb.ReadHeaderNumber(b.DB, hash)
if number == nil {
return nil, nil
}
receipts := rawdb.ReadReceipts(b.DB, hash, *number, params.TestChainConfig)
logs := make([][]*types.Log, len(receipts))
for i, receipt := range receipts {
logs[i] = receipt.Logs
}
return logs, nil
}
func (b *TestBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
return b.txFeed.Subscribe(ch)
}
func (b *TestBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
return b.rmLogsFeed.Subscribe(ch)
}
func (b *TestBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
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)
}
func (b *TestBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
requests := make(chan chan *bloombits.Retrieval)
go session.Multiplex(16, 0, requests)
go func() {
for {
// Wait for a service request or a shutdown
select {
case <-ctx.Done():
return
case request := <-requests:
task := <-request
task.Bitsets = make([][]byte, len(task.Sections))
for i, section := range task.Sections {
if rand.Int()%4 != 0 { // Handle occasional missing deliveries
head := rawdb.ReadCanonicalHash(b.DB, (section+1)*params.BloomBitsBlocks-1)
task.Bitsets[i], _ = rawdb.ReadBloomBits(b.DB, task.Bit, section, head)
}
}
request <- task
}
}
}()
}
func (b *TestBackend) SubscribeStateSyncEvent(ch chan<- core.StateSyncEvent) event.Subscription {
return b.stateSyncFeed.Subscribe(ch)
}

View file

@ -0,0 +1,183 @@
//go:build integration
package filters
import (
"context"
"fmt"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/params"
)
func TestBorFilters(t *testing.T) {
t.Parallel()
var (
db = rawdb.NewMemoryDatabase()
backend = &filters.TestBackend{DB: db}
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr = crypto.PubkeyToAddress(key1.PublicKey)
hash1 = common.BytesToHash([]byte("topic1"))
hash2 = common.BytesToHash([]byte("topic2"))
hash3 = common.BytesToHash([]byte("topic3"))
hash4 = common.BytesToHash([]byte("topic4"))
)
defer db.Close()
genesis := core.GenesisBlockForTesting(db, addr, big.NewInt(1000000))
sprint := params.TestChainConfig.Bor.Sprint
chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 1000, func(i int, gen *core.BlockGen) {
switch i {
case 7: //state-sync tx at block 8
receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = []*types.Log{
{
Address: addr,
Topics: []common.Hash{hash1},
},
}
gen.AddUncheckedReceipt(receipt)
gen.AddUncheckedTx(types.NewTransaction(8, common.HexToAddress("0x8"), big.NewInt(8), 8, gen.BaseFee(), nil))
case 23: //state-sync tx at block 24
receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = []*types.Log{
{
Address: addr,
Topics: []common.Hash{hash2},
},
}
gen.AddUncheckedReceipt(receipt)
gen.AddUncheckedTx(types.NewTransaction(24, common.HexToAddress("0x24"), big.NewInt(24), 24, gen.BaseFee(), nil))
case 991: //state-sync tx at block 992
receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = []*types.Log{
{
Address: addr,
Topics: []common.Hash{hash3},
},
}
gen.AddUncheckedReceipt(receipt)
gen.AddUncheckedTx(types.NewTransaction(992, common.HexToAddress("0x992"), big.NewInt(992), 992, gen.BaseFee(), nil))
case 999: //state-sync tx at block 1000
receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = []*types.Log{
{
Address: addr,
Topics: []common.Hash{hash4},
},
}
gen.AddUncheckedReceipt(receipt)
gen.AddUncheckedTx(types.NewTransaction(1000, common.HexToAddress("0x1000"), big.NewInt(1000), 1000, gen.BaseFee(), nil))
}
})
for i, block := range chain {
// write the block to database
rawdb.WriteBlock(db, block)
rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
rawdb.WriteHeadBlockHash(db, block.Hash())
blockBatch := db.NewBatch()
// since all the transactions are state-sync, we will not include them as normal receipts
rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), []*types.Receipt{})
// check for blocks with receipts. Since the only receipt is state-sync, we can chack the length of receipts
if len(receipts[i]) > 0 {
// write the state-sync receipts to database
// State sync logs don't have tx index, tx hash and other necessary fields, DeriveFieldsForBorLogs will fill those fields for websocket subscriptions
// DeriveFieldsForBorLogs argurments:
// 1. State-sync logs
// 2. Block Hash
// 3. Block Number
// 4. Transactions in the block(except state-sync) i.e. 0 in our case
// 5. AllLogs - StateSyncLogs ; since we only have state-sync tx, it will be 0
types.DeriveFieldsForBorLogs(receipts[i][0].Logs, block.Hash(), block.NumberU64(), uint(0), uint(0))
rawdb.WriteBorReceipt(blockBatch, block.Hash(), block.NumberU64(), &types.ReceiptForStorage{
Status: types.ReceiptStatusSuccessful, // make receipt status successful
Logs: receipts[i][0].Logs,
})
rawdb.WriteBorTxLookupEntry(blockBatch, block.Hash(), block.NumberU64())
}
if err := blockBatch.Write(); err != nil {
fmt.Println("Failed to write block into disk", "err", err)
}
}
filter := filters.NewBorBlockLogsRangeFilter(backend, sprint, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
logs, _ := filter.Logs(context.Background())
if len(logs) != 4 {
t.Error("expected 4 log, got", len(logs))
}
filter = filters.NewBorBlockLogsRangeFilter(backend, sprint, 900, 999, []common.Address{addr}, [][]common.Hash{{hash3}})
logs, _ = filter.Logs(context.Background())
if len(logs) != 1 {
t.Error("expected 1 log, got", len(logs))
}
if len(logs) > 0 && logs[0].Topics[0] != hash3 {
t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
}
filter = filters.NewBorBlockLogsRangeFilter(backend, sprint, 992, -1, []common.Address{addr}, [][]common.Hash{{hash3}})
logs, _ = filter.Logs(context.Background())
if len(logs) != 1 {
t.Error("expected 1 log, got", len(logs))
}
if len(logs) > 0 && logs[0].Topics[0] != hash3 {
t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0])
}
filter = filters.NewBorBlockLogsRangeFilter(backend, sprint, 1, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2}})
logs, _ = filter.Logs(context.Background())
if len(logs) != 2 {
t.Error("expected 2 log, got", len(logs))
}
failHash := common.BytesToHash([]byte("fail"))
filter = filters.NewBorBlockLogsRangeFilter(backend, sprint, 0, -1, nil, [][]common.Hash{{failHash}})
logs, _ = filter.Logs(context.Background())
if len(logs) != 0 {
t.Error("expected 0 log, got", len(logs))
}
failAddr := common.BytesToAddress([]byte("failmenow"))
filter = filters.NewBorBlockLogsRangeFilter(backend, sprint, 0, -1, []common.Address{failAddr}, nil)
logs, _ = filter.Logs(context.Background())
if len(logs) != 0 {
t.Error("expected 0 log, got", len(logs))
}
filter = filters.NewBorBlockLogsRangeFilter(backend, sprint, 0, -1, nil, [][]common.Hash{{failHash}, {hash1}})
logs, _ = filter.Logs(context.Background())
if len(logs) != 0 {
t.Error("expected 0 log, got", len(logs))
}
}