From 1f809c9ab912c22e632ef98e5f009b8fd2679d7d Mon Sep 17 00:00:00 2001 From: Containerman17 <8990432+containerman17@users.noreply.github.com> Date: Fri, 4 Oct 2024 07:19:16 +0000 Subject: [PATCH 1/2] simulate multiple actions --- api/jsonrpc/client.go | 22 ++++++---- api/jsonrpc/server.go | 98 +++++++++++++++++++++++-------------------- 2 files changed, 66 insertions(+), 54 deletions(-) diff --git a/api/jsonrpc/client.go b/api/jsonrpc/client.go index 54e89d9f2e..dc76f8ffef 100644 --- a/api/jsonrpc/client.go +++ b/api/jsonrpc/client.go @@ -194,21 +194,25 @@ func (cli *JSONRPCClient) GetABI(ctx context.Context) (abi.ABI, error) { return resp.ABI, err } -func (cli *JSONRPCClient) Execute(ctx context.Context, actor codec.Address, action chain.Action) ([]byte, error) { - actionBytes, err := chain.MarshalTyped(action) - if err != nil { - return nil, fmt.Errorf("failed to marshal action: %w", err) +func (cli *JSONRPCClient) Execute(ctx context.Context, actor codec.Address, actions []chain.Action) ([][]byte, error) { + actionsMarshaled := make([][]byte, 0) + for _, action := range actions { + actionBytes, err := chain.MarshalTyped(action) + if err != nil { + return nil, fmt.Errorf("failed to marshal action: %w", err) + } + actionsMarshaled = append(actionsMarshaled, actionBytes) } args := &ExecuteActionArgs{ - Actor: actor, - Action: actionBytes, + Actor: actor, + Actions: actionsMarshaled, } resp := new(ExecuteActionReply) - err = cli.requester.SendRequest( + err := cli.requester.SendRequest( ctx, - "executeAction", + "execute", args, resp, ) @@ -219,7 +223,7 @@ func (cli *JSONRPCClient) Execute(ctx context.Context, actor codec.Address, acti return nil, fmt.Errorf("failed to execute action: %s", resp.Error) } - return resp.Output, nil + return resp.Outputs, nil } func Wait(ctx context.Context, interval time.Duration, check func(ctx context.Context) (bool, error)) error { diff --git a/api/jsonrpc/server.go b/api/jsonrpc/server.go index dcb1293aa1..cad21977be 100644 --- a/api/jsonrpc/server.go +++ b/api/jsonrpc/server.go @@ -162,13 +162,13 @@ func (j *JSONRPCServer) GetABI(_ *http.Request, _ *GetABIArgs, reply *GetABIRepl } type ExecuteActionArgs struct { - Actor codec.Address `json:"actor"` - Action []byte `json:"action"` + Actor codec.Address `json:"actor"` + Actions [][]byte `json:"actions"` } type ExecuteActionReply struct { - Output []byte `json:"output"` - Error string `json:"error"` + Outputs [][]byte `json:"outputs"` + Error string `json:"error"` } func (j *JSONRPCServer) Execute( @@ -180,58 +180,66 @@ func (j *JSONRPCServer) Execute( defer span.End() actionRegistry := j.vm.ActionRegistry() - action, err := (*actionRegistry).Unmarshal(codec.NewReader(args.Action, len(args.Action))) - if err != nil { - return fmt.Errorf("failed to unmashal action: %w", err) + actions := make([]chain.Action, 0) + for _, action := range args.Actions { + action, err := (*actionRegistry).Unmarshal(codec.NewReader(action, len(action))) + if err != nil { + return fmt.Errorf("failed to unmashal action: %w", err) + } + actions = append(actions, action) } now := time.Now().UnixMilli() - // Get expected state keys - stateKeysWithPermissions := action.StateKeys(args.Actor) + storage := make(map[string][]byte) + ts := tstate.New(1) //TODO: optimize if needed - // flatten the map to a slice of keys - storageKeysToRead := make([][]byte, 0) - for key := range stateKeysWithPermissions { - storageKeysToRead = append(storageKeysToRead, []byte(key)) - } + for _, action := range actions { + // Get expected state keys + stateKeysWithPermissions := action.StateKeys(args.Actor) - storage := make(map[string][]byte) - values, errs := j.vm.ReadState(ctx, storageKeysToRead) - for _, err := range errs { - if err != nil && !errors.Is(err, database.ErrNotFound) { - return fmt.Errorf("failed to read state: %w", err) + // flatten the map to a slice of keys + storageKeysToRead := make([][]byte, 0) + for key := range stateKeysWithPermissions { + storageKeysToRead = append(storageKeysToRead, []byte(key)) } - } - for i, value := range values { - if value == nil { - continue + + values, errs := j.vm.ReadState(ctx, storageKeysToRead) + for _, err := range errs { + if err != nil && !errors.Is(err, database.ErrNotFound) { + return fmt.Errorf("failed to read state: %w", err) + } + } + for i, value := range values { + if value == nil { + continue + } + storage[string(storageKeysToRead[i])] = value } - storage[string(storageKeysToRead[i])] = value - } - ts := tstate.New(1) - tsv := ts.NewView(stateKeysWithPermissions, storage) - - output, err := action.Execute( - ctx, - j.vm.Rules(now), - tsv, - now, - args.Actor, - ids.Empty, - ) - if err != nil { - reply.Error = fmt.Sprintf("failed to execute action: %s", err) - return nil - } + tsv := ts.NewView(stateKeysWithPermissions, storage) + + output, err := action.Execute( + ctx, + j.vm.Rules(now), + tsv, + now, + args.Actor, + ids.Empty, + ) + if err != nil { + reply.Error = fmt.Sprintf("failed to execute action: %s", err) + return nil + } - encodedOutput, err := chain.MarshalTyped(output) - if err != nil { - return fmt.Errorf("failed to marshal output: %w", err) - } + tsv.Commit() - reply.Output = encodedOutput + encodedOutput, err := chain.MarshalTyped(output) + if err != nil { + return fmt.Errorf("failed to marshal output: %w", err) + } + reply.Outputs = append(reply.Outputs, encodedOutput) + } return nil } From 68597b0d24e3c36d5b9618b0ec4268f0dd4aa885 Mon Sep 17 00:00:00 2001 From: Containerman17 <8990432+containerman17@users.noreply.github.com> Date: Fri, 4 Oct 2024 07:24:30 +0000 Subject: [PATCH 2/2] lint --- api/jsonrpc/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/jsonrpc/server.go b/api/jsonrpc/server.go index cad21977be..a4b20574cd 100644 --- a/api/jsonrpc/server.go +++ b/api/jsonrpc/server.go @@ -192,7 +192,7 @@ func (j *JSONRPCServer) Execute( now := time.Now().UnixMilli() storage := make(map[string][]byte) - ts := tstate.New(1) //TODO: optimize if needed + ts := tstate.New(1) for _, action := range actions { // Get expected state keys