|
|
|
@ -66,6 +66,7 @@ type SimulatedBackend struct { |
|
|
|
|
mu sync.Mutex |
|
|
|
|
pendingBlock *types.Block // Currently pending block that will be imported on request
|
|
|
|
|
pendingState *state.StateDB // Currently pending state that will be the active on request
|
|
|
|
|
pendingReceipts types.Receipts // Currently receipts for the pending block
|
|
|
|
|
|
|
|
|
|
events *filters.EventSystem // Event system for filtering log events live
|
|
|
|
|
|
|
|
|
@ -84,8 +85,8 @@ func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.Genesis |
|
|
|
|
database: database, |
|
|
|
|
blockchain: blockchain, |
|
|
|
|
config: genesis.Config, |
|
|
|
|
events: filters.NewEventSystem(&filterBackend{database, blockchain}, false), |
|
|
|
|
} |
|
|
|
|
backend.events = filters.NewEventSystem(&filterBackend{database, blockchain, backend}, false) |
|
|
|
|
backend.rollback(blockchain.CurrentBlock()) |
|
|
|
|
return backend |
|
|
|
|
} |
|
|
|
@ -662,7 +663,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa |
|
|
|
|
return fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce) |
|
|
|
|
} |
|
|
|
|
// Include tx in chain
|
|
|
|
|
blocks, _ := core.GenerateChain(b.config, block, ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) { |
|
|
|
|
blocks, receipts := core.GenerateChain(b.config, block, ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) { |
|
|
|
|
for _, tx := range b.pendingBlock.Transactions() { |
|
|
|
|
block.AddTxWithChain(b.blockchain, tx) |
|
|
|
|
} |
|
|
|
@ -672,6 +673,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa |
|
|
|
|
|
|
|
|
|
b.pendingBlock = blocks[0] |
|
|
|
|
b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil) |
|
|
|
|
b.pendingReceipts = receipts[0] |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -683,7 +685,7 @@ func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.Filter |
|
|
|
|
var filter *filters.Filter |
|
|
|
|
if query.BlockHash != nil { |
|
|
|
|
// Block filter requested, construct a single-shot filter
|
|
|
|
|
filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain}, *query.BlockHash, query.Addresses, query.Topics) |
|
|
|
|
filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain, b}, *query.BlockHash, query.Addresses, query.Topics) |
|
|
|
|
} else { |
|
|
|
|
// Initialize unset filter boundaries to run from genesis to chain head
|
|
|
|
|
from := int64(0) |
|
|
|
@ -695,7 +697,7 @@ func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.Filter |
|
|
|
|
to = query.ToBlock.Int64() |
|
|
|
|
} |
|
|
|
|
// Construct the range filter
|
|
|
|
|
filter = filters.NewRangeFilter(&filterBackend{b.database, b.blockchain}, from, to, query.Addresses, query.Topics) |
|
|
|
|
filter = filters.NewRangeFilter(&filterBackend{b.database, b.blockchain, b}, from, to, query.Addresses, query.Topics) |
|
|
|
|
} |
|
|
|
|
// Run the filter and return all the logs
|
|
|
|
|
logs, err := filter.Logs(ctx) |
|
|
|
@ -818,6 +820,7 @@ func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList } |
|
|
|
|
type filterBackend struct { |
|
|
|
|
db ethdb.Database |
|
|
|
|
bc *core.BlockChain |
|
|
|
|
backend *SimulatedBackend |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db } |
|
|
|
@ -834,6 +837,10 @@ func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*t |
|
|
|
|
return fb.bc.GetHeaderByHash(hash), nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (fb *filterBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) { |
|
|
|
|
return fb.backend.pendingBlock, fb.backend.pendingReceipts |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { |
|
|
|
|
number := rawdb.ReadHeaderNumber(fb.db, hash) |
|
|
|
|
if number == nil { |
|
|
|
|