Skip to content

Commit 837f6f7

Browse files
Update TxReceipt API according to the RPC ethereum documentation (#148)
1 parent 622ba4e commit 837f6f7

File tree

3 files changed

+64
-23
lines changed

3 files changed

+64
-23
lines changed

packages/ethereum/src/Network/Ethereum/Account/Internal.hs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import Network.Ethereum.Account.Class (Account)
3333
import qualified Network.Ethereum.Api.Eth as Eth (getTransactionReceipt)
3434
import Network.Ethereum.Api.Types (Call (..),
3535
DefaultBlock (Latest),
36-
TxReceipt (receiptTransactionHash))
36+
TxReceipt)
3737
import Network.Ethereum.Unit (Unit (..))
3838
import Network.JsonRpc.TinyClient (JsonRpc)
3939

@@ -139,8 +139,3 @@ getReceipt mbtimeout tx = do
139139

140140
getReceipt' :: JsonRpc m => HexString -> m TxReceipt
141141
getReceipt' = fmap (fromRight undefined) . getReceipt Nothing
142-
143-
updateReceipt :: JsonRpc m => TxReceipt -> m TxReceipt
144-
{-# INLINE updateReceipt #-}
145-
-- No timeout, because we update the receipt of an already processed transaction.
146-
updateReceipt = getReceipt' . receiptTransactionHash

packages/ethereum/src/Network/Ethereum/Account/Safe.hs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import Control.Monad.Trans (lift)
2020
import Data.ByteArray.HexString (HexString)
2121

2222
import Network.Ethereum.Account.Class (Account (send))
23-
import Network.Ethereum.Account.Internal (updateReceipt)
2423
import qualified Network.Ethereum.Api.Eth as Eth
2524
import Network.Ethereum.Api.Types (TxReceipt (receiptBlockNumber))
2625
import Network.Ethereum.Contract.Method (Method)
@@ -42,17 +41,12 @@ safeSend b a = lift . withReceipt waiting =<< send a
4241
Left tx -> return $ Left tx
4342
Right receipt -> Right <$> f receipt
4443

45-
waiting receipt =
46-
case receiptBlockNumber receipt of
47-
Nothing -> do
48-
liftIO $ threadDelay 1000000
49-
waiting =<< updateReceipt receipt
50-
Just bn -> do
51-
current <- Eth.blockNumber
52-
if current - bn >= fromInteger b
53-
then return receipt
54-
else do liftIO $ threadDelay 1000000
55-
waiting receipt
44+
waiting receipt = do
45+
current <- Eth.blockNumber
46+
if current - receiptBlockNumber receipt >= fromInteger b
47+
then return receipt
48+
else do liftIO $ threadDelay 1000000
49+
waiting receipt
5650

5751
-- | Count block confirmation to keep secure
5852
-- According to Vitalik post

packages/ethereum/src/Network/Ethereum/Api/Types.hs

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import qualified Data.Text as T (pack)
3232
import qualified Data.Text.Lazy.Builder as B (toLazyText)
3333
import qualified Data.Text.Lazy.Builder.Int as B (hexadecimal)
3434
import qualified Data.Text.Read as R (decimal, hexadecimal)
35+
import Data.Word (Word8)
3536
import GHC.Generics (Generic)
3637
import Lens.Micro (_head, over)
3738

@@ -74,6 +75,43 @@ instance FromJSON Quantity where
7475
_ -> fail $ "Quantity " ++ show v <> " is not valid hex"
7576
parseJSON _ = fail "Quantity should be a JSON String"
7677

78+
-- | Type representing a Byte in Web3 JSON RPC docs ("#/components/schemas/byte")
79+
--
80+
-- The encoding is similar to Quantity, encoding as hex string.
81+
newtype Byte = Byte { unByte :: Word8 }
82+
deriving (Num, Real, Integral, Enum, Eq, Ord, Generic)
83+
84+
instance Show Byte where
85+
show = show . unByte
86+
87+
instance IsString Byte where
88+
fromString ('0' : 'x' : hex) =
89+
case R.hexadecimal (T.pack hex) of
90+
Right (x, "")
91+
| toInteger (minBound :: Word8) <= x && x <= toInteger (maxBound :: Word8) -> Byte (fromInteger x)
92+
| otherwise -> error ("Byte " ++ show hex ++ "is not within bounds")
93+
_ -> error ("Byte " ++ show hex ++ " is not valid hex")
94+
95+
fromString num =
96+
case R.decimal (T.pack num) of
97+
Right (x, "")
98+
| toInteger (minBound :: Word8) <= x && x <= toInteger (maxBound :: Word8) -> Byte (fromInteger x)
99+
| otherwise -> error ("Byte " ++ show num ++ "is not within bounds")
100+
_ -> error ("Byte " ++ show num ++ " is not valid decimal")
101+
102+
instance ToJSON Byte where
103+
toJSON (Byte x) =
104+
let hexValue = B.toLazyText (B.hexadecimal x)
105+
in toJSON ("0x" <> hexValue)
106+
107+
instance FromJSON Byte where
108+
parseJSON (String v) =
109+
case R.hexadecimal v of
110+
Right (x, "") -> return (Byte x)
111+
_ -> fail $ "Byte " ++ show v <> " is not valid hex"
112+
parseJSON _ = fail "Byte should be a JSON String"
113+
114+
77115
-- | An object with sync status data.
78116
data SyncActive = SyncActive
79117
{ syncStartingBlock :: !Quantity
@@ -194,26 +232,40 @@ instance Ord DefaultBlock where
194232

195233
-- | The Receipt of a Transaction
196234
data TxReceipt = TxReceipt
197-
{ receiptTransactionHash :: !HexString
235+
{ receiptType :: !(Maybe Byte)
236+
-- ^ BYTE - type of the transaction 0x00 for legacy transactions, 0x01 EIP-2930, 0x02 EIP-1559
237+
, receiptTransactionHash :: !HexString
198238
-- ^ DATA, 32 Bytes - hash of the transaction.
199239
, receiptTransactionIndex :: !Quantity
200240
-- ^ QUANTITY - index of the transaction.
201-
, receiptBlockHash :: !(Maybe HexString)
202-
-- ^ DATA, 32 Bytes - hash of the block where this transaction was in. null when its pending.
203-
, receiptBlockNumber :: !(Maybe Quantity)
204-
-- ^ QUANTITY - block number where this transaction was in. null when its pending.
241+
, receiptBlockHash :: !HexString
242+
-- ^ DATA, 32 Bytes - hash of the block where this transaction was in.
243+
, receiptBlockNumber :: !Quantity
244+
-- ^ QUANTITY - block number where this transaction was in.
245+
, receiptFrom :: !Address
246+
-- ^ DATA, 20 Bytes - the address of the sender
247+
, receiptTo :: !(Maybe Address)
248+
-- ^ DATA, 20 Bytes - The address of the receiver. null when the transaction is a contract creation transaction.
205249
, receiptCumulativeGasUsed :: !Quantity
206250
-- ^ QUANTITY - The total amount of gas used when this transaction was executed in the block.
207251
, receiptGasUsed :: !Quantity
208252
-- ^ QUANTITY - The amount of gas used by this specific transaction alone.
253+
, receiptBlobGasUsed :: !(Maybe Quantity)
254+
-- ^ QUANTITY - The amount of blob gas used for this specific transaction. Only specified for blob transactions as defined by EIP-4844.
209255
, receiptContractAddress :: !(Maybe Address)
210256
-- ^ DATA, 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise null.
211257
, receiptLogs :: ![Change]
212258
-- ^ Array - Array of log objects, which this transaction generated.
213259
, receiptLogsBloom :: !HexString
214260
-- ^ DATA, 256 Bytes - Bloom filter for light clients to quickly retrieve related logs.
261+
, receiptRoot :: !(Maybe HexString)
262+
-- ^ DATA, 32 Bytes - The post-transaction state root. Only specified for transactions included before the Byzantium upgrade.
215263
, receiptStatus :: !(Maybe Quantity)
216264
-- ^ QUANTITY either 1 (success) or 0 (failure)
265+
, receiptEffectiveGasPrice :: !Quantity
266+
-- ^ QUANTITY - The actual value per gas deducted from the sender's account. Before EIP-1559, this is equal to the transaction's gas price. After, it is equal to baseFeePerGas + min(maxFeePerGas - baseFeePerGas, maxPriorityFeePerGas).
267+
, blobGasPrice :: !(Maybe Quantity)
268+
-- ^ QUANTITY - The actual value per gas deducted from the sender's account for blob gas. Only specified for blob transactions as defined by EIP-4844.
217269
}
218270
deriving (Show, Generic)
219271

0 commit comments

Comments
 (0)