Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
tsachiherman committed Oct 8, 2024
1 parent c172c59 commit 89a134d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 51 deletions.
25 changes: 13 additions & 12 deletions api/jsonrpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/ava-labs/hypersdk/codec"
"github.com/ava-labs/hypersdk/fees"
"github.com/ava-labs/hypersdk/requester"
"github.com/ava-labs/hypersdk/state"
"github.com/ava-labs/hypersdk/utils"
)

Expand Down Expand Up @@ -237,27 +236,29 @@ func Wait(ctx context.Context, interval time.Duration, check func(ctx context.Co
return ctx.Err()
}

func (cli *JSONRPCClient) SimulateActions(ctx context.Context, actions []chain.Action, actor codec.Address) (state.Keys, []codec.Bytes, error) {
args := &SimulatActionArgs{
Actions: marshaledActions,
Actor: actor,
func (cli *JSONRPCClient) SimulateActions(ctx context.Context, actions chain.Actions, actor codec.Address) ([]SimulateActionResult, error) {
args := &SimulatActionsArgs{
Actor: actor,
}

marshaledActions, err := chain.MarshalTyped(actions)
if err != nil {
return nil, nil, err
for _, action := range actions {
marshaledAction, err := chain.MarshalTyped(action)
if err != nil {
return nil, err
}
args.Actions = append(args.Actions, marshaledAction)
}

resp := new(SimulateActionReply)
err = cli.requester.SendRequest(
resp := new(SimulateActionsReply)
err := cli.requester.SendRequest(
ctx,
"simulateActions",
args,
resp,
)
if err != nil {
return nil, nil, err
return nil, err
}

return resp.StateKeys, resp.Outputs, nil
return resp.ActionResults, nil
}
47 changes: 29 additions & 18 deletions api/jsonrpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,32 +232,40 @@ func (j *JSONRPCServer) Execute(
return nil
}

type SimulatActionArgs struct {
Actions codec.Bytes `json:"actions"`
type SimulatActionsArgs struct {
Actions []codec.Bytes `json:"actions"`
Actor codec.Address `json:"actor"`
}

type SimulateActionReply struct {
Outputs []codec.Bytes `json:"outputs"`
StateKeys state.Keys `json:"stateKeys"`
type SimulateActionResult struct {
Output codec.Bytes `json:"output"`
StateKeys state.Keys `json:"stateKeys"`
}

type SimulateActionsReply struct {
ActionResults []SimulateActionResult `json:"actionresults"`
}

func (j *JSONRPCServer) SimulateActions(
req *http.Request,
args *SimulatActionArgs,
reply *SimulateActionReply,
args *SimulatActionsArgs,
reply *SimulateActionsReply,
) error {
ctx, span := j.vm.Tracer().Start(req.Context(), "JSONRPCServer.SimulateActions")
defer span.End()

actionRegistry := j.vm.ActionRegistry()
actionsReader := codec.NewReader(args.Actions, len(args.Actions)) // will likely be much smaller than this
actions, err := chain.UnmarshalActions(actionsReader, actionRegistry)
if err != nil {
return fmt.Errorf("%w: unable to unmarshal on public service", err)
}
if !actionsReader.Empty() {
return errors.New("tx has extra bytes")
var actions chain.Actions
for _, actionBytes := range args.Actions {
actionsReader := codec.NewReader(actionBytes, len(actionBytes))
action, err := (*actionRegistry).Unmarshal(actionsReader)
if err != nil {
return err
}
if !actionsReader.Empty() {
return errors.New("tx has extra bytes")
}
actions = append(actions, action)
}
if len(actions) == 0 {
return errors.New("simulateAction expects at least a single action, none found")
Expand All @@ -273,19 +281,22 @@ func (j *JSONRPCServer) SimulateActions(
for _, action := range actions {
actionOutput, err := action.Execute(ctx, j.vm.Rules(currentTime), recorder, currentTime, args.Actor, ids.Empty)

var actionResult SimulateActionResult
if actionOutput == nil {
reply.Outputs = append(reply.Outputs, []byte{})
actionResult.Output = []byte{}
} else {
output, err := chain.MarshalTyped(actionOutput)
actionResult.Output, err = chain.MarshalTyped(actionOutput)
if err != nil {
return fmt.Errorf("failed to marshal output: %w", err)
}
reply.Outputs = append(reply.Outputs, output)
}
if err != nil {
return err
}
actionResult.StateKeys = recorder.GetStateKeys()
reply.ActionResults = append(reply.ActionResults, actionResult)
// create another recorder to recored the next action.
recorder = state.NewRecorder(recorder)
}
reply.StateKeys = recorder.GetStateKeys()
return nil
}
16 changes: 0 additions & 16 deletions examples/vmwithcontracts/actions/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,24 +147,8 @@ func (*Result) GetTypeID() uint8 {
return mconsts.ResultOutputID
}

// Marshal encodes a type as bytes.
func (r *Result) Marshal(p *codec.Packer) {
p.PackBytes(r.Value)
p.PackUint64(r.ConsumedFuel)
}

// Size is the number of bytes it takes to represent this [Action]. This is used to preallocate
// memory during encoding and to charge bandwidth fees.
func (r *Result) Size() int {
return consts.Uint64Len + consts.Uint32Len + len(r.Value)
}

func UnmarshalResult(p *codec.Packer) (*Result, error) {
var result Result
p.UnpackBytes(MaxResultSizeLimit, true, &result.Value)
p.UnpackUint64(true)
if err := p.Err(); err != nil {
return nil, err
}
return &result, nil
}
22 changes: 17 additions & 5 deletions examples/vmwithcontracts/cmd/vmwithcontracts-cli/cmd/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package cmd

import (
"context"
"errors"
"fmt"
"os"

"github.com/near/borsh-go"
Expand All @@ -15,6 +17,7 @@ import (
"github.com/ava-labs/hypersdk/cli/prompt"
"github.com/ava-labs/hypersdk/codec"
"github.com/ava-labs/hypersdk/examples/vmwithcontracts/actions"
"github.com/ava-labs/hypersdk/examples/vmwithcontracts/vm"
"github.com/ava-labs/hypersdk/utils"
)

Expand Down Expand Up @@ -144,19 +147,28 @@ var callCmd = &cobra.Command{
Fuel: uint64(1000000000),
}

specifiedStateKeysSet, encodedActionResults, err := cli.SimulateAction(ctx, action, priv.Address)
actionSimulationResults, err := cli.SimulateActions(ctx, chain.Actions{action}, priv.Address)
if err != nil {
return err
}
if len(actionSimulationResults) != 1 {
return fmt.Errorf("unexpected number of returned actions. One action expected, %d returned", len(actionSimulationResults))
}
actionSimulationResult := actionSimulationResults[0]

rtx := codec.NewReader(actionSimulationResult.Output, len(actionSimulationResult.Output))

rtx := codec.NewReader(encodedActionResults, len(encodedActionResults))
simulationResult, err := actions.UnmarshalResult(rtx)
simulationResultOutput, err := (*vm.OutputParser).Unmarshal(rtx)
if err != nil {
return err
}
simulationResult, ok := simulationResultOutput.(*actions.Result)
if !ok {
return errors.New("returned output from SimulateActions was not actions.Result")
}

action.SpecifiedStateKeys = make([]actions.StateKeyPermission, 0, len(specifiedStateKeysSet))
for key, value := range specifiedStateKeysSet {
action.SpecifiedStateKeys = make([]actions.StateKeyPermission, 0, len(actionSimulationResult.StateKeys))
for key, value := range actionSimulationResult.StateKeys {
action.SpecifiedStateKeys = append(action.SpecifiedStateKeys, actions.StateKeyPermission{Key: key, Permission: value})
}
action.Fuel = simulationResult.ConsumedFuel
Expand Down

0 comments on commit 89a134d

Please sign in to comment.