store: read a revert with a reason as not dataless

This commit is contained in:
shum committed 2026-10-22 01:35:41 +00:00
1 parent 2992a2133c
commit 55a0ea2d18
3 files changed
+16 -3

No files matched your search

@@ -115,6 +115,9 @@ maxRpcResponseBytes = 1024 * 1024
revertCode :: Int
revertCode = 3
revertMessage :: Text
revertMessage = "execution reverted"
-- | A node's error message is cut to this many characters.
maxNodeMessageLength :: Int
maxNodeMessageLength = 200
@@ -273,10 +276,14 @@ rpc ChainClient {ccManager, ccConfig = ChainConfig {cRpcUrl}, ccTimeout} method
message <- e .: "message"
revertData <- e .:? "data"
pure $
if code == revertCode || "execution reverted" `T.isPrefixOf` message
then ChainReverted $ maybe (Just RNWithoutData) (decodeRevert <=< JT.parseMaybe bytes) revertData
if code == revertCode || revertMessage `T.isPrefixOf` message
then ChainReverted $ maybe (dataless message) (decodeRevert <=< JT.parseMaybe bytes) revertData
else unavailable $ "error " <> tshow code <> ": " <> T.take maxNodeMessageLength message
unavailable reason = ChainUnavailable $ method <> ": " <> reason
-- a node or proxy that drops the data can keep a reason in the message, as in "execution reverted: ERC721: invalid token ID"
dataless message
| message == revertMessage = Just RNWithoutData
| otherwise = Nothing
-- | Only the kind of failure, for callers: an exception's text can hold the URL or its host.
httpFailure :: HTTP.HttpException -> Text
+4 -1
View File
@@ -31,7 +31,7 @@ namesChainTests = describe "StoreService names: chain" $ do
it "reads a dry run's revert with data by its name" $ testDryRunRevertNamed g
it "reads an eth_call revert with data by its name" $ testCallRevertNamed g
it "reads ownerOf of a name nobody holds as a revert" $ testOwnerOfRevert g
it "reads a revert without code 3 or data as a revert without data" $ testRevertWithoutData g
it "reads a bare revert message without data as a revert without data, and one with a reason as unknown" $ testRevertWithoutData g
it "reads a revert of an unknown error as an unnamed revert" $ testUnknownRevert g
describe "failures" $ do
it "reads an RPC error as unavailable, without the URL" $ testRpcError g
@@ -127,6 +127,9 @@ testRevertWithoutData :: TVar ChaChaDRG -> IO ()
testRevertWithoutData g = withChain g $ \node c -> do
setFault node "eth_call" $ RpcError (-32000) "execution reverted" Nothing
ethCall c fakeController availableCall `shouldReturn` Left (ChainReverted $ Just RNWithoutData)
-- a reason kept in the message names a revert that had data, so it is not read as one without
setFault node "eth_call" $ RpcError 3 "execution reverted: ERC721: invalid token ID" Nothing
ethCall c fakeController availableCall `shouldReturn` Left (ChainReverted Nothing)
testUnknownRevert :: TVar ChaChaDRG -> IO ()
testUnknownRevert g = withChain g $ \node c -> do
@@ -184,6 +184,9 @@ testOwnerOfFailed g = withContracts g $ \node ct -> do
-- viem's encodeErrorResult of ReentrantCall()
answerCall node (registrarOf node) ownerOfCall $ Reverts $ unhex "37ed32e8"
ownerOfToken ct alice `shouldReturn` Left (ChainReverted $ Just RNReentrantCall)
-- a node or proxy that keeps the reason in the message but drops the data
setFault node "eth_call" $ RpcError (-32000) "execution reverted: ERC721: invalid token ID" Nothing
ownerOfToken ct alice `shouldReturn` Left (ChainReverted Nothing)
setFault node "eth_call" HttpFailure
ownerOfToken ct alice `shouldReturn` Left (ChainUnavailable "eth_call: HTTP 502")