diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..26c9e8f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +jsonrpc/openrpc.json +jsonrpc/node_modules diff --git a/history/history-network.md b/history/history-network.md index d9c0c291..bd5d3b4d 100644 --- a/history/history-network.md +++ b/history/history-network.md @@ -202,6 +202,7 @@ as there is the `BlockProofHistoricalHashesAccumulator` solution available. For post-merge until Capella headers, clients SHOULD NOT accept headers without a proof as there is the `BlockProofHistoricalRoots` solution available. For Capella and onwards headers, clients SHOULD NOT accept headers without a proof as there is the `BlockProofHistoricalSummaries` solution available. For headers that are not yet part of the last period, clients SHOULD + accept headers without a proof. ##### Block Header by Hash diff --git a/jsonrpc/scripts/build.js b/jsonrpc/scripts/build.js index 6f17c8c1..3677f8da 100644 --- a/jsonrpc/scripts/build.js +++ b/jsonrpc/scripts/build.js @@ -43,6 +43,19 @@ contentFiles.forEach(file => { }; }); +let errors = {}; +let errorBase = "src/errors/" +let errorFiles = fs.readdirSync(errorBase) +errorFiles.forEach(file => { + console.log(file); + let raw = fs.readFileSync(errorBase + file); + let parsed = JSON.parse(raw); + errors = { + ...errors, + ...parsed, + }; +}); + let spec = await parseOpenRPCDocument({ openrpc: "1.2.4", info: { @@ -57,7 +70,8 @@ let spec = await parseOpenRPCDocument({ methods: methods, components: { contentDescriptors: content, - schemas: schemas + schemas: schemas, + errors: errors } }, {dereference: false}) diff --git a/jsonrpc/scripts/debug.sh b/jsonrpc/scripts/debug.sh index 7e4d76b6..7cdd5387 100755 --- a/jsonrpc/scripts/debug.sh +++ b/jsonrpc/scripts/debug.sh @@ -2,6 +2,6 @@ set -o xtrace curl -s http://localhost:8545 -H 'Content-Type: application/json' -d '{"method":"'$1'","id":1,"jsonrpc":"2.0", "params":['$2']}' | jq '.["result"]' > data.json 2>&1 -cat openrpc.json | jq '.["methods"][] | select(.name == "'$1'") | .["result"]["schema"]' > schema.json +cat openrpc.json | jq '.["methods"][] | select(.name == "'$1'") | .["result"]["schema"]["errors"]' > schema.json ajv validate -s schema.json -d data.json # rm schema.json data.json diff --git a/jsonrpc/src/content/params.json b/jsonrpc/src/content/params.json index 0e9d6b3c..59176d66 100644 --- a/jsonrpc/src/content/params.json +++ b/jsonrpc/src/content/params.json @@ -43,6 +43,19 @@ } } }, + "ContentItems": { + "name": "content_items", + "required": true, + "schema": { + "title": "content_item", + "type": "array", + "items": { + "$ref": "#/components/schemas/ContentItem" + }, + "minItems": 1, + "maxItems": 64 + } + }, "Enr": { "name": "enr", "required": true, diff --git a/jsonrpc/src/content/results.json b/jsonrpc/src/content/results.json index 21035be8..8e511a3b 100644 --- a/jsonrpc/src/content/results.json +++ b/jsonrpc/src/content/results.json @@ -34,7 +34,7 @@ "schema": { "title": "FindContentResult", "type": "object", - "oneOf" :[ + "oneOf": [ { "title": "ContentInfo", "type": "object", @@ -58,7 +58,9 @@ "title": "ENRs", "description": "List of ENR records of nodes that are closer than the recipient is to the requested content", "type": "object", - "required": ["enrs"], + "required": [ + "enrs" + ], "properties": { "enrs": { "type": "array", @@ -164,8 +166,8 @@ } } }, - "RecursiveFindContentResult": { - "name": "RecursiveFindContentResult", + "GetContentResult": { + "name": "GetContentResult", "description": "Returns the hex encoded content value and utp transfer flag. If the content is not available, returns \"0x\"", "schema": { "type": "object", @@ -185,8 +187,8 @@ } } }, - "TraceRecursiveFindContentResult": { - "name": "TraceRecursiveFindContentResult", + "TraceGetContentResult": { + "name": "TraceGetContentResult", "description": "Returns the hex encoded content value and trace data object. If the content is not available, returns \"0x\"", "schema": { "type": "object", @@ -213,7 +215,7 @@ }, "LocalContentResult": { "name": "LocalContentResult", - "description": "Returns the hex encoded content value. If the content is not available, returns \"0x\"", + "description": "Returns the hex encoded content value.", "schema": { "$ref": "#/components/schemas/hexString" } diff --git a/jsonrpc/src/errors/errors.json b/jsonrpc/src/errors/errors.json new file mode 100644 index 00000000..063cab89 --- /dev/null +++ b/jsonrpc/src/errors/errors.json @@ -0,0 +1,13 @@ +{ + "ContentNotFoundError": { + "code": -39001, + "message": "content not found" + }, + "ContentNotFoundErrorWithTrace": { + "code": -39002, + "message": "content not found", + "data": { + "$ref": "#/components/schemas/traceResultObject" + } + } +} diff --git a/jsonrpc/src/methods/beacon.json b/jsonrpc/src/methods/beacon.json index 1dae6869..f423f2d9 100644 --- a/jsonrpc/src/methods/beacon.json +++ b/jsonrpc/src/methods/beacon.json @@ -99,16 +99,13 @@ }, { "name": "portal_beaconOffer", - "summary": "Send an OFFER request with given ContentKey, to the designated peer and wait for a response.", + "summary": "Send an OFFER request with given array of content items (keys & values), to the designated peer and wait for a response. The client MUST return an error if more than 64 content items are provided or less than 1 content items are provided.", "params": [ { "$ref": "#/components/contentDescriptors/Enr" }, { - "$ref": "#/components/contentDescriptors/ContentKey" - }, - { - "$ref": "#/components/contentDescriptors/ContentValue" + "$ref": "#/components/contentDescriptors/ContentItems" } ], "result": { @@ -136,28 +133,34 @@ } }, { - "name": "portal_beaconRecursiveFindContent", - "summary": "Look up a target content key in the network", + "name": "portal_beaconGetContent", + "summary": "Get content from the local database if it exists, otherwise look up the target content key in the network. After fetching from the network the content is validated and stored in the local database if storage criteria is met before being returned.", "params": [ { "$ref": "#/components/contentDescriptors/ContentKey" } ], "result": { - "$ref": "#/components/contentDescriptors/RecursiveFindContentResult" - } + "$ref": "#/components/contentDescriptors/GetContentResult" + }, + "errors":[{ + "$ref": "#/components/errors/ContentNotFoundError" + }] }, { - "name": "portal_beaconTraceRecursiveFindContent", - "summary": "Look up a target content key in the network and get tracing data", + "name": "portal_beaconTraceGetContent", + "summary": "Get content as defined in portal_beaconGetContent and get additional tracing data", "params": [ { "$ref": "#/components/contentDescriptors/ContentKey" } ], "result": { - "$ref": "#/components/contentDescriptors/TraceRecursiveFindContentResult" - } + "$ref": "#/components/contentDescriptors/TraceGetContentResult" + }, + "errors":[{ + "$ref": "#/components/errors/ContentNotFoundErrorWithTrace" + }] }, { "name": "portal_beaconStore", @@ -184,7 +187,10 @@ ], "result": { "$ref": "#/components/contentDescriptors/LocalContentResult" - } + }, + "errors":[{ + "$ref": "#/components/errors/ContentNotFoundError" + }] }, { "name": "portal_beaconGossip", diff --git a/jsonrpc/src/methods/history.json b/jsonrpc/src/methods/history.json index e94d8abe..165d6743 100644 --- a/jsonrpc/src/methods/history.json +++ b/jsonrpc/src/methods/history.json @@ -99,16 +99,13 @@ }, { "name": "portal_historyOffer", - "summary": "Send an OFFER request with given ContentKey, to the designated peer and wait for a response.", + "summary": "Send an OFFER request with given array of content items (keys & values), to the designated peer and wait for a response. The client MUST return an error if more than 64 content items are provided or less than 1 content items are provided.", "params": [ { "$ref": "#/components/contentDescriptors/Enr" }, { - "$ref": "#/components/contentDescriptors/ContentKey" - }, - { - "$ref": "#/components/contentDescriptors/ContentValue" + "$ref": "#/components/contentDescriptors/ContentItems" } ], "result": { @@ -128,28 +125,34 @@ } }, { - "name": "portal_historyRecursiveFindContent", - "summary": "Look up a target content key in the network", + "name": "portal_historyGetContent", + "summary": "Get content from the local database if it exists, otherwise look up the target content key in the network. After fetching from the network the content is validated and stored in the local database if storage criteria is met before being returned.", "params": [ { "$ref": "#/components/contentDescriptors/ContentKey" } ], "result": { - "$ref": "#/components/contentDescriptors/RecursiveFindContentResult" - } + "$ref": "#/components/contentDescriptors/GetContentResult" + }, + "errors":[{ + "$ref": "#/components/errors/ContentNotFoundError" + }] }, { - "name": "portal_historyTraceRecursiveFindContent", - "summary": "Look up a target content key in the network and get tracing data", + "name": "portal_historyTraceGetContent", + "summary": "Get content as defined in portal_historyGetContent and get additional tracing data", "params": [ { "$ref": "#/components/contentDescriptors/ContentKey" } ], "result": { - "$ref": "#/components/contentDescriptors/TraceRecursiveFindContentResult" - } + "$ref": "#/components/contentDescriptors/TraceGetContentResult" + }, + "errors":[{ + "$ref": "#/components/errors/ContentNotFoundErrorWithTrace" + }] }, { "name": "portal_historyStore", @@ -176,7 +179,10 @@ ], "result": { "$ref": "#/components/contentDescriptors/LocalContentResult" - } + }, + "errors":[{ + "$ref": "#/components/errors/ContentNotFoundError" + }] }, { "name": "portal_historyGossip", diff --git a/jsonrpc/src/methods/state.json b/jsonrpc/src/methods/state.json index 166275e7..1ffe1585 100644 --- a/jsonrpc/src/methods/state.json +++ b/jsonrpc/src/methods/state.json @@ -99,16 +99,13 @@ }, { "name": "portal_stateOffer", - "summary": "Send an OFFER request with given ContentKey, to the designated peer and wait for a response.", + "summary": "Send an OFFER request with given array of content items (keys & values), to the designated peer and wait for a response. The client MUST return an error if more than 64 content items are provided or less than 1 content items are provided.", "params": [ { "$ref": "#/components/contentDescriptors/Enr" }, { - "$ref": "#/components/contentDescriptors/ContentKey" - }, - { - "$ref": "#/components/contentDescriptors/ContentValue" + "$ref": "#/components/contentDescriptors/ContentItems" } ], "result": { @@ -128,16 +125,34 @@ } }, { - "name": "portal_stateRecursiveFindContent", - "summary": "Look up a target content key in the network", + "name": "portal_stateGetContent", + "summary": "Get content from the local database if it exists, otherwise look up the target content key in the network. After fetching from the network the content is validated and stored in the local database if storage criteria is met before being returned.", "params": [ { "$ref": "#/components/contentDescriptors/ContentKey" } ], "result": { - "$ref": "#/components/contentDescriptors/RecursiveFindContentResult" - } + "$ref": "#/components/contentDescriptors/GetContentResult" + }, + "errors":[{ + "$ref": "#/components/errors/ContentNotFoundError" + }] + }, + { + "name": "portal_stateTraceGetContent", + "summary": "Get content as defined in portal_stateGetContent and get additional tracing data", + "params": [ + { + "$ref": "#/components/contentDescriptors/ContentKey" + } + ], + "result": { + "$ref": "#/components/contentDescriptors/TraceGetContentResult" + }, + "errors":[{ + "$ref": "#/components/errors/ContentNotFoundErrorWithTrace" + }] }, { "name": "portal_stateStore", @@ -164,7 +179,10 @@ ], "result": { "$ref": "#/components/contentDescriptors/LocalContentResult" - } + }, + "errors":[{ + "$ref": "#/components/errors/ContentNotFoundError" + }] }, { "name": "portal_stateGossip", diff --git a/jsonrpc/src/schemas/portal.json b/jsonrpc/src/schemas/portal.json index 8103a2c4..7b08401d 100644 --- a/jsonrpc/src/schemas/portal.json +++ b/jsonrpc/src/schemas/portal.json @@ -38,5 +38,24 @@ "title": "UDP port number", "type": "string", "pattern": "^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$" + }, + "ContentItem": { + "title": "content_item", + "type": "array", + "items": [ + { + "title": "Content key", + "description": "The encoded Portal content key", + "$ref": "#/components/schemas/hexString" + }, + { + "title": "Content value", + "description": "The encoded Portal content value", + "$ref": "#/components/schemas/hexString" + } + ], + "minItems": 2, + "maxItems": 2, + "additionalItems": false } }