Skip to content
This repository has been archived by the owner on Nov 21, 2019. It is now read-only.

Commit

Permalink
Adapt to Nimbus API
Browse files Browse the repository at this point in the history
  • Loading branch information
Pedro Pombeiro committed Oct 30, 2019
1 parent 30d6fa5 commit 65edcb1
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 94 deletions.
26 changes: 11 additions & 15 deletions bridge/nimbus/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ import (
)

type nimbusFilterWrapper struct {
filter *C.filter
filter *C.filter_options
id string
own bool
pk *ecdsa.PrivateKey
keySym [whispertypes.AesKeyLength]byte
}

// NewNimbusFilterWrapper returns an object that wraps Nimbus's Filter in a whispertypes interface
func NewNimbusFilterWrapper(f *C.filter, id string, own bool) whispertypes.Filter {
key, err := crypto.HexToECDSA(C.GoString(f.keyAsymHex))
func NewNimbusFilterWrapper(f *C.filter_options, id string, own bool) whispertypes.Filter {
key, err := crypto.HexToECDSA(C.GoString(f.privateKeyID))
if err != nil {
panic(err)
}
Expand All @@ -39,12 +39,12 @@ func NewNimbusFilterWrapper(f *C.filter, id string, own bool) whispertypes.Filte
own: own,
pk: key,
}
copy(wrapper.keySym[:], C.GoBytes(unsafe.Pointer(f.keySym), whispertypes.AesKeyLength))
copy(wrapper.keySym[:], C.GoBytes(unsafe.Pointer(f.symKeyID), whispertypes.AesKeyLength))
return wrapper
}

