github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/eth/filters/test_backend.go (about)

     1  package filters
     2  
     3  import (
     4  	context "context"
     5  	"crypto/rand"
     6  	"math/big"
     7  
     8  	common "github.com/ethereum/go-ethereum/common"
     9  	core "github.com/ethereum/go-ethereum/core"
    10  	bloombits "github.com/ethereum/go-ethereum/core/bloombits"
    11  	"github.com/ethereum/go-ethereum/core/rawdb"
    12  	types "github.com/ethereum/go-ethereum/core/types"
    13  	ethdb "github.com/ethereum/go-ethereum/ethdb"
    14  	event "github.com/ethereum/go-ethereum/event"
    15  	"github.com/ethereum/go-ethereum/params"
    16  	rpc "github.com/ethereum/go-ethereum/rpc"
    17  )
    18  
    19  type TestBackend struct {
    20  	DB              ethdb.Database
    21  	sections        uint64
    22  	txFeed          event.Feed
    23  	logsFeed        event.Feed
    24  	rmLogsFeed      event.Feed
    25  	pendingLogsFeed event.Feed
    26  	chainFeed       event.Feed
    27  
    28  	stateSyncFeed event.Feed
    29  }
    30  
    31  func (b *TestBackend) BloomStatus() (uint64, uint64) {
    32  	return params.BloomBitsBlocks, b.sections
    33  }
    34  
    35  func (b *TestBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) {
    36  	number := rawdb.ReadHeaderNumber(b.DB, hash)
    37  	if number == nil {
    38  		return &types.Receipt{}, nil
    39  	}
    40  
    41  	receipt := rawdb.ReadBorReceipt(b.DB, hash, *number, nil)
    42  	if receipt == nil {
    43  		return &types.Receipt{}, nil
    44  	}
    45  
    46  	return receipt, nil
    47  }
    48  
    49  func (b *TestBackend) GetBorBlockLogs(ctx context.Context, hash common.Hash) ([]*types.Log, error) {
    50  	receipt, err := b.GetBorBlockReceipt(ctx, hash)
    51  	if err != nil {
    52  		return []*types.Log{}, err
    53  	}
    54  
    55  	if receipt == nil {
    56  		return []*types.Log{}, nil
    57  	}
    58  
    59  	return receipt.Logs, nil
    60  }
    61  
    62  func (b *TestBackend) ChainDb() ethdb.Database {
    63  	return b.DB
    64  }
    65  
    66  func (b *TestBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
    67  	var (
    68  		hash common.Hash
    69  		num  uint64
    70  	)
    71  
    72  	if blockNr == rpc.LatestBlockNumber {
    73  		hash = rawdb.ReadHeadBlockHash(b.DB)
    74  		number := rawdb.ReadHeaderNumber(b.DB, hash)
    75  
    76  		if number == nil {
    77  			return &types.Header{}, nil
    78  		}
    79  
    80  		num = *number
    81  	} else {
    82  		num = uint64(blockNr)
    83  		hash = rawdb.ReadCanonicalHash(b.DB, num)
    84  	}
    85  
    86  	return rawdb.ReadHeader(b.DB, hash, num), nil
    87  }
    88  
    89  func (b *TestBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
    90  	number := rawdb.ReadHeaderNumber(b.DB, hash)
    91  	if number == nil {
    92  		return &types.Header{}, nil
    93  	}
    94  
    95  	return rawdb.ReadHeader(b.DB, hash, *number), nil
    96  }
    97  
    98  func (b *TestBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
    99  	if number := rawdb.ReadHeaderNumber(b.DB, hash); number != nil {
   100  		return rawdb.ReadReceipts(b.DB, hash, *number, params.TestChainConfig), nil
   101  	}
   102  
   103  	return nil, nil
   104  }
   105  
   106  func (b *TestBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
   107  	number := rawdb.ReadHeaderNumber(b.DB, hash)
   108  	if number == nil {
   109  		return nil, nil
   110  	}
   111  
   112  	receipts := rawdb.ReadReceipts(b.DB, hash, *number, params.TestChainConfig)
   113  
   114  	logs := make([][]*types.Log, len(receipts))
   115  	for i, receipt := range receipts {
   116  		logs[i] = receipt.Logs
   117  	}
   118  
   119  	return logs, nil
   120  }
   121  
   122  func (b *TestBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
   123  	return b.txFeed.Subscribe(ch)
   124  }
   125  
   126  func (b *TestBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
   127  	return b.rmLogsFeed.Subscribe(ch)
   128  }
   129  
   130  func (b *TestBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
   131  	return b.logsFeed.Subscribe(ch)
   132  }
   133  
   134  func (b *TestBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription {
   135  	return b.pendingLogsFeed.Subscribe(ch)
   136  }
   137  
   138  func (b *TestBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
   139  	return b.chainFeed.Subscribe(ch)
   140  }
   141  
   142  func (b *TestBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
   143  	requests := make(chan chan *bloombits.Retrieval)
   144  
   145  	go session.Multiplex(16, 0, requests)
   146  	go func() {
   147  		for {
   148  			// Wait for a service request or a shutdown
   149  			select {
   150  			case <-ctx.Done():
   151  				return
   152  
   153  			case request := <-requests:
   154  				task := <-request
   155  
   156  				task.Bitsets = make([][]byte, len(task.Sections))
   157  				for i, section := range task.Sections {
   158  					nBig, err := rand.Int(rand.Reader, big.NewInt(100))
   159  
   160  					if err != nil {
   161  						panic(err)
   162  					}
   163  
   164  					if nBig.Int64()%4 != 0 { // Handle occasional missing deliveries
   165  						head := rawdb.ReadCanonicalHash(b.DB, (section+1)*params.BloomBitsBlocks-1)
   166  						task.Bitsets[i], _ = rawdb.ReadBloomBits(b.DB, task.Bit, section, head)
   167  					}
   168  				}
   169  				request <- task
   170  			}
   171  		}
   172  	}()
   173  }
   174  
   175  func (b *TestBackend) SubscribeStateSyncEvent(ch chan<- core.StateSyncEvent) event.Subscription {
   176  	return b.stateSyncFeed.Subscribe(ch)
   177  }