Add EthHashStr validation

This commit is contained in:
coffeepots 2018-08-13 18:39:17 +01:00
parent d1f283b004
commit 4c38ede9c9
1 changed files with 31 additions and 2 deletions

View File

@ -13,11 +13,13 @@
type type
HexQuantityStr* = distinct string HexQuantityStr* = distinct string
HexDataStr* = distinct string HexDataStr* = distinct string
EthAddressStr* = distinct string EthAddressStr* = distinct string # Same as HexDataStr but must be less <= 20 bytes
EthHashStr* = distinct string # Same as HexDataStr but must be exactly 32 bytes
func len*(data: HexQuantityStr): int = data.string.len func len*(quantity: HexQuantityStr): int = quantity.string.len
func len*(data: HexDataStr): int = data.string.len func len*(data: HexDataStr): int = data.string.len
func len*(data: EthAddressStr): int = data.string.len func len*(data: EthAddressStr): int = data.string.len
func len*(data: EthHashStr): int = data.string.len
# Hex validation # Hex validation
@ -67,12 +69,20 @@ func isValidHexData*(value: string): bool =
func isValidEthAddress*(value: string): bool = func isValidEthAddress*(value: string): bool =
# 20 bytes for EthAddress plus "0x" # 20 bytes for EthAddress plus "0x"
# Addresses are allowed to be shorter than 20 bytes for convenience
result = value.len <= 42 and value.isValidHexData result = value.len <= 42 and value.isValidHexData
func isValidEthHash*(value: string): bool =
# 32 bytes for EthAddress plus "0x"
# Currently hashes are required to be exact lengths
# TODO: Allow shorter hashes (pad with zeros) for convenience?
result = value.len == 66 and value.isValidHexData
const const
SInvalidQuantity = "Invalid hex quantity format for Ethereum" SInvalidQuantity = "Invalid hex quantity format for Ethereum"
SInvalidData = "Invalid hex data format for Ethereum" SInvalidData = "Invalid hex data format for Ethereum"
SInvalidAddress = "Invalid address format for Ethereum" SInvalidAddress = "Invalid address format for Ethereum"
SInvalidHash = "Invalid hash format for Ethereum"
proc validateHexQuantity*(value: string) {.inline.} = proc validateHexQuantity*(value: string) {.inline.} =
if unlikely(not value.isValidHexQuantity): if unlikely(not value.isValidHexQuantity):
@ -86,6 +96,10 @@ proc validateHexAddressStr*(value: string) {.inline.} =
if unlikely(not value.isValidEthAddress): if unlikely(not value.isValidEthAddress):
raise newException(ValueError, SInvalidAddress & ": " & value) raise newException(ValueError, SInvalidAddress & ": " & value)
proc validateHashStr*(value: string) {.inline.} =
if unlikely(not value.isValidEthHash):
raise newException(ValueError, SInvalidHash & ": " & value)
# Initialisation # Initialisation
proc hexQuantityStr*(value: string): HexQuantityStr {.inline.} = proc hexQuantityStr*(value: string): HexQuantityStr {.inline.} =
@ -100,6 +114,10 @@ proc ethAddressStr*(value: string): EthAddressStr {.inline.} =
value.validateHexAddressStr value.validateHexAddressStr
result = value.EthAddressStr result = value.EthAddressStr
proc ethHashStr*(value: string): EthHashStr {.inline.} =
value.validateHashStr
result = value.EthHashStr
# Converters for use in RPC # Converters for use in RPC
import json import json
@ -114,6 +132,9 @@ proc `%`*(value: HexDataStr): JsonNode =
proc `%`*(value: EthAddressStr): JsonNode = proc `%`*(value: EthAddressStr): JsonNode =
result = %(value.string) result = %(value.string)
proc `%`*(value: EthHashStr): JsonNode =
result = %(value.string)
proc fromJson*(n: JsonNode, argName: string, result: var HexQuantityStr) = proc fromJson*(n: JsonNode, argName: string, result: var HexQuantityStr) =
# Note that '0x' is stripped after validation # Note that '0x' is stripped after validation
n.kind.expect(JString, argName) n.kind.expect(JString, argName)
@ -138,3 +159,11 @@ proc fromJson*(n: JsonNode, argName: string, result: var EthAddressStr) =
raise newException(ValueError, "Parameter \"" & argName & "\" is not valid as an Ethereum address \"" & hexStr & "\"") raise newException(ValueError, "Parameter \"" & argName & "\" is not valid as an Ethereum address \"" & hexStr & "\"")
result = hexStr.EthAddressStr result = hexStr.EthAddressStr
proc fromJson*(n: JsonNode, argName: string, result: var EthHashStr) =
# Note that '0x' is stripped after validation
n.kind.expect(JString, argName)
let hexStr = n.getStr()
if not hexStr.isValidEthHash:
raise newException(ValueError, "Parameter \"" & argName & "\" is not valid as an Ethereum hash \"" & hexStr & "\"")
result = hexStr.EthHashStr