Skip to content

Commit 1d94582

Browse files
authored
Portal bridge: Fix crash when JSON-RPC methods not available (#3785)
Remove overly aggressive use of raiseAssert in error parsing and rework a bit. Also move a spammy info log to debug.
1 parent 109e4a6 commit 1d94582

File tree

4 files changed

+43
-39
lines changed

4 files changed

+43
-39
lines changed

execution_chain/portal/portal.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ proc getBlockBodyByHeader*(historyExpiry: HistoryExpiryRef, header: Header): Res
9191
return err("Portal RPC is not available")
9292

9393
(waitFor rpc.historyGetBlockBody(header)).mapErr(
94-
proc(e: PortalRpcError): string =
95-
debug "Portal request failed", error = $e
96-
"Portal request failed: " & $e
94+
proc(e: PortalErrorResponse): string =
95+
debug "Portal request failed", error = $e.message
96+
"Portal request failed: " & $e.message
9797
)

portal/bridge/history/portal_history_bridge.nim

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,14 @@ proc runBackfillLoopSyncMode(
181181

182182
block bodyBlock:
183183
let _ = (await historyGetBlockBody(bridge.portalClient, blockTuple.header)).valueOr:
184-
info "Failed to find block body content, gossiping..", error = $error
184+
debug "Failed to find block body content, gossiping..", error = $error.message
185185
await bridge.gossipBlockBody(blockNumber, blockTuple.body)
186186
break bodyBlock
187187

188188
block receiptsBlock:
189189
let _ = (await historyGetReceipts(bridge.portalClient, blockTuple.header)).valueOr:
190-
info "Failed to find block receipts content, gossiping..", error = $error
190+
debug "Failed to find block receipts content, gossiping..",
191+
error = $error.message
191192
await bridge.gossipReceipts(
192193
blockNumber, blockTuple.receipts.to(StoredReceipts)
193194
)

portal/rpc/portal_rpc_client.nim

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
66
# at your option. This file may not be copied, modified, or distributed except according to those terms.
77

8+
{.push raises: [].}
9+
810
import
911
json_serialization,
1012
chronos,
@@ -14,41 +16,32 @@ import
1416
json_rpc/rpcclient,
1517
../common/common_types,
1618
../network/history/[history_content, history_validation],
17-
./rpc_calls/[rpc_discovery_calls, rpc_portal_calls, rpc_portal_debug_calls]
19+
./rpc_calls/[rpc_discovery_calls, rpc_portal_calls, rpc_portal_debug_calls],
20+
./rpc_types
1821

19-
export rpcclient, rpc_discovery_calls, rpc_portal_calls, rpc_portal_debug_calls, results
22+
export
23+
rpcclient, rpc_discovery_calls, rpc_portal_calls, rpc_portal_debug_calls, results,
24+
rpc_types
2025

2126
type
2227
PortalRpcClient* = distinct RpcClient
2328

24-
PortalRpcError* = enum
25-
ContentNotFound
26-
InvalidContentKey
27-
InvalidContentValue
28-
ContentValidationFailed
29-
30-
ErrorResponse = object
29+
PortalErrorResponse* = object
3130
code*: int
3231
message*: string
3332

33+
const
34+
InvalidJsonRpcError* = -1
35+
ReceivedInvalidDataError* = -2
36+
3437
proc init*(T: type PortalRpcClient, rpcClient: RpcClient): T =
3538
T(rpcClient)
3639

37-
func toPortalRpcError(e: ref CatchableError): PortalRpcError =
38-
let error =
39-
try:
40-
Json.decode(e.msg, ErrorResponse)
41-
except SerializationError as e:
42-
raiseAssert(e.msg)
43-
44-
if error.code == -39001:
45-
ContentNotFound
46-
elif error.code == -32602:
47-
InvalidContentKey
48-
elif error.code == -32603:
49-
ContentValidationFailed
50-
else:
51-
raiseAssert(e.msg)
40+
func toPortalRpcError*(error: string): PortalErrorResponse =
41+
try:
42+
Json.decode(error, PortalErrorResponse)
43+
except SerializationError as e:
44+
PortalErrorResponse(code: InvalidJsonRpcError, message: error)
5245

5346
template toBytes(content: string): seq[byte] =
5447
try:
@@ -58,7 +51,7 @@ template toBytes(content: string): seq[byte] =
5851

5952
proc historyGetBlockBody*(
6053
client: PortalRpcClient, header: Header
61-
): Future[Result[BlockBody, PortalRpcError]] {.async: (raises: []).} =
54+
): Future[Result[BlockBody, PortalErrorResponse]] {.async: (raises: []).} =
6255
## Fetches the block body for the given block header from the Portal History
6356
## Network. The data is first looked up in the node's local database before
6457
## trying to fetch it from the network. The block header needs to be passed
@@ -69,15 +62,20 @@ proc historyGetBlockBody*(
6962
try:
7063
await RpcClient(client).portal_historyGetBlockBody(headerBytes)
7164
except CatchableError as e:
72-
return err(e.toPortalRpcError())
65+
return err(e.msg.toPortalRpcError())
7366
blockBody = decodeRlp(content.toBytes(), BlockBody).valueOr:
74-
return err(InvalidContentValue)
67+
return err(
68+
PortalErrorResponse(
69+
code: ReceivedInvalidDataError,
70+
message: "Failed to decode received BlockBody: " & error,
71+
)
72+
)
7573

7674
ok(blockBody)
7775

7876
proc historyGetReceipts*(
7977
client: PortalRpcClient, header: Header
80-
): Future[Result[StoredReceipts, PortalRpcError]] {.async: (raises: []).} =
78+
): Future[Result[StoredReceipts, PortalErrorResponse]] {.async: (raises: []).} =
8179
## Fetches the receipts for the given block header from the Portal History
8280
## Network. The data is first looked up in the node's local database before
8381
## trying to fetch it from the network. The block header needs to be passed
@@ -88,8 +86,13 @@ proc historyGetReceipts*(
8886
try:
8987
await RpcClient(client).portal_historyGetReceipts(headerBytes)
9088
except CatchableError as e:
91-
return err(e.toPortalRpcError())
89+
return err(e.msg.toPortalRpcError())
9290
receipts = decodeRlp(content.toBytes(), StoredReceipts).valueOr:
93-
return err(InvalidContentValue)
91+
return err(
92+
PortalErrorResponse(
93+
code: ReceivedInvalidDataError,
94+
message: "Failed to decode received StoredReceipts: " & error,
95+
)
96+
)
9497

9598
ok(receipts)

portal/tests/rpc_tests/test_portal_rpc_client.nim

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ procSuite "Portal RPC Client":
127127
let blockBodyRes = await tc.client.historyGetBlockBody(blockHeader)
128128
check:
129129
blockBodyRes.isErr()
130-
blockBodyRes.error() == ContentNotFound
130+
blockBodyRes.error().code == ContentNotFoundError.code
131131

132132
# Test content validation failed
133133
block:
@@ -136,7 +136,7 @@ procSuite "Portal RPC Client":
136136
let blockBodyRes = await tc.client.historyGetBlockBody(blockHeader)
137137
check:
138138
blockBodyRes.isErr()
139-
blockBodyRes.error() == ContentNotFound
139+
blockBodyRes.error().code == ContentNotFoundError.code
140140

141141
# When local node has the content the validation is skipped
142142
block:
@@ -160,7 +160,7 @@ procSuite "Portal RPC Client":
160160
let receiptsRes = await tc.client.historyGetReceipts(blockHeader)
161161
check:
162162
receiptsRes.isErr()
163-
receiptsRes.error() == ContentNotFound
163+
receiptsRes.error().code == ContentNotFoundError.code
164164

165165
# Test content validation failed
166166
block:
@@ -169,7 +169,7 @@ procSuite "Portal RPC Client":
169169
let receiptsRes = await tc.client.historyGetReceipts(blockHeader)
170170
check:
171171
receiptsRes.isErr()
172-
receiptsRes.error() == ContentNotFound
172+
receiptsRes.error().code == ContentNotFoundError.code
173173

174174
# When local node has the content the validation is skipped
175175
block:

0 commit comments

Comments
 (0)