Use directly the Whisper types instead of distinct strings, we test for string in fromJson anyhow
This commit is contained in:
parent
1df3c7202b
commit
ce523550c0
|
@ -36,14 +36,9 @@ type
|
||||||
HexDataStr* = distinct string
|
HexDataStr* = distinct string
|
||||||
EthAddressStr* = distinct string # Same as HexDataStr but must be less <= 20 bytes
|
EthAddressStr* = distinct string # Same as HexDataStr but must be less <= 20 bytes
|
||||||
EthHashStr* = distinct string # Same as HexDataStr but must be exactly 32 bytes
|
EthHashStr* = distinct string # Same as HexDataStr but must be exactly 32 bytes
|
||||||
IdentifierStr* = distinct string # 32 bytes, no 0x prefix!
|
Identifier* = distinct string # 32 bytes, no 0x prefix!
|
||||||
PublicKeyStr* = distinct string # 0x prefix + 65 bytes
|
|
||||||
PrivateKeyStr* = distinct string # 0x prefix + 32 bytes
|
|
||||||
SymKeyStr* = distinct string # 0x prefix + 32 bytes
|
|
||||||
TopicStr* = distinct string # 0x prefix + 4 bytes
|
|
||||||
HexStrings = HexQuantityStr | HexDataStr | EthAddressStr | EthHashStr |
|
HexStrings = HexQuantityStr | HexDataStr | EthAddressStr | EthHashStr |
|
||||||
IdentifierStr | PublicKeyStr | PrivateKeyStr | SymKeyStr |
|
Identifier
|
||||||
TopicStr
|
|
||||||
|
|
||||||
template len*(value: HexStrings): int = value.string.len
|
template len*(value: HexStrings): int = value.string.len
|
||||||
|
|
||||||
|
@ -136,11 +131,6 @@ const
|
||||||
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"
|
SInvalidHash = "Invalid hash format for Ethereum"
|
||||||
SInvalidIdentifier = "Invalid format for identifier"
|
|
||||||
SInvalidPublicKey = "Invalid format for public key"
|
|
||||||
SInvalidPrivateKey = "Invalid format for private key"
|
|
||||||
SInvalidSymKey = "Invalid format for symmetric key"
|
|
||||||
SInvalidTopic = "Invalid format for topic"
|
|
||||||
|
|
||||||
proc validateHexQuantity*(value: string) {.inline.} =
|
proc validateHexQuantity*(value: string) {.inline.} =
|
||||||
if unlikely(not value.isValidHexQuantity):
|
if unlikely(not value.isValidHexQuantity):
|
||||||
|
@ -217,6 +207,21 @@ proc `%`*(value: whisper_protocol.Topic): JsonNode =
|
||||||
proc `%`*(value: Bytes): JsonNode =
|
proc `%`*(value: Bytes): JsonNode =
|
||||||
result = %("0x" & value.toHex)
|
result = %("0x" & value.toHex)
|
||||||
|
|
||||||
|
|
||||||
|
# Helpers for the fromJson procs
|
||||||
|
|
||||||
|
proc toPublicKey*(key: string): PublicKey {.inline.} =
|
||||||
|
result = initPublicKey(key[4 .. ^1])
|
||||||
|
|
||||||
|
proc toPrivateKey*(key: string): PrivateKey {.inline.} =
|
||||||
|
result = initPrivateKey(key[2 .. ^1])
|
||||||
|
|
||||||
|
proc toSymKey*(key: string): SymKey {.inline.} =
|
||||||
|
hexToByteArray(key[2 .. ^1], result)
|
||||||
|
|
||||||
|
proc toTopic*(topic: string): whisper_protocol.Topic {.inline.} =
|
||||||
|
hexToByteArray(topic[2 .. ^1], result)
|
||||||
|
|
||||||
# Marshalling from JSON to Nim types that includes format checking
|
# Marshalling from JSON to Nim types that includes format checking
|
||||||
|
|
||||||
func invalidMsg(name: string): string = "When marshalling from JSON, parameter \"" & name & "\" is not valid"
|
func invalidMsg(name: string): string = "When marshalling from JSON, parameter \"" & name & "\" is not valid"
|
||||||
|
@ -249,12 +254,12 @@ proc fromJson*(n: JsonNode, argName: string, result: var EthHashStr) =
|
||||||
raise newException(ValueError, invalidMsg(argName) & " as an Ethereum hash \"" & hexStr & "\"")
|
raise newException(ValueError, invalidMsg(argName) & " as an Ethereum hash \"" & hexStr & "\"")
|
||||||
result = hexStr.EthHashStr
|
result = hexStr.EthHashStr
|
||||||
|
|
||||||
proc fromJson*(n: JsonNode, argName: string, result: var IdentifierStr) =
|
proc fromJson*(n: JsonNode, argName: string, result: var Identifier) =
|
||||||
n.kind.expect(JString, argName)
|
n.kind.expect(JString, argName)
|
||||||
let hexStr = n.getStr()
|
let hexStr = n.getStr()
|
||||||
if not hexStr.isValidIdentifier:
|
if not hexStr.isValidIdentifier:
|
||||||
raise newException(ValueError, invalidMsg(argName) & " as a identifier \"" & hexStr & "\"")
|
raise newException(ValueError, invalidMsg(argName) & " as a identifier \"" & hexStr & "\"")
|
||||||
result = hexStr.IdentifierStr
|
result = hexStr.Identifier
|
||||||
|
|
||||||
proc fromJson*(n: JsonNode, argName: string, result: var UInt256) =
|
proc fromJson*(n: JsonNode, argName: string, result: var UInt256) =
|
||||||
n.kind.expect(JString, argName)
|
n.kind.expect(JString, argName)
|
||||||
|
@ -263,44 +268,37 @@ proc fromJson*(n: JsonNode, argName: string, result: var UInt256) =
|
||||||
raise newException(ValueError, invalidMsg(argName) & " as a UInt256 \"" & hexStr & "\"")
|
raise newException(ValueError, invalidMsg(argName) & " as a UInt256 \"" & hexStr & "\"")
|
||||||
result = readUintBE[256](hexToPaddedByteArray[32](hexStr))
|
result = readUintBE[256](hexToPaddedByteArray[32](hexStr))
|
||||||
|
|
||||||
proc fromJson*(n: JsonNode, argName: string, result: var PublicKeyStr) =
|
proc fromJson*(n: JsonNode, argName: string, result: var PublicKey) =
|
||||||
n.kind.expect(JString, argName)
|
n.kind.expect(JString, argName)
|
||||||
let hexStr = n.getStr()
|
let hexStr = n.getStr()
|
||||||
if not hexStr.isValidPublicKey:
|
if not hexStr.isValidPublicKey:
|
||||||
raise newException(ValueError, invalidMsg(argName) & " as a public key \"" & hexStr & "\"")
|
raise newException(ValueError, invalidMsg(argName) & " as a public key \"" & hexStr & "\"")
|
||||||
result = hexStr.PublicKeyStr
|
result = hexStr.toPublicKey
|
||||||
|
|
||||||
proc fromJson*(n: JsonNode, argName: string, result: var PrivateKeyStr) =
|
proc fromJson*(n: JsonNode, argName: string, result: var PrivateKey) =
|
||||||
n.kind.expect(JString, argName)
|
n.kind.expect(JString, argName)
|
||||||
let hexStr = n.getStr()
|
let hexStr = n.getStr()
|
||||||
if not hexStr.isValidPrivateKey:
|
if not hexStr.isValidPrivateKey:
|
||||||
raise newException(ValueError, invalidMsg(argName) & " as a private key \"" & hexStr & "\"")
|
raise newException(ValueError, invalidMsg(argName) & " as a private key \"" & hexStr & "\"")
|
||||||
result = hexStr.PrivateKeyStr
|
result = hexStr.toPrivateKey
|
||||||
|
|
||||||
proc fromJson*(n: JsonNode, argName: string, result: var SymKeyStr) =
|
proc fromJson*(n: JsonNode, argName: string, result: var SymKey) =
|
||||||
n.kind.expect(JString, argName)
|
n.kind.expect(JString, argName)
|
||||||
let hexStr = n.getStr()
|
let hexStr = n.getStr()
|
||||||
if not hexStr.isValidSymKey:
|
if not hexStr.isValidSymKey:
|
||||||
raise newException(ValueError, invalidMsg(argName) & " as a symmetric key \"" & hexStr & "\"")
|
raise newException(ValueError, invalidMsg(argName) & " as a symmetric key \"" & hexStr & "\"")
|
||||||
result = hexStr.SymKeyStr
|
result = toSymKey(hexStr)
|
||||||
|
|
||||||
proc fromJson*(n: JsonNode, argName: string, result: var TopicStr) =
|
|
||||||
n.kind.expect(JString, argName)
|
|
||||||
let hexStr = n.getStr()
|
|
||||||
if not hexStr.isValidTopic:
|
|
||||||
raise newException(ValueError, invalidMsg(argName) & " as a topic \"" & hexStr & "\"")
|
|
||||||
result = hexStr.TopicStr
|
|
||||||
|
|
||||||
# Following procs currently required only for testing, the `createRpcSigs` macro
|
|
||||||
# requires it as it will convert the JSON results back to the original Nim
|
|
||||||
# types, but it needs the `fromJson` calls for those specific Nim types to do so
|
|
||||||
proc fromJson*(n: JsonNode, argName: string, result: var whisper_protocol.Topic) =
|
proc fromJson*(n: JsonNode, argName: string, result: var whisper_protocol.Topic) =
|
||||||
n.kind.expect(JString, argName)
|
n.kind.expect(JString, argName)
|
||||||
let hexStr = n.getStr()
|
let hexStr = n.getStr()
|
||||||
if not hexStr.isValidTopic:
|
if not hexStr.isValidTopic:
|
||||||
raise newException(ValueError, invalidMsg(argName) & " as a topic \"" & hexStr & "\"")
|
raise newException(ValueError, invalidMsg(argName) & " as a topic \"" & hexStr & "\"")
|
||||||
hexToByteArray(hexStr.string[2 .. ^1], result)
|
result = toTopic(hexStr)
|
||||||
|
|
||||||
|
# Following procs currently required only for testing, the `createRpcSigs` macro
|
||||||
|
# requires it as it will convert the JSON results back to the original Nim
|
||||||
|
# types, but it needs the `fromJson` calls for those specific Nim types to do so
|
||||||
proc fromJson*(n: JsonNode, argName: string, result: var Bytes) =
|
proc fromJson*(n: JsonNode, argName: string, result: var Bytes) =
|
||||||
n.kind.expect(JString, argName)
|
n.kind.expect(JString, argName)
|
||||||
let hexStr = n.getStr()
|
let hexStr = n.getStr()
|
||||||
|
@ -314,10 +312,3 @@ proc fromJson*(n: JsonNode, argName: string, result: var Hash256) =
|
||||||
if not hexStr.isValidHash256:
|
if not hexStr.isValidHash256:
|
||||||
raise newException(ValueError, invalidMsg(argName) & " as a Hash256 \"" & hexStr & "\"")
|
raise newException(ValueError, invalidMsg(argName) & " as a Hash256 \"" & hexStr & "\"")
|
||||||
hexToByteArray(hexStr.string, result.data)
|
hexToByteArray(hexStr.string, result.data)
|
||||||
|
|
||||||
proc fromJson*(n: JsonNode, argName: string, result: var PublicKey) =
|
|
||||||
n.kind.expect(JString, argName)
|
|
||||||
let hexStr = n.getStr()
|
|
||||||
if not hexStr.isValidPublicKey:
|
|
||||||
raise newException(ValueError, invalidMsg(argName) & " as a public key \"" & hexStr & "\"")
|
|
||||||
result = initPublicKey(hexStr.string[4 .. ^1])
|
|
||||||
|
|
|
@ -132,11 +132,11 @@ type
|
||||||
|
|
||||||
WhisperFilterOptions* = object
|
WhisperFilterOptions* = object
|
||||||
# Parameter from user
|
# Parameter from user
|
||||||
symKeyID*: Option[IdentifierStr] # ID of symmetric key for message decryption.
|
symKeyID*: Option[Identifier] # ID of symmetric key for message decryption.
|
||||||
privateKeyID*: Option[IdentifierStr] # ID of private (asymmetric) key for message decryption.
|
privateKeyID*: Option[Identifier] # ID of private (asymmetric) key for message decryption.
|
||||||
sig*: Option[PublicKeyStr] # (Optional) Public key of the signature.
|
sig*: Option[PublicKey] # (Optional) Public key of the signature.
|
||||||
minPow*: Option[float64] # (Optional) Minimal PoW requirement for incoming messages.
|
minPow*: Option[float64] # (Optional) Minimal PoW requirement for incoming messages.
|
||||||
topics*: Option[seq[TopicStr]] # (Optional when asym key): Array of possible topics (or partial topics).
|
topics*: Option[seq[whisper_protocol.Topic]] # (Optional when asym key): Array of possible topics (or partial topics).
|
||||||
allowP2P*: Option[bool] # (Optional) Indicates if this filter allows processing of direct peer-to-peer messages.
|
allowP2P*: Option[bool] # (Optional) Indicates if this filter allows processing of direct peer-to-peer messages.
|
||||||
|
|
||||||
WhisperFilterMessage* = object
|
WhisperFilterMessage* = object
|
||||||
|
@ -153,11 +153,11 @@ type
|
||||||
|
|
||||||
WhisperPostMessage* = object
|
WhisperPostMessage* = object
|
||||||
# Parameter from user
|
# Parameter from user
|
||||||
symKeyID*: Option[IdentifierStr] # ID of symmetric key for message encryption.
|
symKeyID*: Option[Identifier] # ID of symmetric key for message encryption.
|
||||||
pubKey*: Option[PublicKeyStr] # Public key for message encryption.
|
pubKey*: Option[PublicKey] # Public key for message encryption.
|
||||||
sig*: Option[IdentifierStr] # (Optional) ID of the signing key.
|
sig*: Option[Identifier] # (Optional) ID of the signing key.
|
||||||
ttl*: uint64 # Time-to-live in seconds.
|
ttl*: uint64 # Time-to-live in seconds.
|
||||||
topic*: Option[TopicStr] # Message topic (mandatory when key is symmetric).
|
topic*: Option[whisper_protocol.Topic] # Message topic (mandatory when key is symmetric).
|
||||||
payload*: HexDataStr # Payload to be encrypted.
|
payload*: HexDataStr # Payload to be encrypted.
|
||||||
padding*: Option[HexDataStr] # (Optional) Padding (byte array of arbitrary length).
|
padding*: Option[HexDataStr] # (Optional) Padding (byte array of arbitrary length).
|
||||||
powTime*: float64 # Maximal time in seconds to be spent on proof of work.
|
powTime*: float64 # Maximal time in seconds to be spent on proof of work.
|
||||||
|
|
|
@ -71,28 +71,26 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
let peerNode = newNode(enode)
|
let peerNode = newNode(enode)
|
||||||
result = node.setPeerTrusted(peerNode.id)
|
result = node.setPeerTrusted(peerNode.id)
|
||||||
|
|
||||||
rpcsrv.rpc("shh_newKeyPair") do() -> IdentifierStr:
|
rpcsrv.rpc("shh_newKeyPair") do() -> Identifier:
|
||||||
## Generates a new public and private key pair for message decryption and
|
## Generates a new public and private key pair for message decryption and
|
||||||
## encryption.
|
## encryption.
|
||||||
##
|
##
|
||||||
## Returns key identifier on success and an error on failure.
|
## Returns key identifier on success and an error on failure.
|
||||||
result = generateRandomID().IdentifierStr
|
result = generateRandomID().Identifier
|
||||||
keys.asymKeys.add(result.string, newKeyPair())
|
keys.asymKeys.add(result.string, newKeyPair())
|
||||||
|
|
||||||
rpcsrv.rpc("shh_addPrivateKey") do(key: PrivateKeyStr) -> IdentifierStr:
|
rpcsrv.rpc("shh_addPrivateKey") do(key: PrivateKey) -> Identifier:
|
||||||
## Stores the key pair, and returns its ID.
|
## Stores the key pair, and returns its ID.
|
||||||
##
|
##
|
||||||
## key: Private key as hex bytes.
|
## key: Private key as hex bytes.
|
||||||
##
|
##
|
||||||
## Returns key identifier on success and an error on failure.
|
## Returns key identifier on success and an error on failure.
|
||||||
result = generateRandomID().IdentifierStr
|
result = generateRandomID().Identifier
|
||||||
|
|
||||||
# No need to check if 0x prefix as the JSON Marshalling should handle this
|
keys.asymKeys.add(result.string, KeyPair(seckey: key,
|
||||||
var privkey = initPrivateKey(key.string[2 .. ^1])
|
pubkey: key.getPublicKey()))
|
||||||
keys.asymKeys.add(result.string, KeyPair(seckey: privkey,
|
|
||||||
pubkey: privkey.getPublicKey()))
|
|
||||||
|
|
||||||
rpcsrv.rpc("shh_deleteKeyPair") do(id: IdentifierStr) -> bool:
|
rpcsrv.rpc("shh_deleteKeyPair") do(id: Identifier) -> bool:
|
||||||
## Deletes the specifies key if it exists.
|
## Deletes the specifies key if it exists.
|
||||||
##
|
##
|
||||||
## id: Identifier of key pair
|
## id: Identifier of key pair
|
||||||
|
@ -101,7 +99,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
var unneeded: KeyPair
|
var unneeded: KeyPair
|
||||||
result = keys.asymKeys.take(id.string, unneeded)
|
result = keys.asymKeys.take(id.string, unneeded)
|
||||||
|
|
||||||
rpcsrv.rpc("shh_hasKeyPair") do(id: IdentifierStr) -> bool:
|
rpcsrv.rpc("shh_hasKeyPair") do(id: Identifier) -> bool:
|
||||||
## Checks if the whisper node has a private key of a key pair matching the
|
## Checks if the whisper node has a private key of a key pair matching the
|
||||||
## given ID.
|
## given ID.
|
||||||
##
|
##
|
||||||
|
@ -110,7 +108,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
## Returns true on success and an error on failure.
|
## Returns true on success and an error on failure.
|
||||||
result = keys.asymkeys.hasKey(id.string)
|
result = keys.asymkeys.hasKey(id.string)
|
||||||
|
|
||||||
rpcsrv.rpc("shh_getPublicKey") do(id: IdentifierStr) -> PublicKey:
|
rpcsrv.rpc("shh_getPublicKey") do(id: Identifier) -> PublicKey:
|
||||||
## Returns the public key for identity ID.
|
## Returns the public key for identity ID.
|
||||||
##
|
##
|
||||||
## id: Identifier of key pair
|
## id: Identifier of key pair
|
||||||
|
@ -119,7 +117,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
# Note: key not found exception as error in case not existing
|
# Note: key not found exception as error in case not existing
|
||||||
result = keys.asymkeys[id.string].pubkey
|
result = keys.asymkeys[id.string].pubkey
|
||||||
|
|
||||||
rpcsrv.rpc("shh_getPrivateKey") do(id: IdentifierStr) -> PrivateKey:
|
rpcsrv.rpc("shh_getPrivateKey") do(id: Identifier) -> PrivateKey:
|
||||||
## Returns the private key for identity ID.
|
## Returns the private key for identity ID.
|
||||||
##
|
##
|
||||||
## id: Identifier of key pair
|
## id: Identifier of key pair
|
||||||
|
@ -128,13 +126,13 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
# Note: key not found exception as error in case not existing
|
# Note: key not found exception as error in case not existing
|
||||||
result = keys.asymkeys[id.string].seckey
|
result = keys.asymkeys[id.string].seckey
|
||||||
|
|
||||||
rpcsrv.rpc("shh_newSymKey") do() -> IdentifierStr:
|
rpcsrv.rpc("shh_newSymKey") do() -> Identifier:
|
||||||
## Generates a random symmetric key and stores it under an ID, which is then
|
## Generates a random symmetric key and stores it under an ID, which is then
|
||||||
## returned. Can be used encrypting and decrypting messages where the key is
|
## returned. Can be used encrypting and decrypting messages where the key is
|
||||||
## known to both parties.
|
## known to both parties.
|
||||||
##
|
##
|
||||||
## Returns key identifier on success and an error on failure.
|
## Returns key identifier on success and an error on failure.
|
||||||
result = generateRandomID().IdentifierStr
|
result = generateRandomID().Identifier
|
||||||
var key: SymKey
|
var key: SymKey
|
||||||
if randomBytes(key) != key.len:
|
if randomBytes(key) != key.len:
|
||||||
error "Generation of SymKey failed"
|
error "Generation of SymKey failed"
|
||||||
|
@ -142,20 +140,17 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
keys.symKeys.add(result.string, key)
|
keys.symKeys.add(result.string, key)
|
||||||
|
|
||||||
|
|
||||||
rpcsrv.rpc("shh_addSymKey") do(key: SymKeyStr) -> IdentifierStr:
|
rpcsrv.rpc("shh_addSymKey") do(key: SymKey) -> Identifier:
|
||||||
## Stores the key, and returns its ID.
|
## Stores the key, and returns its ID.
|
||||||
##
|
##
|
||||||
## key: The raw key for symmetric encryption as hex bytes.
|
## key: The raw key for symmetric encryption as hex bytes.
|
||||||
##
|
##
|
||||||
## Returns key identifier on success and an error on failure.
|
## Returns key identifier on success and an error on failure.
|
||||||
result = generateRandomID().IdentifierStr
|
result = generateRandomID().Identifier
|
||||||
|
|
||||||
var symKey: SymKey
|
keys.symKeys.add(result.string, key)
|
||||||
# No need to check if 0x prefix as the JSON Marshalling should handle this
|
|
||||||
hexToByteArray(key.string[2 .. ^1], symKey)
|
|
||||||
keys.symKeys.add(result.string, symKey)
|
|
||||||
|
|
||||||
rpcsrv.rpc("shh_generateSymKeyFromPassword") do(password: string) -> IdentifierStr:
|
rpcsrv.rpc("shh_generateSymKeyFromPassword") do(password: string) -> Identifier:
|
||||||
## Generates the key from password, stores it, and returns its ID.
|
## Generates the key from password, stores it, and returns its ID.
|
||||||
##
|
##
|
||||||
## password: Password.
|
## password: Password.
|
||||||
|
@ -169,10 +164,10 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
if pbkdf2(ctx, password, "", 65356, symKey) != sizeof(SymKey):
|
if pbkdf2(ctx, password, "", 65356, symKey) != sizeof(SymKey):
|
||||||
raise newException(ValueError, "Failed generating key")
|
raise newException(ValueError, "Failed generating key")
|
||||||
|
|
||||||
result = generateRandomID().IdentifierStr
|
result = generateRandomID().Identifier
|
||||||
keys.symKeys.add(result.string, symKey)
|
keys.symKeys.add(result.string, symKey)
|
||||||
|
|
||||||
rpcsrv.rpc("shh_hasSymKey") do(id: IdentifierStr) -> bool:
|
rpcsrv.rpc("shh_hasSymKey") do(id: Identifier) -> bool:
|
||||||
## Returns true if there is a key associated with the name string.
|
## Returns true if there is a key associated with the name string.
|
||||||
## Otherwise, returns false.
|
## Otherwise, returns false.
|
||||||
##
|
##
|
||||||
|
@ -181,7 +176,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
## Returns (true or false) on success and an error on failure.
|
## Returns (true or false) on success and an error on failure.
|
||||||
result = keys.symkeys.hasKey(id.string)
|
result = keys.symkeys.hasKey(id.string)
|
||||||
|
|
||||||
rpcsrv.rpc("shh_getSymKey") do(id: IdentifierStr) -> SymKey:
|
rpcsrv.rpc("shh_getSymKey") do(id: Identifier) -> SymKey:
|
||||||
## Returns the symmetric key associated with the given ID.
|
## Returns the symmetric key associated with the given ID.
|
||||||
##
|
##
|
||||||
## id: Identifier of key.
|
## id: Identifier of key.
|
||||||
|
@ -190,7 +185,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
# Note: key not found exception as error in case not existing
|
# Note: key not found exception as error in case not existing
|
||||||
result = keys.symkeys[id.string]
|
result = keys.symkeys[id.string]
|
||||||
|
|
||||||
rpcsrv.rpc("shh_deleteSymKey") do(id: IdentifierStr) -> bool:
|
rpcsrv.rpc("shh_deleteSymKey") do(id: Identifier) -> bool:
|
||||||
## Deletes the key associated with the name string if it exists.
|
## Deletes the key associated with the name string if it exists.
|
||||||
##
|
##
|
||||||
## id: Identifier of key.
|
## id: Identifier of key.
|
||||||
|
@ -200,7 +195,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
result = keys.symKeys.take(id.string, unneeded)
|
result = keys.symKeys.take(id.string, unneeded)
|
||||||
|
|
||||||
rpcsrv.rpc("shh_subscribe") do(id: string,
|
rpcsrv.rpc("shh_subscribe") do(id: string,
|
||||||
options: WhisperFilterOptions) -> IdentifierStr:
|
options: WhisperFilterOptions) -> Identifier:
|
||||||
## Creates and registers a new subscription to receive notifications for
|
## Creates and registers a new subscription to receive notifications for
|
||||||
## inbound whisper messages. Returns the ID of the newly created
|
## inbound whisper messages. Returns the ID of the newly created
|
||||||
## subscription.
|
## subscription.
|
||||||
|
@ -214,7 +209,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
# TODO: implement subscriptions, only for WS & IPC?
|
# TODO: implement subscriptions, only for WS & IPC?
|
||||||
discard
|
discard
|
||||||
|
|
||||||
rpcsrv.rpc("shh_unsubscribe") do(id: IdentifierStr) -> bool:
|
rpcsrv.rpc("shh_unsubscribe") do(id: Identifier) -> bool:
|
||||||
## Cancels and removes an existing subscription.
|
## Cancels and removes an existing subscription.
|
||||||
##
|
##
|
||||||
## id: Subscription identifier
|
## id: Subscription identifier
|
||||||
|
@ -229,7 +224,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
if asym.isNone() and topic.isNone():
|
if asym.isNone() and topic.isNone():
|
||||||
raise newException(ValueError, "Topic mandatory with symmetric key")
|
raise newException(ValueError, "Topic mandatory with symmetric key")
|
||||||
|
|
||||||
rpcsrv.rpc("shh_newMessageFilter") do(options: WhisperFilterOptions) -> IdentifierStr:
|
rpcsrv.rpc("shh_newMessageFilter") do(options: WhisperFilterOptions) -> Identifier:
|
||||||
## Create a new filter within the node. This filter can be used to poll for
|
## Create a new filter within the node. This filter can be used to poll for
|
||||||
## new messages that match the set of criteria.
|
## new messages that match the set of criteria.
|
||||||
##
|
##
|
||||||
|
@ -248,24 +243,20 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
if options.symKeyID.isSome():
|
if options.symKeyID.isSome():
|
||||||
filter.symKey= some(keys.symKeys[options.symKeyID.get().string])
|
filter.symKey= some(keys.symKeys[options.symKeyID.get().string])
|
||||||
|
|
||||||
if options.sig.isSome():
|
filter.src = options.sig
|
||||||
# Need to strip 0x04
|
|
||||||
filter.src = some(initPublicKey(options.sig.get().string[4 .. ^1]))
|
|
||||||
|
|
||||||
if options.minPow.isSome():
|
if options.minPow.isSome():
|
||||||
filter.powReq = options.minPow.get()
|
filter.powReq = options.minPow.get()
|
||||||
|
|
||||||
if options.topics.isSome():
|
if options.topics.isSome():
|
||||||
filter.topics = map(options.topics.get(),
|
filter.topics = options.topics.get()
|
||||||
proc(x: TopicStr): whisper_protocol.Topic =
|
|
||||||
hexToByteArray(x.string[2 .. ^1], result))
|
|
||||||
|
|
||||||
if options.allowP2P.isSome():
|
if options.allowP2P.isSome():
|
||||||
filter.allowP2P = options.allowP2P.get()
|
filter.allowP2P = options.allowP2P.get()
|
||||||
|
|
||||||
result = node.subscribeFilter(filter).IdentifierStr
|
result = node.subscribeFilter(filter).Identifier
|
||||||
|
|
||||||
rpcsrv.rpc("shh_deleteMessageFilter") do(id: IdentifierStr) -> bool:
|
rpcsrv.rpc("shh_deleteMessageFilter") do(id: Identifier) -> bool:
|
||||||
## Uninstall a message filter in the node.
|
## Uninstall a message filter in the node.
|
||||||
##
|
##
|
||||||
## id: Filter identifier as returned when the filter was created.
|
## id: Filter identifier as returned when the filter was created.
|
||||||
|
@ -273,7 +264,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
## Returns true on success, error on failure.
|
## Returns true on success, error on failure.
|
||||||
result = node.unsubscribeFilter(id.string)
|
result = node.unsubscribeFilter(id.string)
|
||||||
|
|
||||||
rpcsrv.rpc("shh_getFilterMessages") do(id: IdentifierStr) -> seq[WhisperFilterMessage]:
|
rpcsrv.rpc("shh_getFilterMessages") do(id: Identifier) -> seq[WhisperFilterMessage]:
|
||||||
## Retrieve messages that match the filter criteria and are received between
|
## Retrieve messages that match the filter criteria and are received between
|
||||||
## the last time this function was called and now.
|
## the last time this function was called and now.
|
||||||
##
|
##
|
||||||
|
@ -320,8 +311,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
padding: Option[Bytes]
|
padding: Option[Bytes]
|
||||||
targetPeer: Option[NodeId]
|
targetPeer: Option[NodeId]
|
||||||
|
|
||||||
if message.pubKey.isSome():
|
pubKey = message.pubKey
|
||||||
pubKey = some(initPublicKey(message.pubKey.get().string[4 .. ^1]))
|
|
||||||
|
|
||||||
if message.sig.isSome():
|
if message.sig.isSome():
|
||||||
sigPrivKey = some(keys.asymKeys[message.sig.get().string].seckey)
|
sigPrivKey = some(keys.asymKeys[message.sig.get().string].seckey)
|
||||||
|
@ -331,7 +321,7 @@ proc setupWhisperRPC*(node: EthereumNode, keys: WhisperKeys, rpcsrv: RpcServer)
|
||||||
|
|
||||||
# Note: If no topic it will be defaulted to 0x00000000
|
# Note: If no topic it will be defaulted to 0x00000000
|
||||||
if message.topic.isSome():
|
if message.topic.isSome():
|
||||||
hexToByteArray(message.topic.get().string[2 .. ^1], topic)
|
topic = message.topic.get()
|
||||||
|
|
||||||
if message.padding.isSome():
|
if message.padding.isSome():
|
||||||
padding = some(hexToSeqByte(message.padding.get().string))
|
padding = some(hexToSeqByte(message.padding.get().string))
|
||||||
|
|
|
@ -82,21 +82,21 @@ proc shh_setMaxMessageSize(size: uint64): bool
|
||||||
proc shh_setMinPoW(pow: float): bool
|
proc shh_setMinPoW(pow: float): bool
|
||||||
proc shh_markTrustedPeer(enode: string): bool
|
proc shh_markTrustedPeer(enode: string): bool
|
||||||
|
|
||||||
proc shh_newKeyPair(): IdentifierStr
|
proc shh_newKeyPair(): Identifier
|
||||||
proc shh_addPrivateKey(key: string): IdentifierStr
|
proc shh_addPrivateKey(key: string): Identifier
|
||||||
proc shh_deleteKeyPair(id: IdentifierStr): bool
|
proc shh_deleteKeyPair(id: Identifier): bool
|
||||||
proc shh_hasKeyPair(id: IdentifierStr): bool
|
proc shh_hasKeyPair(id: Identifier): bool
|
||||||
proc shh_getPublicKey(id: IdentifierStr): PublicKeyStr
|
proc shh_getPublicKey(id: Identifier): PublicKey
|
||||||
proc shh_getPrivateKey(id: IdentifierStr): PrivateKeyStr
|
proc shh_getPrivateKey(id: Identifier): PrivateKey
|
||||||
|
|
||||||
proc shh_newSymKey(): IdentifierStr
|
proc shh_newSymKey(): Identifier
|
||||||
proc shh_addSymKey(key: string): IdentifierStr
|
proc shh_addSymKey(key: string): Identifier
|
||||||
proc shh_generateSymKeyFromPassword(password: string): IdentifierStr
|
proc shh_generateSymKeyFromPassword(password: string): Identifier
|
||||||
proc shh_hasSymKey(id: IdentifierStr): bool
|
proc shh_hasSymKey(id: Identifier): bool
|
||||||
proc shh_getSymKey(id: IdentifierStr): SymKeyStr
|
proc shh_getSymKey(id: Identifier): SymKey
|
||||||
proc shh_deleteSymKey(id: IdentifierStr): bool
|
proc shh_deleteSymKey(id: Identifier): bool
|
||||||
|
|
||||||
proc shh_newMessageFilter(options: WhisperFilterOptions): IdentifierStr
|
proc shh_newMessageFilter(options: WhisperFilterOptions): Identifier
|
||||||
proc shh_deleteMessageFilter(id: IdentifierStr): bool
|
proc shh_deleteMessageFilter(id: Identifier): bool
|
||||||
proc shh_getFilterMessages(id: IdentifierStr): seq[WhisperFilterMessage]
|
proc shh_getFilterMessages(id: Identifier): seq[WhisperFilterMessage]
|
||||||
proc shh_post(message: WhisperPostMessage): bool
|
proc shh_post(message: WhisperPostMessage): bool
|
||||||
|
|
|
@ -77,8 +77,8 @@ proc doTests =
|
||||||
let pubkey = "0x04e5fd642a0f630bbb1e4cd7df629d7b8b019457a9a74f983c0484a045cebb176def86a54185b50bbba6bbf97779173695e92835d63109c23471e6da382f922fdb"
|
let pubkey = "0x04e5fd642a0f630bbb1e4cd7df629d7b8b019457a9a74f983c0484a045cebb176def86a54185b50bbba6bbf97779173695e92835d63109c23471e6da382f922fdb"
|
||||||
let keyID2 = waitFor client.shh_addPrivateKey(privkey)
|
let keyID2 = waitFor client.shh_addPrivateKey(privkey)
|
||||||
check:
|
check:
|
||||||
waitFor(client.shh_getPublicKey(keyID2)).string == pubkey
|
waitFor(client.shh_getPublicKey(keyID2)) == pubkey.toPublicKey
|
||||||
waitFor(client.shh_getPrivateKey(keyID2)).string == privkey
|
waitFor(client.shh_getPrivateKey(keyID2)) == privkey.toPrivateKey
|
||||||
waitFor(client.shh_hasKeyPair(keyID2)) == true
|
waitFor(client.shh_hasKeyPair(keyID2)) == true
|
||||||
waitFor(client.shh_deleteKeyPair(keyID2)) == true
|
waitFor(client.shh_deleteKeyPair(keyID2)) == true
|
||||||
waitFor(client.shh_hasKeyPair(keyID2)) == false
|
waitFor(client.shh_hasKeyPair(keyID2)) == false
|
||||||
|
@ -94,7 +94,7 @@ proc doTests =
|
||||||
let symKey = "0x0000000000000000000000000000000000000000000000000000000000000001"
|
let symKey = "0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||||
let keyID2 = waitFor client.shh_addSymKey(symKey)
|
let keyID2 = waitFor client.shh_addSymKey(symKey)
|
||||||
check:
|
check:
|
||||||
waitFor(client.shh_getSymKey(keyID2)).string == symKey
|
waitFor(client.shh_getSymKey(keyID2)) == symKey.toSymKey
|
||||||
waitFor(client.shh_hasSymKey(keyID2)) == true
|
waitFor(client.shh_hasSymKey(keyID2)) == true
|
||||||
waitFor(client.shh_deleteSymKey(keyID2)) == true
|
waitFor(client.shh_deleteSymKey(keyID2)) == true
|
||||||
waitFor(client.shh_hasSymKey(keyID2)) == false
|
waitFor(client.shh_hasSymKey(keyID2)) == false
|
||||||
|
@ -104,10 +104,10 @@ proc doTests =
|
||||||
let keyID4 = waitFor client.shh_generateSymKeyFromPassword("password")
|
let keyID4 = waitFor client.shh_generateSymKeyFromPassword("password")
|
||||||
let keyID5 = waitFor client.shh_generateSymKeyFromPassword("nimbus!")
|
let keyID5 = waitFor client.shh_generateSymKeyFromPassword("nimbus!")
|
||||||
check:
|
check:
|
||||||
waitFor(client.shh_getSymKey(keyID3)).string ==
|
waitFor(client.shh_getSymKey(keyID3)) ==
|
||||||
waitFor(client.shh_getSymKey(keyID4)).string
|
waitFor(client.shh_getSymKey(keyID4))
|
||||||
waitFor(client.shh_getSymKey(keyID3)).string !=
|
waitFor(client.shh_getSymKey(keyID3)) !=
|
||||||
waitFor(client.shh_getSymKey(keyID5)).string
|
waitFor(client.shh_getSymKey(keyID5))
|
||||||
waitFor(client.shh_hasSymKey(keyID3)) == true
|
waitFor(client.shh_hasSymKey(keyID3)) == true
|
||||||
waitFor(client.shh_deleteSymKey(keyID3)) == true
|
waitFor(client.shh_deleteSymKey(keyID3)) == true
|
||||||
waitFor(client.shh_hasSymKey(keyID3)) == false
|
waitFor(client.shh_hasSymKey(keyID3)) == false
|
||||||
|
@ -116,7 +116,7 @@ proc doTests =
|
||||||
# Some defaults for the filter & post tests
|
# Some defaults for the filter & post tests
|
||||||
let
|
let
|
||||||
ttl = 30'u64
|
ttl = 30'u64
|
||||||
topic = "0x12345678"
|
topicStr = "0x12345678"
|
||||||
payload = "0x45879632"
|
payload = "0x45879632"
|
||||||
# A very low target and long time so we are sure the test never fails
|
# A very low target and long time so we are sure the test never fails
|
||||||
# because of this
|
# because of this
|
||||||
|
@ -125,13 +125,14 @@ proc doTests =
|
||||||
|
|
||||||
test "shh symKey post and filter loop":
|
test "shh symKey post and filter loop":
|
||||||
let
|
let
|
||||||
|
topic = topicStr.toTopic()
|
||||||
symKeyID = waitFor client.shh_newSymKey()
|
symKeyID = waitFor client.shh_newSymKey()
|
||||||
options = WhisperFilterOptions(symKeyID: some(symKeyID),
|
options = WhisperFilterOptions(symKeyID: some(symKeyID),
|
||||||
topics: some(@[topic.TopicStr]))
|
topics: some(@[topic]))
|
||||||
filterID = waitFor client.shh_newMessageFilter(options)
|
filterID = waitFor client.shh_newMessageFilter(options)
|
||||||
message = WhisperPostMessage(symKeyID: some(symKeyID),
|
message = WhisperPostMessage(symKeyID: some(symKeyID),
|
||||||
ttl: ttl,
|
ttl: ttl,
|
||||||
topic: some(topic.TopicStr),
|
topic: some(topic),
|
||||||
payload: payload.HexDataStr,
|
payload: payload.HexDataStr,
|
||||||
powTime: powTime,
|
powTime: powTime,
|
||||||
powTarget: powTarget)
|
powTarget: powTarget)
|
||||||
|
@ -145,20 +146,21 @@ proc doTests =
|
||||||
messages[0].sig.isNone()
|
messages[0].sig.isNone()
|
||||||
messages[0].recipientPublicKey.isNone()
|
messages[0].recipientPublicKey.isNone()
|
||||||
messages[0].ttl == ttl
|
messages[0].ttl == ttl
|
||||||
("0x" & messages[0].topic.toHex) == topic
|
messages[0].topic == topic
|
||||||
("0x" & messages[0].payload.toHex) == payload
|
messages[0].payload == hexToSeqByte(payload)
|
||||||
messages[0].padding.len > 0
|
messages[0].padding.len > 0
|
||||||
messages[0].pow >= powTarget
|
messages[0].pow >= powTarget
|
||||||
|
|
||||||
test "shh asymKey post and filter loop":
|
test "shh asymKey post and filter loop":
|
||||||
let
|
let
|
||||||
|
topic = topicStr.toTopic()
|
||||||
privateKeyID = waitFor client.shh_newKeyPair()
|
privateKeyID = waitFor client.shh_newKeyPair()
|
||||||
options = WhisperFilterOptions(privateKeyID: some(privateKeyID))
|
options = WhisperFilterOptions(privateKeyID: some(privateKeyID))
|
||||||
filterID = waitFor client.shh_newMessageFilter(options)
|
filterID = waitFor client.shh_newMessageFilter(options)
|
||||||
pubKey = waitFor client.shh_getPublicKey(privateKeyID)
|
pubKey = waitFor client.shh_getPublicKey(privateKeyID)
|
||||||
message = WhisperPostMessage(pubKey: some(pubKey),
|
message = WhisperPostMessage(pubKey: some(pubKey),
|
||||||
ttl: ttl,
|
ttl: ttl,
|
||||||
topic: some(topic.TopicStr),
|
topic: some(topic),
|
||||||
payload: payload.HexDataStr,
|
payload: payload.HexDataStr,
|
||||||
powTime: powTime,
|
powTime: powTime,
|
||||||
powTarget: powTarget)
|
powTarget: powTarget)
|
||||||
|
@ -170,26 +172,27 @@ proc doTests =
|
||||||
check:
|
check:
|
||||||
messages.len == 1
|
messages.len == 1
|
||||||
messages[0].sig.isNone()
|
messages[0].sig.isNone()
|
||||||
("0x04" & $messages[0].recipientPublicKey.get()) == pubKey.string
|
messages[0].recipientPublicKey.get() == pubKey
|
||||||
messages[0].ttl == ttl
|
messages[0].ttl == ttl
|
||||||
("0x" & messages[0].topic.toHex) == topic
|
messages[0].topic == topic
|
||||||
("0x" & messages[0].payload.toHex) == payload
|
messages[0].payload == hexToSeqByte(payload)
|
||||||
messages[0].padding.len > 0
|
messages[0].padding.len > 0
|
||||||
messages[0].pow >= powTarget
|
messages[0].pow >= powTarget
|
||||||
|
|
||||||
test "shh signature in post and filter loop":
|
test "shh signature in post and filter loop":
|
||||||
let
|
let
|
||||||
|
topic = topicStr.toTopic()
|
||||||
symKeyID = waitFor client.shh_newSymKey()
|
symKeyID = waitFor client.shh_newSymKey()
|
||||||
privateKeyID = waitFor client.shh_newKeyPair()
|
privateKeyID = waitFor client.shh_newKeyPair()
|
||||||
pubKey = waitFor client.shh_getPublicKey(privateKeyID)
|
pubKey = waitFor client.shh_getPublicKey(privateKeyID)
|
||||||
options = WhisperFilterOptions(symKeyID: some(symKeyID),
|
options = WhisperFilterOptions(symKeyID: some(symKeyID),
|
||||||
topics: some(@[topic.TopicStr]),
|
topics: some(@[topic]),
|
||||||
sig: some(pubKey))
|
sig: some(pubKey))
|
||||||
filterID = waitFor client.shh_newMessageFilter(options)
|
filterID = waitFor client.shh_newMessageFilter(options)
|
||||||
message = WhisperPostMessage(symKeyID: some(symKeyID),
|
message = WhisperPostMessage(symKeyID: some(symKeyID),
|
||||||
sig: some(privateKeyID),
|
sig: some(privateKeyID),
|
||||||
ttl: ttl,
|
ttl: ttl,
|
||||||
topic: some(topic.TopicStr),
|
topic: some(topic),
|
||||||
payload: payload.HexDataStr,
|
payload: payload.HexDataStr,
|
||||||
powTime: powTime,
|
powTime: powTime,
|
||||||
powTarget: powTarget)
|
powTarget: powTarget)
|
||||||
|
@ -200,11 +203,11 @@ proc doTests =
|
||||||
let messages = waitFor client.shh_getFilterMessages(filterID)
|
let messages = waitFor client.shh_getFilterMessages(filterID)
|
||||||
check:
|
check:
|
||||||
messages.len == 1
|
messages.len == 1
|
||||||
("0x04" & $messages[0].sig.get()) == pubKey.string
|
messages[0].sig.get() == pubKey
|
||||||
messages[0].recipientPublicKey.isNone()
|
messages[0].recipientPublicKey.isNone()
|
||||||
messages[0].ttl == ttl
|
messages[0].ttl == ttl
|
||||||
("0x" & messages[0].topic.toHex) == topic
|
messages[0].topic == topic
|
||||||
("0x" & messages[0].payload.toHex) == payload
|
messages[0].payload == hexToSeqByte(payload)
|
||||||
messages[0].padding.len > 0
|
messages[0].padding.len > 0
|
||||||
messages[0].pow >= powTarget
|
messages[0].pow >= powTarget
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue