plugeth/plugins/ptp/live_tracer.go

158 lines
4.0 KiB
Go
Raw Normal View History

package main
import (
"context"
"math/big"
"time"
"github.com/openrelayxyz/plugeth-utils/core"
"github.com/openrelayxyz/plugeth-utils/restricted/hexutil"
)
type LiveTracerResult struct {
CallStack []CallStack
Results []CallStack
}
type CallStack struct {
Type string `json:"type"`
From core.Address `json:"from"`
To core.Address `json:"to"`
Value *big.Int `json:"value,omitempty"`
Gas hexutil.Uint64 `json:"gas"`
GasUsed hexutil.Uint64 `json:"gasUsed"`
Input hexutil.Bytes `json:"input"`
Output hexutil.Bytes `json:"output"`
Time string `json:"time,omitempty"`
Calls []CallStack `json:"calls,omitempty"`
Results []CallStack `json:"results,omitempty"`
Error string `json:"error,omitempty"`
}
func (t *LiveTracerResult) TraceBlock(ctx context.Context) (<-chan []CallStack, error) {
subch := make(chan []CallStack, 1000)
rtrnch := make(chan []CallStack, 1000)
go func() {
log.Info("Subscription Block Tracer setup")
sub := events.Subscribe(subch)
for {
select {
case <-ctx.Done():
sub.Unsubscribe()
close(subch)
close(rtrnch)
return
case t := <-subch:
rtrnch <- t
case <-sub.Err():
sub.Unsubscribe()
close(subch)
close(rtrnch)
return
}
}
}()
return rtrnch, nil
}
func GetLiveTracer(core.Hash, core.StateDB) core.BlockTracer {
return &LiveTracerResult{}
}
func (r *LiveTracerResult) PreProcessBlock(hash core.Hash, number uint64, encoded []byte) {
m := map[string]struct{}{
"LivePreProcessBlock":struct{}{},
}
hookChan <- m
r.Results = []CallStack{}
}
func (r *LiveTracerResult) PreProcessTransaction(tx core.Hash, block core.Hash, i int) {
m := map[string]struct{}{
"LivePreProcessTransaction":struct{}{},
}
hookChan <- m
}
func (r *LiveTracerResult) BlockProcessingError(tx core.Hash, block core.Hash, err error) {
m := map[string]struct{}{
"LiveBlockProcessingError":struct{}{},
}
hookChan <- m
}
func (r *LiveTracerResult) PostProcessTransaction(tx core.Hash, block core.Hash, i int, receipt []byte) {
m := map[string]struct{}{
"LivePostProcessTransaction":struct{}{},
}
hookChan <- m
}
func (r *LiveTracerResult) PostProcessBlock(block core.Hash) {
m := map[string]struct{}{
"LivePostProcessBlock":struct{}{},
}
hookChan <- m
if len(r.Results) > 0 {
events.Send(r.Results)
}
}
func (r *LiveTracerResult) CaptureStart(from core.Address, to core.Address, create bool, input []byte, gas uint64, value *big.Int) {
r.CallStack = []CallStack{}
m := map[string]struct{}{
"LiveCaptureStart":struct{}{},
}
hookChan <- m
}
func (r *LiveTracerResult) CaptureState(pc uint64, op core.OpCode, gas, cost uint64, scope core.ScopeContext, rData []byte, depth int, err error) {
m := map[string]struct{}{
"LiveCaptureState":struct{}{},
}
hookChan <- m
}
func (r *LiveTracerResult) CaptureFault(pc uint64, op core.OpCode, gas, cost uint64, scope core.ScopeContext, depth int, err error) {
// this method is not covered by tests at this time
// m := map[string]struct{}{
// "LiveCaptureFault":struct{}{},
// }
// hookChan <- m
}
func (r *LiveTracerResult) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {
m := map[string]struct{}{
"LiveCaptureEnd":struct{}{},
}
hookChan <- m
if len(r.CallStack) > 0 {
r.Results = append(r.CallStack)
}
}
func (r *LiveTracerResult) CaptureEnter(typ core.OpCode, from core.Address, to core.Address, input []byte, gas uint64, value *big.Int) {
// this method is not covered by tests at this time
// m := map[string]struct{}{
// "LiveCaptureEnter":struct{}{},
// }
// hookChan <- m
}
func (r *LiveTracerResult) CaptureExit(output []byte, gasUsed uint64, err error) {
// this method is not covered by tests at this time
// m := map[string]struct{}{
// "LiveCaptureExit":struct{}{},
// }
// hookChan <- m
}
func (r *LiveTracerResult) Result() (interface{}, error) {
// this method is not covered by tests at this time
// m := map[string]struct{}{
// "LiveTracerResult":struct{}{},
// }
// hookChan <- m
return "", nil
}