Skip to content

Commit

Permalink
optionally dump all read and written registers
Browse files Browse the repository at this point in the history
  • Loading branch information
turbolent committed Jan 24, 2025
1 parent 7d305da commit 0c0326b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 10 deletions.
41 changes: 37 additions & 4 deletions cmd/util/cmd/debug-tx/cmd.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package debug_tx

import (
"cmp"
"context"
"encoding/hex"

"github.com/onflow/flow/protobuf/go/flow/execution"
"github.com/onflow/flow/protobuf/go/flow/executiondata"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

Expand All @@ -29,6 +32,7 @@ var (
flagComputeLimit uint64
flagProposalKeySeq uint64
flagUseExecutionDataAPI bool
flagDumpRegisters bool
)

var Cmd = &cobra.Command{
Expand Down Expand Up @@ -61,6 +65,8 @@ func init() {
Cmd.Flags().Uint64Var(&flagProposalKeySeq, "proposal-key-seq", 0, "proposal key sequence number")

Cmd.Flags().BoolVar(&flagUseExecutionDataAPI, "use-execution-data-api", false, "use the execution data API")

Cmd.Flags().BoolVar(&flagDumpRegisters, "dump-registers", false, "dump registers")
}

func run(*cobra.Command, []string) {
Expand Down Expand Up @@ -187,11 +193,38 @@ func run(*cobra.Command, []string) {
proposalKeySequenceNumber,
)

txErr, processErr := debugger.RunTransaction(txBody, snap, header)
if txErr != nil {
log.Err(txErr).Msg("transaction error")
}
resultSnapshot, txErr, processErr := debugger.RunTransaction(txBody, snap, header)
if processErr != nil {
log.Fatal().Err(processErr).Msg("process error")
}

if flagDumpRegisters {
log.Info().Msg("Read registers:")
readRegisterIDs := resultSnapshot.ReadRegisterIDs()
sortRegisters(readRegisterIDs)
for _, registerID := range readRegisterIDs {
log.Info().Msgf("\t%s", registerID)
}

log.Info().Msg("Written registers:")
for _, updatedRegister := range resultSnapshot.UpdatedRegisters() {
log.Info().Msgf(
"\t%s, %s",
updatedRegister.Key,
hex.EncodeToString(updatedRegister.Value),
)
}
}
if txErr != nil {
log.Err(txErr).Msg("transaction error")
}
}

func sortRegisters(registerIDs []flow.RegisterID) {
slices.SortFunc(registerIDs, func(a, b flow.RegisterID) int {
return cmp.Or(
cmp.Compare(a.Owner, b.Owner),
cmp.Compare(a.Key, b.Key),
)
})
}
6 changes: 3 additions & 3 deletions utils/debug/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func TestDebugger_RunTransactionAgainstExecutionNodeAtBlockID(t *testing.T) {

txBody := getTransaction(chain)

txErr, err := debugger.RunTransaction(txBody, snapshot, header)
_, txErr, err := debugger.RunTransaction(txBody, snapshot, header)
require.NoError(t, txErr)
require.NoError(t, err)
}
Expand Down Expand Up @@ -137,12 +137,12 @@ func TestDebugger_RunTransactionAgainstAccessNodeAtBlockIDWithFileCache(t *testi
txBody := getTransaction(chain)

// the first run will cache the results
txErr, err := debugger.RunTransaction(txBody, snapshot, header)
_, txErr, err := debugger.RunTransaction(txBody, snapshot, header)
require.NoError(t, txErr)
require.NoError(t, err)

// the second run should only use the cache.
txErr, err = debugger.RunTransaction(txBody, snapshot, header)
_, txErr, err = debugger.RunTransaction(txBody, snapshot, header)
require.NoError(t, txErr)
require.NoError(t, err)
}
Expand Down
12 changes: 9 additions & 3 deletions utils/debug/remoteDebugger.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/rs/zerolog"

"github.com/onflow/flow-go/fvm"
"github.com/onflow/flow-go/fvm/storage/snapshot"
"github.com/onflow/flow-go/model/flow"
)

Expand Down Expand Up @@ -43,6 +44,7 @@ func (d *RemoteDebugger) RunTransaction(
snapshot StorageSnapshot,
blockHeader *flow.Header,
) (
resultSnapshot *snapshot.ExecutionSnapshot,
txErr error,
processError error,
) {
Expand All @@ -52,11 +54,15 @@ func (d *RemoteDebugger) RunTransaction(

tx := fvm.Transaction(txBody, 0)

_, output, err := d.vm.Run(blockCtx, tx, snapshot)
var (
output fvm.ProcedureOutput
err error
)
resultSnapshot, output, err = d.vm.Run(blockCtx, tx, snapshot)
if err != nil {
return nil, err
return resultSnapshot, nil, err
}
return output.Err, nil
return resultSnapshot, output.Err, nil
}

// RunScript runs the script using the given storage snapshot.
Expand Down

0 comments on commit 0c0326b

Please sign in to comment.