Improving whisper post and subscribe

This commit is contained in:
kdeme 2019-10-25 17:31:42 +02:00 committed by zah
parent 24850f8b96
commit 119a53d298
3 changed files with 79 additions and 75 deletions

View File

@ -12,6 +12,7 @@ typedef struct {
int8_t* decoded;
size_t decodedLen;
uint8_t source[64];
uint8_t recipientPublicKey[64];
uint32_t timestamp;
uint32_t ttl;
uint8_t topic[4];
@ -22,19 +23,20 @@ typedef struct {
typedef struct {
const char* symKeyID;
const char* privateKeyID;
uint8_t sig[64];
uint8_t* source; // 64 bytes public key
double minPow;
uint8_t topic[4];
int allowP2P;
} filter_options;
typedef struct {
const char* symKeyID;
uint8_t pubKey[64];
const char* sig;
uint8_t* pubKey; // 64 bytes public key
const char* sourceID;
uint32_t ttl;
uint8_t topic[4];
char* payload;
char* padding;
uint8_t topic[4]; // default 0 is OK
const char* payload; // could also provide uint8_t* + size_t
const char* padding; // could also provide uint8_t* + size_t
double powTime;
double powTarget;
} post_message;
@ -85,10 +87,11 @@ int nimbus_get_symkey(const char* id, uint8_t* symkey);
/* Whisper message posting and receiving API */
/* Subscribe to given filter */
void nimbus_subscribe_filter(filter_options* filter_options,
const char* nimbus_subscribe_filter(filter_options* filter_options,
received_msg_handler msg);
int nimbus_unsubscribe_filter(const char* id);
/* Post Whisper message */
void nimbus_post(post_message* msg);
int nimbus_post(post_message* msg);
#ifdef __cplusplus
}

View File

@ -35,6 +35,7 @@ type
decoded*: ptr byte
decodedLen*: csize
source*: PublicKey
recipientPublicKey*: PublicKey
timestamp*: uint32
ttl*: uint32
topic*: Topic
@ -44,14 +45,15 @@ type
CFilterOptions* = object
symKeyID*: cstring
privateKeyID*: cstring
sig*: PublicKey
source*: ptr PublicKey
minPow*: float64
topic*: Topic # lets go with one topic for now
allowP2P*: bool
CPostMessage* = object
symKeyID*: cstring
pubKey*: PublicKey
sig*: cstring
pubKey*: ptr PublicKey
sourceID*: cstring
ttl*: uint32
topic*: Topic
payload*: cstring
@ -291,9 +293,10 @@ proc nimbus_get_symkey(id: cstring, symKey: ptr SymKey):
# Whisper message posting and receiving API
proc nimbus_post(message: ptr CPostMessage) {.exportc.} =
setupForeignThreadGc()
proc nimbus_post(message: ptr CPostMessage): bool {.exportc,foreignThreadGc.} =
## Encryption is not mandatory.
## A symKey, an asymKey, or nothing can be provided. asymKey has precedence.
## Providing a payload is mandatory.
var
sigPrivKey: Option[PrivateKey]
asymKey: Option[PublicKey]
@ -301,31 +304,27 @@ proc nimbus_post(message: ptr CPostMessage) {.exportc.} =
padding: Option[Bytes]
payload: Bytes
# TODO:
# - check if there is a asymKey and/or pubKey or do we not care?
# - fail if payload is nil?
# - error handling on key access
# TODO: How to arrange optional pubkey?
# - Ptr with check on Nil? (or just cstring?)
# - Convert also Options?
# - Or just add different API calls?
# asymKey = some(message.pubKey)
asymKey = none(PublicKey)
if not message.pubKey.isNil():
asymKey = some(message.pubKey[])
try:
if not message.symKeyID.isNil():
symKey = some(whisperKeys.symKeys[$message.symKeyID])
if not message.sig.isNil():
sigPrivKey = some(whisperKeys.asymKeys[$message.sig].seckey)
if not message.sourceID.isNil():
sigPrivKey = some(whisperKeys.asymKeys[$message.sourceID].seckey)
except KeyError:
return false
if not message.payload.isNil():
# TODO: Is this cast OK?
payload = cast[Bytes]($message.payload)
# payload = cast[Bytes](@($message.payload))
else:
return false
if not message.padding.isNil():
padding = some(cast[Bytes]($message.padding))
# TODO: Handle error case
discard node.postMessage(asymKey,
result = node.postMessage(asymKey,
symKey,
sigPrivKey,
ttl = message.ttl,
@ -335,30 +334,31 @@ proc nimbus_post(message: ptr CPostMessage) {.exportc.} =
powTime = message.powTime,
powTarget = message.powTarget)
tearDownForeignThreadGc()
proc nimbus_subscribe_filter(options: ptr CFilterOptions,
handler: proc (msg: ptr CReceivedMessage)
{.gcsafe, cdecl.}) {.exportc.} =
setupForeignThreadGc()
# TODO: same remarks as in nimbus_whisper_post()
handler: proc (msg: ptr CReceivedMessage) {.gcsafe, cdecl.}):
cstring {.exportc, foreignThreadGc.} =
## In case of a passed handler, the received msg needs to be copied before the
## handler ends.
## TODO: provide some user context passing here else this is rather useless?
var filter: Filter
filter.src = none(PublicKey)
if not options.source.isNil():
filter.src = some(options.source[])
try:
if not options.symKeyID.isNil():
# if options.symKeyID.len() > 0:
filter.symKey= some(whisperKeys.symKeys[$options.symKeyID])
if not options.privateKeyID.isNil():
filter.privateKey= some(whisperKeys.asymKeys[$options.privateKeyID].seckey)
except KeyError:
return nil
filter.powReq = options.minPow
filter.topics = @[options.topic]
filter.allowP2P = false
filter.allowP2P = options.allowP2P
if handler.isNil:
discard node.subscribeFilter(filter, nil)
return
result = node.subscribeFilter(filter, nil)
else:
proc c_handler(msg: ReceivedMessage) {.gcsafe.} =
var cmsg = CReceivedMessage(
decoded: unsafeAddr msg.decoded.payload[0],
@ -370,14 +370,15 @@ proc nimbus_subscribe_filter(options: ptr CFilterOptions,
hash: msg.hash
)
# TODO: change this to ptr, so that C/go code can check on nil?
if msg.decoded.src.isSome():
cmsg.source = msg.decoded.src.get()
if msg.dst.isSome():
cmsg.recipientPublicKey = msg.decoded.src.get()
handler(addr cmsg)
discard node.subscribeFilter(filter, c_handler)
tearDownForeignThreadGc()
result = node.subscribeFilter(filter, c_handler)
proc nimbus_unsubscribe_filter(id: cstring): bool {.exportc.} =
result = node.unsubscribeFilter($id)

View File

@ -58,7 +58,7 @@ func StatusListenAndPost(channel string) {
(C.received_msg_handler)(unsafe.Pointer(C.receiveHandler_cgo)))
postMessage := C.post_message{symKeyID: C.CString(symKeyId),
sig: C.CString(asymKeyId),
sourceID: C.CString(asymKeyId),
ttl: 20,
topic: C.nimbus_string_to_topic(C.CString(channel)).topic,
powTarget: 0.002,