Skip to content

Commit

Permalink
Subscription service to detect address accesses
Browse files Browse the repository at this point in the history
  • Loading branch information
wizeguyy committed Sep 16, 2024
1 parent 1a3bd86 commit af9fe8f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
5 changes: 5 additions & 0 deletions quai/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ func (b *QuaiAPIBackend) GetBloom(hash common.Hash) (*types.Bloom, error) {
return b.quai.core.Slice().HeaderChain().GetBloom(hash)
}

// GetBlock returns the Block for the given block hash
func (b *QuaiAPIBackend) GetBlock(hash common.Hash, number uint64) (*types.WorkObject, error) {
return b.quai.core.Slice().HeaderChain().GetBlock(hash, number), nil
}

func (b *QuaiAPIBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
nodeCtx := b.quai.core.NodeCtx()
if nodeCtx != common.ZONE_CTX {
Expand Down
57 changes: 57 additions & 0 deletions quai/filters/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,63 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er
return rpcSub, nil
}

// Accesses send a notification each time the specified address is accessed
func (api *PublicFilterAPI) Accesses(ctx context.Context, addr common.Address) (*rpc.Subscription, error) {
notifier, supported := rpc.NotifierFromContext(ctx)
if !supported {
return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
}

rpcSub := notifier.CreateSubscription()

go func() {
defer func() {
if r := recover(); r != nil {
api.backend.Logger().WithFields(log.Fields{
"error": r,
"stacktrace": string(debug.Stack()),
}).Fatal("Go-Quai Panicked")
}
}()
headers := make(chan *types.WorkObject)
headersSub := api.events.SubscribeNewHeads(headers)

for {
select {
case h := <-headers:
// Marshal the header data
hash := h.Hash()
nodeLocation := api.backend.NodeLocation()
nodeCtx := nodeLocation.Context()
if block, err := api.backend.GetBlock(h.Hash(), h.NumberU64(nodeCtx)); err != nil {
for _, tx := range block.Transactions() {
// Check for external accesses
if tx.To() == &addr || tx.From(nodeLocation) == &addr {
notifier.Notify(rpcSub.ID, hash)
break
}
// Check for EVM accesses
for _, access := range tx.AccessList() {
if access.Address == addr {
notifier.Notify(rpcSub.ID, hash)
break
}
}
}
}
case <-rpcSub.Err():
headersSub.Unsubscribe()
return
case <-notifier.Closed():
headersSub.Unsubscribe()
return
}
}
}()

return rpcSub, nil
}

// Logs creates a subscription that fires for all new log that match the given filter criteria.
func (api *PublicFilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc.Subscription, error) {
notifier, supported := rpc.NotifierFromContext(ctx)
Expand Down
1 change: 1 addition & 0 deletions quai/filters/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type Backend interface {
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error)
GetBloom(blockHash common.Hash) (*types.Bloom, error)
GetBlock(hash common.Hash, number uint64) (*types.WorkObject, error)
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription
SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription
Expand Down

0 comments on commit af9fe8f

Please sign in to comment.