github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/admin/commands/state_synchronization/execute_script.go (about) 1 package state_synchronization 2 3 import ( 4 "context" 5 "encoding/json" 6 "strconv" 7 8 "github.com/onflow/flow-go/admin" 9 "github.com/onflow/flow-go/admin/commands" 10 "github.com/onflow/flow-go/module/execution" 11 ) 12 13 var _ commands.AdminCommand = (*ReadExecutionDataCommand)(nil) 14 15 type scriptData struct { 16 height uint64 17 script []byte 18 arguments [][]byte 19 } 20 21 type ExecuteScriptCommand struct { 22 scriptExecutor execution.ScriptExecutor 23 } 24 25 func (e *ExecuteScriptCommand) Handler(ctx context.Context, req *admin.CommandRequest) (interface{}, error) { 26 d := req.ValidatorData.(*scriptData) 27 28 result, err := e.scriptExecutor.ExecuteAtBlockHeight(context.Background(), d.script, d.arguments, d.height) 29 if err != nil { 30 return nil, err 31 } 32 33 return string(result), nil 34 } 35 36 // Validator validates the request. 37 // Returns admin.InvalidAdminReqError for invalid/malformed requests. 38 func (e *ExecuteScriptCommand) Validator(req *admin.CommandRequest) error { 39 input, ok := req.Data.(map[string]interface{}) 40 if !ok { 41 return admin.NewInvalidAdminReqFormatError("expected map[string]any") 42 } 43 44 heightRaw, ok := input["height"] 45 if !ok { 46 return admin.NewInvalidAdminReqFormatError("missing required field 'height") 47 } 48 49 scriptRaw, ok := input["script"] 50 if !ok { 51 return admin.NewInvalidAdminReqFormatError("missing required field 'script") 52 } 53 54 argsRaw, ok := input["args"] 55 if !ok { 56 return admin.NewInvalidAdminReqFormatError("missing required field 'args") 57 } 58 59 heightStr, ok := heightRaw.(string) 60 if !ok { 61 return admin.NewInvalidAdminReqFormatError("'height' must be string") 62 } 63 64 height, err := strconv.ParseUint(heightStr, 10, 64) 65 if err != nil { 66 return admin.NewInvalidAdminReqFormatError("'height' must be valid uint64 value", err) 67 } 68 69 scriptStr, ok := scriptRaw.(string) 70 if !ok { 71 return admin.NewInvalidAdminReqFormatError("'script' must be string") 72 } 73 74 argsStr, ok := argsRaw.(string) 75 if !ok { 76 return admin.NewInvalidAdminReqFormatError("'args' must be string") 77 } 78 79 args := make([][]byte, 0) 80 err = json.Unmarshal([]byte(argsStr), &args) 81 if err != nil { 82 return admin.NewInvalidAdminReqFormatError("'args' not valid JSON", err) 83 } 84 85 req.ValidatorData = &scriptData{ 86 height: height, 87 script: []byte(scriptStr), 88 arguments: args, 89 } 90 91 return nil 92 } 93 94 func NewExecuteScriptCommand(scripts execution.ScriptExecutor) commands.AdminCommand { 95 return &ExecuteScriptCommand{ 96 scripts, 97 } 98 }