github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/services/rpcsrv/params/types.go (about) 1 package params 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "io" 9 10 "github.com/nspcc-dev/neo-go/pkg/neorpc" 11 ) 12 13 const ( 14 // maxBatchSize is the maximum number of requests per batch. 15 maxBatchSize = 100 16 ) 17 18 // Request contains standard JSON-RPC 2.0 request and batch of 19 // requests: http://www.jsonrpc.org/specification. 20 // It's used in server to represent incoming queries. 21 type Request struct { 22 In *In 23 Batch Batch 24 } 25 26 // In represents a standard JSON-RPC 2.0 27 // request: http://www.jsonrpc.org/specification#request_object. 28 type In struct { 29 JSONRPC string `json:"jsonrpc"` 30 Method string `json:"method"` 31 RawParams []Param `json:"params,omitempty"` 32 RawID json.RawMessage `json:"id,omitempty"` 33 } 34 35 // Batch represents a standard JSON-RPC 2.0 36 // batch: https://www.jsonrpc.org/specification#batch. 37 type Batch []In 38 39 // MarshalJSON implements the json.Marshaler interface. 40 func (r Request) MarshalJSON() ([]byte, error) { 41 if r.In != nil { 42 return json.Marshal(r.In) 43 } 44 return json.Marshal(r.Batch) 45 } 46 47 // UnmarshalJSON implements the json.Unmarshaler interface. 48 func (r *Request) UnmarshalJSON(data []byte) error { 49 var ( 50 in *In 51 batch Batch 52 ) 53 in = &In{} 54 err := json.Unmarshal(data, in) 55 if err == nil { 56 r.In = in 57 return nil 58 } 59 decoder := json.NewDecoder(bytes.NewReader(data)) 60 t, err := decoder.Token() // read `[` 61 if err != nil { 62 return err 63 } 64 if t != json.Delim('[') { 65 return fmt.Errorf("`[` expected, got %s", t) 66 } 67 count := 0 68 for decoder.More() { 69 if count > maxBatchSize { 70 return fmt.Errorf("the number of requests in batch shouldn't exceed %d", maxBatchSize) 71 } 72 in = &In{} 73 decodeErr := decoder.Decode(in) 74 if decodeErr != nil { 75 return decodeErr 76 } 77 batch = append(batch, *in) 78 count++ 79 } 80 if len(batch) == 0 { 81 return errors.New("empty request") 82 } 83 r.Batch = batch 84 return nil 85 } 86 87 // DecodeData decodes the given reader into the the request 88 // struct. 89 func (r *Request) DecodeData(data io.ReadCloser) error { 90 defer data.Close() 91 92 rawData := json.RawMessage{} 93 err := json.NewDecoder(data).Decode(&rawData) 94 if err != nil { 95 return fmt.Errorf("error parsing JSON payload: %w", err) 96 } 97 98 return r.UnmarshalJSON(rawData) 99 } 100 101 // NewRequest creates a new Request struct. 102 func NewRequest() *Request { 103 return &Request{} 104 } 105 106 // NewIn creates a new In struct. 107 func NewIn() *In { 108 return &In{ 109 JSONRPC: neorpc.JSONRPCVersion, 110 } 111 }