github.com/koko1123/flow-go-1@v0.29.6/utils/debug/remoteDebugger.go (about)

     1  package debug
     2  
     3  import (
     4  	"github.com/onflow/cadence"
     5  	"github.com/rs/zerolog"
     6  
     7  	"github.com/koko1123/flow-go-1/fvm"
     8  	"github.com/koko1123/flow-go-1/model/flow"
     9  )
    10  
    11  type RemoteDebugger struct {
    12  	vm          fvm.VM
    13  	ctx         fvm.Context
    14  	grpcAddress string
    15  }
    16  
    17  // Warning : make sure you use the proper flow-go version, same version as the network you are collecting registers
    18  // from, otherwise the execution might differ from the way runs on the network
    19  func NewRemoteDebugger(grpcAddress string,
    20  	chain flow.Chain,
    21  	logger zerolog.Logger) *RemoteDebugger {
    22  	vm := fvm.NewVirtualMachine()
    23  
    24  	// no signature processor here
    25  	// TODO Maybe we add fee-deduction step as well
    26  	ctx := fvm.NewContext(
    27  		fvm.WithLogger(logger),
    28  		fvm.WithChain(chain),
    29  		fvm.WithAuthorizationChecksEnabled(false),
    30  	)
    31  
    32  	return &RemoteDebugger{
    33  		ctx:         ctx,
    34  		vm:          vm,
    35  		grpcAddress: grpcAddress,
    36  	}
    37  }
    38  
    39  // RunTransaction runs the transaction given the latest sealed block data
    40  func (d *RemoteDebugger) RunTransaction(txBody *flow.TransactionBody) (txErr, processError error) {
    41  	view := NewRemoteView(d.grpcAddress)
    42  	blockCtx := fvm.NewContextFromParent(d.ctx, fvm.WithBlockHeader(d.ctx.BlockHeader))
    43  	tx := fvm.Transaction(txBody, 0)
    44  	err := d.vm.Run(blockCtx, tx, view)
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  	return tx.Err, nil
    49  }
    50  
    51  // RunTransaction runs the transaction and tries to collect the registers at the given blockID
    52  // note that it would be very likely that block is far in the past and you can't find the trie to
    53  // read the registers from
    54  // if regCachePath is empty, the register values won't be cached
    55  func (d *RemoteDebugger) RunTransactionAtBlockID(txBody *flow.TransactionBody, blockID flow.Identifier, regCachePath string) (txErr, processError error) {
    56  	view := NewRemoteView(d.grpcAddress, WithBlockID(blockID))
    57  	defer view.Done()
    58  
    59  	blockCtx := fvm.NewContextFromParent(d.ctx, fvm.WithBlockHeader(d.ctx.BlockHeader))
    60  	if len(regCachePath) > 0 {
    61  		view.Cache = newFileRegisterCache(regCachePath)
    62  	}
    63  	tx := fvm.Transaction(txBody, 0)
    64  	err := d.vm.Run(blockCtx, tx, view)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  	err = view.Cache.Persist()
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	return tx.Err, nil
    73  }
    74  
    75  func (d *RemoteDebugger) RunScript(code []byte, arguments [][]byte) (value cadence.Value, scriptError, processError error) {
    76  	view := NewRemoteView(d.grpcAddress)
    77  	scriptCtx := fvm.NewContextFromParent(d.ctx, fvm.WithBlockHeader(d.ctx.BlockHeader))
    78  	script := fvm.Script(code).WithArguments(arguments...)
    79  	err := d.vm.Run(scriptCtx, script, view)
    80  	if err != nil {
    81  		return nil, nil, err
    82  	}
    83  	return script.Value, script.Err, nil
    84  }
    85  
    86  func (d *RemoteDebugger) RunScriptAtBlockID(code []byte, arguments [][]byte, blockID flow.Identifier) (value cadence.Value, scriptError, processError error) {
    87  	view := NewRemoteView(d.grpcAddress, WithBlockID(blockID))
    88  	scriptCtx := fvm.NewContextFromParent(d.ctx, fvm.WithBlockHeader(d.ctx.BlockHeader))
    89  	script := fvm.Script(code).WithArguments(arguments...)
    90  	err := d.vm.Run(scriptCtx, script, view)
    91  	if err != nil {
    92  		return nil, nil, err
    93  	}
    94  	return script.Value, script.Err, nil
    95  }