// GetNimbusFilterFrom retrieves the underlying whisper Filter struct from a wrapped Filter interface
func GetNimbusFilterFrom(f whispertypes.Filter) *C.filter {
func GetNimbusFilterFrom(f whispertypes.Filter) *C.filter_options {
return f.(*nimbusFilterWrapper).filter
}

Expand All @@ -69,16 +69,12 @@ func (w *nimbusFilterWrapper) Free() {
panic("native filter is not owned by Go")
}

if w.filter.topic != nil {
C.free(unsafe.Pointer(w.filter.topic))
w.filter.topic = nil
if w.filter.privateKeyID != nil {
C.free(unsafe.Pointer(w.filter.privateKeyID))
w.filter.privateKeyID = nil
}
if w.filter.keyAsymHex != nil {
C.free(unsafe.Pointer(w.filter.keyAsymHex))
w.filter.keyAsymHex = nil
}
if w.filter.keySym != nil {
C.free(unsafe.Pointer(w.filter.keySym))
w.filter.keySym = nil
if w.filter.symKeyID != nil {
C.free(unsafe.Pointer(w.filter.symKeyID))
w.filter.symKeyID = nil
}
}
114 changes: 83 additions & 31 deletions bridge/nimbus/libnim.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
#ifndef __LIBNIMBUS_H__
#define __LIBNIMBUS_H__

#include <stdint.h>
#include <stddef.h>

#pragma once

#ifndef __LIBNIM_H__
#define __LIBNIM_H__
#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
uint8_t* decoded;
int8_t* decoded;
size_t decodedLen;
uint8_t source[64];
uint8_t recipientPublicKey[64];
uint32_t timestamp;
uint32_t ttl;
uint8_t topic[4];
Expand All @@ -17,12 +21,25 @@ typedef struct {
} received_message;

typedef struct {
const char* keyAsymHex;
const uint8_t* keySym;
double pow;
bool allowP2P;
const uint8_t* topic;
} filter;
const char* symKeyID;
const char* privateKeyID;
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 bytes public key
const char* sourceID;
uint32_t ttl;
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;

typedef struct {
uint8_t* sig; // Public key who signed this message.
Expand All @@ -37,30 +54,65 @@ typedef struct {
uint8_t* hash; // Hash of the enveloped message.
} whisperfiltermessage;

typedef struct {
uint8_t topic[4];
} topic;

typedef void (*received_msg_handler)(const received_message* msg);
// void nimbus_start(uint16_t port);
// void nimbus_poll();
// void NimMain();
const char* nimbus_post(const char* payload);
// void nimbus_subscribe(const char* channel, received_msg_handler msg);
// void nimbus_add_peer(const char* nodeId);
typedef void (*received_msg_handler)(received_message* msg);

double nimbus_get_min_pow();
void nimbus_get_bloom_filter(uint8_t* pBloomFilter);
/** Initialize Nim and the status library */
void NimMain();

/** Start nimbus event loop, connect to bootnodes etc */
void nimbus_start(uint16_t port);

/** Add peers to connect to - must be called after nimbus_start */
void nimbus_add_peer(const char* nodeId);

const char* nimbus_add_keypair(const char* pszHexPK);
bool nimbus_delete_keypair(const char* pszID);
const char* nimbus_get_private_key(const char* pszID);
/**
* Should be called in regularly - for example in a busy loop (beautiful!) on
* dedicated thread.
*/
void nimbus_poll();

const char* nimbus_add_symkey_direct(const uint8_t* pSymKey);
const char* nimbus_add_symkey_from_password(const char* pszPassword);
bool nimbus_get_symkey(const char* pszID, uint8_t* pSymKey);
bool nimbus_delete_symkey(const char* pszID);
void nimbus_post_public(const char* channel, const char* payload);
void nimbus_join_public_chat(const char* channel, received_msg_handler msg);

const char* nimbus_subscribe_filter(const filter* pcFilter, received_msg_handler msg);
const filter* nimbus_get_filter(const char* pszID);
bool nimbus_unsubscribe_filter(const char* pszID);
/* Whisper API */

/* Helper, can be removed */
topic nimbus_string_to_topic(const char* s);

/* Asymmetric Keys API */

const char* nimbus_new_keypair();
const char* nimbus_add_keypair(const uint8_t* privkey);
int nimbus_delete_keypair(const char* id);
int nimbus_get_private_key(const char* id, uint8_t* privkey);

/* Symmetric Keys API */

const char* nimbus_add_symkey(const uint8_t* symkey);
const char* nimbus_add_symkey_from_password(const char* password);
int nimbus_delete_symkey(const char* id);
int nimbus_get_symkey(const char* id, uint8_t* symkey);

/* Whisper message posting and receiving API */

/* Subscribe to given filter */
const char* nimbus_subscribe_filter(filter_options* filter_options,
received_msg_handler msg);
int nimbus_unsubscribe_filter(const char* id);
whisperfiltermessage* nimbus_getfiltermessages(const char* pszID, uint32_t* count);
/* Post Whisper message */
int nimbus_post(post_message* msg);

// TODO: why are these getters needed?
double nimbus_get_min_pow();
void nimbus_get_bloom_filter(uint8_t* bloomfilter);

#ifdef __cplusplus
}
#endif

#endif // __LIBNIM_H__
#endif //__LIBNIMBUS_H__
56 changes: 56 additions & 0 deletions bridge/nimbus/node.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package nimbusbridge

// https://golang.org/cmd/cgo/

/*
#include <stddef.h>
#include <stdbool.h>
#include <stdlib.h>
#include <libnim.h>
*/
import "C"
import (
"fmt"
"runtime"
"time"
)

func Init() {
runtime.LockOSThread()
}

func StartNimbus() {
start()
//go poll()
}

func Poll() {
C.nimbus_poll()
}

func poll() {

for {
fmt.Println("POLLING")
time.Sleep(1 * time.Microsecond)
C.nimbus_poll()
}
}

func start() {
C.NimMain()
fmt.Println("[nim-status] Start 1")
C.nimbus_start(30306)
//C.nimbus_subscribe(C.CString("status-test-c"), nil)
fmt.Println("[nim-status] Start 2")

peer1 := "enode://2d3e27d7846564f9b964308038dfadd4076e4373ac938e020708ad8819fd4fd90e5eb8314140768f782db704cb313b60707b968f8b61108a6fecd705b041746d@192.168.0.33:30303"
peer2 := "enode://4ea35352702027984a13274f241a56a47854a7fd4b3ba674a596cff917d3c825506431cf149f9f2312a293bb7c2b1cca55db742027090916d01529fe0729643b@206.189.243.178:443"

peer3 := "enode://94d2403d0c55b5c1627eb032c4c6ea8d30b523ae84661aafa18c539ce3af3f114a5bfe1a3cde7776988a6ab2906169dca8ce6a79e32d30c445629b24e6f59e0a@0.0.0.0:30303"
fmt.Println(C.nimbus_add_peer(C.CString(peer1)))
fmt.Println(C.nimbus_add_peer(C.CString(peer2)))

fmt.Println(C.nimbus_add_peer(C.CString(peer3)))

}
55 changes: 31 additions & 24 deletions bridge/nimbus/public_whisper_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import "C"

import (
"context"
"encoding/hex"
"errors"
"unsafe"

Expand All @@ -30,10 +29,10 @@ func NewNimbusPublicWhisperAPIWrapper() whispertypes.PublicWhisperAPI {

// AddPrivateKey imports the given private key.
func (w *nimbusPublicWhisperAPIWrapper) AddPrivateKey(ctx context.Context, privateKey statusproto.HexBytes) (string, error) {
privKeyHexC := C.CString(statusproto.EncodeHex(privateKey))
defer C.free(unsafe.Pointer(privKeyHexC))
privKeyC := C.CBytes(privateKey)
defer C.free(unsafe.Pointer(privKeyC))

idC := C.nimbus_add_keypair(privKeyHexC)
idC := C.nimbus_add_keypair((*C.uchar)(privKeyC))
if idC == nil {
return "", errors.New("failed to add private key to Nimbus")
}
Expand All @@ -59,7 +58,7 @@ func (w *nimbusPublicWhisperAPIWrapper) DeleteKeyPair(ctx context.Context, key s
keyC := C.CString(key)
defer C.free(unsafe.Pointer(keyC))

return bool(C.nimbus_delete_keypair(keyC)), nil
return bool(C.nimbus_delete_keypair(keyC) != 0), nil
}

// NewMessageFilter creates a new filter that can be used to poll for
Expand Down Expand Up @@ -88,8 +87,10 @@ func (w *nimbusPublicWhisperAPIWrapper) NewMessageFilter(req whispertypes.Criter
func (w *nimbusPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*whispertypes.Message, error) {
var count uint
var msgs *C.whisperfiltermessage

idC := C.CString(id)
defer C.free(unsafe.Pointer(idC))

msgs = C.nimbus_getfiltermessages(idC, (*C.uint)(unsafe.Pointer(&count)))
if msgs == nil {
return nil, errors.New("failed to retrieve filter messages from Nimbus")
Expand Down Expand Up @@ -120,24 +121,30 @@ func (w *nimbusPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*whisper
// Post posts a message on the Whisper network.
// returns the hash of the message in case of success.
func (w *nimbusPublicWhisperAPIWrapper) Post(ctx context.Context, req whispertypes.NewMessage) ([]byte, error) {
// msg := whisper.NewMessage{
// SymKeyID: req.SymKeyID,
// PublicKey: req.PublicKey,
// Sig: req.Sig,
// TTL: req.TTL,
// Topic: whisper.TopicType(req.Topic),
// Payload: req.Payload,
// Padding: req.Padding,
// PowTime: req.PowTime,
// PowTarget: req.PowTarget,
// TargetPeer: req.TargetPeer,
// }
payloadC := C.CBytes(req.Payload)
defer C.free(unsafe.Pointer(payloadC))

hashC := C.nimbus_post((*C.char)(payloadC))
if hashC == nil {
return nil, errors.New("Nimbus failed to post message")
msg := C.post_message{
ttl: C.uint(req.TTL),
powTime: C.double(req.PowTime),
powTarget: C.double(req.PowTarget),
}
return hex.DecodeString(C.GoString(hashC))
if req.SymKeyID != "" {
msg.symKeyID = C.CString(req.SymKeyID)
defer C.free(unsafe.Pointer(msg.symKeyID))
}
msg.pubKey = (*C.uchar)(C.CBytes(req.PublicKey))
defer C.free(unsafe.Pointer(msg.pubKey))
msg.payload = (*C.char)(C.CBytes(req.Payload))
defer C.free(unsafe.Pointer(msg.payload))
msg.padding = (*C.char)(C.CBytes(req.Padding))
defer C.free(unsafe.Pointer(msg.padding))
copyTopicToCBuffer(&msg.topic[0], req.Topic[:])

if C.nimbus_post(&msg) != 0 {
return make([]byte, 0), nil
}
return nil, errors.New("failed to post message")
// hashC := C.nimbus_post(&msg)
// if hashC == nil {
// return nil, errors.New("Nimbus failed to post message")
// }
// return hex.DecodeString(C.GoString(hashC))
}
Loading

0 comments on commit 65edcb1

Please sign in to comment.