Skip to content
Snippets Groups Projects
Commit faaf9f73 authored by Hans Moog's avatar Hans Moog
Browse files

Feat: commit of initial packages

parent f9d47f24
No related branches found
No related tags found
No related merge requests found
Showing
with 869 additions and 0 deletions
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Project files
.idea
# Database directory
mainnetdb/
\ No newline at end of file
package accountability
import (
"github.com/dgraph-io/badger"
"github.com/iotaledger/goshimmer/packages/settings"
"github.com/iotaledger/goshimmer/packages/identity"
)
var OWN_ID *identity.Identity
func generateNewIdentity() *identity.Identity {
newIdentity := identity.GenerateRandomIdentity()
if err := settings.Set([]byte("ACCOUNTABILITY_PUBLIC_KEY"), newIdentity.PublicKey); err != nil {
panic(err)
}
if err := settings.Set([]byte("ACCOUNTABILITY_PRIVATE_KEY"), newIdentity.PrivateKey); err != nil {
panic(err)
}
return newIdentity
}
func getIdentity() *identity.Identity {
publicKey, err := settings.Get([]byte("ACCOUNTABILITY_PUBLIC_KEY"))
if err != nil {
if err == badger.ErrKeyNotFound {
return generateNewIdentity()
} else {
panic(err)
}
}
privateKey, err := settings.Get([]byte("ACCOUNTABILITY_PRIVATE_KEY"))
if err != nil {
if err == badger.ErrKeyNotFound {
return generateNewIdentity()
} else {
panic(err)
}
}
return identity.NewIdentity(publicKey, privateKey)
}
func init() {
OWN_ID = getIdentity()
}
\ No newline at end of file
package daemon
import (
"sync"
)
var (
running bool
runOnce sync.Once
shutdownOnce sync.Once
wg sync.WaitGroup
installWG sync.WaitGroup
ShutdownSignal = make(chan int, 1)
backgroundWorkers = make([]func(), 0)
backgroundWorkerChan = make(chan func(), 10)
)
var Events = daemonEvents{
Run: &callbackEvent{
callbacks: map[uintptr]Callback{},
},
Shutdown: &callbackEvent{
callbacks: map[uintptr]Callback{},
},
}
func init() {
shutdownOnce.Do(func() {})
go func() {
for {
backgroundWorker := <- backgroundWorkerChan
backgroundWorkers = append(backgroundWorkers, backgroundWorker)
installWG.Done()
if IsRunning() {
runBackgroundWorker(backgroundWorker)
}
}
}()
}
func runBackgroundWorker(backgroundWorker func()) {
wg.Add(1)
go func() {
backgroundWorker()
wg.Done()
}()
}
func runBackgroundWorkers() {
for _, backgroundWorker := range backgroundWorkers {
runBackgroundWorker(backgroundWorker)
}
}
func BackgroundWorker(handler func()) {
installWG.Add(1)
backgroundWorkerChan <- handler
}
func Run() {
runOnce.Do(func() {
installWG.Wait()
ShutdownSignal = make(chan int, 1)
running = true
Events.Run.Trigger()
runBackgroundWorkers()
shutdownOnce = sync.Once{}
})
wg.Wait()
}
func Shutdown() {
shutdownOnce.Do(func() {
close(ShutdownSignal)
running = false
Events.Shutdown.Trigger()
runOnce = sync.Once{}
})
}
func IsRunning() bool {
return running
}
package daemon
import "reflect"
type daemonEvents struct {
Run *callbackEvent
Shutdown *callbackEvent
}
type callbackEvent struct {
callbacks map[uintptr]Callback
}
func (this *callbackEvent) Attach(callback Callback) {
this.callbacks[reflect.ValueOf(callback).Pointer()] = callback
}
func (this *callbackEvent) Detach(callback Callback) {
delete(this.callbacks, reflect.ValueOf(callback).Pointer())
}
func (this *callbackEvent) Trigger() {
for _, callback := range this.callbacks {
callback()
}
}
package daemon
type Callback = func()
package database
import (
"github.com/dgraph-io/badger"
"os"
"path/filepath"
"sync"
)
var databasesByName = make(map[string]*databaseImpl)
var getLock sync.Mutex
var ErrKeyNotFound = badger.ErrKeyNotFound
type databaseImpl struct {
db *badger.DB
name string
openLock sync.Mutex
}
func Get(name string) (Database, error) {
getLock.Lock()
defer getLock.Unlock()
if database, exists := databasesByName[name]; exists {
return database, nil
}
database := &databaseImpl{
db: nil,
name: name,
}
if err := database.Open(); err != nil {
return nil, err
}
databasesByName[name] = database
return databasesByName[name], nil
}
func (this *databaseImpl) Open() error {
this.openLock.Lock()
defer this.openLock.Unlock()
if this.db == nil {
directory := *DIRECTORY.Value
if _, err := os.Stat(directory); os.IsNotExist(err) {
if err := os.Mkdir(directory, 0700); err != nil {
return err
}
}
opts := badger.DefaultOptions
opts.Dir = directory + string(filepath.Separator) + this.name
opts.ValueDir = opts.Dir
opts.Logger = &logger{}
opts.Truncate = true
db, err := badger.Open(opts)
if err != nil {
return err
}
this.db = db
}
return nil
}
func (this *databaseImpl) Set(key []byte, value []byte) error {
if err := this.db.Update(func(txn *badger.Txn) error { return txn.Set(key, value) }); err != nil {
return err
}
return nil
}
func (this *databaseImpl) Get(key []byte) ([]byte, error) {
var result []byte = nil
var err error = nil
err = this.db.View(func(txn *badger.Txn) error {
item, err := txn.Get(key)
if err != nil {
return err
}
return item.Value(func(val []byte) error {
result = append([]byte{}, val...)
return nil
})
})
return result, err
}
func (this *databaseImpl) Close() error {
this.openLock.Lock()
defer this.openLock.Unlock()
if this.db != nil {
err := this.db.Close()
this.db = nil
if err != nil {
return err
}
}
return nil
}
package database
type Database interface {
Open() error
Set(key []byte, value []byte) error
Get(key []byte) ([]byte, error)
Close() error
}
package database
type logger struct {}
func (this *logger) Errorf(string, ...interface{}) {
// disable logging
}
func (this *logger) Infof(string, ...interface{}) {
// disable logging
}
func (this *logger) Warningf(string, ...interface{}) {
// disable logging
}
package database
import (
"github.com/iotadevelopment/go/modules/parameter"
)
var DIRECTORY = parameter.AddString("DATABASE/DIRECTORY", "mainnetdb", "path to the database folder")
package identity
const (
PRIVATE_TYPE = IdentityType(0)
PUBLIC_TYPE = IdentityType(1)
PUBLIC_KEY_BYTE_LENGTH = 65
)
package identity
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"fmt"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/iotadevelopment/consensus/crypto"
)
type Identity struct {
Type IdentityType
Identifier []byte
StringIdentifier string
PublicKey []byte
PrivateKey []byte
}
func NewIdentity(publicKey []byte, optionalPrivateKey ... []byte) *Identity {
this := &Identity{
Identifier: crypto.Hash20(publicKey),
PublicKey: publicKey,
}
this.StringIdentifier = fmt.Sprintf("%x", this.Identifier)
if len(optionalPrivateKey) == 1 {
this.Type = PRIVATE_TYPE
this.PrivateKey = optionalPrivateKey[0]
} else {
this.Type = PUBLIC_TYPE
}
return this
}
func (this *Identity) Sign(data []byte) ([]byte, error) {
sha256Hasher := sha256.New()
sha256Hasher.Write(data)
sig, err := secp256k1.Sign(sha256Hasher.Sum(nil), this.PrivateKey)
if err != nil {
return nil, err
}
return sig, nil
}
func (this *Identity) VerifySignature(data []byte, signature []byte) bool {
sha256Hasher := sha256.New()
sha256Hasher.Write(data)
return secp256k1.VerifySignature(this.PublicKey, sha256Hasher.Sum(nil), signature[:64])
}
func GenerateRandomIdentity() *Identity {
// generate key pair
keyPair, err := ecdsa.GenerateKey(secp256k1.S256(), rand.Reader)
if err != nil {
panic(err)
}
// build public key bytes
publicKey := elliptic.Marshal(secp256k1.S256(), keyPair.X, keyPair.Y)
// build private key bytes
privkey := make([]byte, 32)
blob := keyPair.D.Bytes()
copy(privkey[32-len(blob):], blob)
return NewIdentity(publicKey, privkey)
}
func FromSignedData(data []byte, signature []byte) (*Identity, error) {
sha256Hasher := sha256.New()
sha256Hasher.Write(data)
pubKey, err := secp256k1.RecoverPubkey(sha256Hasher.Sum(nil), signature)
if err != nil {
return nil, err
}
return NewIdentity(pubKey), nil
}
package identity
type IdentityType int
package network
import (
"net"
"time"
)
type Connection interface {
GetProtocol() string
GetConnection() net.Conn
Write(data []byte)
OnReceiveData(callback DataConsumer) Connection
OnDisconnect(callback Callback) Connection
OnError(callback ErrorConsumer) Connection
TriggerReceiveData(data []byte) Connection
TriggerDisconnect() Connection
TriggerError(err error) Connection
SetTimeout(duration time.Duration) Connection
HandleConnection()
}
type Callback func()
type ErrorConsumer func(err error)
type DataConsumer func(data []byte)
package network
const (
READ_BUFFER_SIZE = 81920
)
package network
import (
"io"
"net"
"time"
)
type peerImplementation struct {
timeout time.Duration
protocol string
conn net.Conn
receiveDataHandlers []DataConsumer
disconnectHandlers []Callback
errorHandlers []ErrorConsumer
}
func NewPeer(protocol string, conn net.Conn) Connection {
this := &peerImplementation{
protocol: protocol,
conn: conn,
receiveDataHandlers: make([]DataConsumer, 0),
disconnectHandlers: make([]Callback, 0),
errorHandlers: make([]ErrorConsumer, 0),
}
return this
}
func (this *peerImplementation) SetTimeout(duration time.Duration) Connection {
this.timeout = duration
//this.conn.SetDeadline(time.Now().Add(this.timeout))
return this
}
func (this *peerImplementation) GetProtocol() string {
return this.protocol
}
func (this *peerImplementation) GetConnection() net.Conn {
return this.conn
}
func (this *peerImplementation) Write(data []byte) {
//this.conn.SetDeadline(time.Now().Add(this.timeout))
if _, err := this.conn.Write(data); err != nil {
this.TriggerError(err)
}
}
func (this *peerImplementation) OnReceiveData(callback DataConsumer) Connection {
this.receiveDataHandlers = append(this.receiveDataHandlers, callback)
return this
}
func (this *peerImplementation) OnDisconnect(callback Callback) Connection {
this.disconnectHandlers = append(this.disconnectHandlers, callback)
return this
}
func (this *peerImplementation) OnError(callback ErrorConsumer) Connection {
this.errorHandlers = append(this.errorHandlers, callback)
return this
}
func (this *peerImplementation) TriggerReceiveData(data []byte) Connection {
for _, receiveDataHandler := range this.receiveDataHandlers {
receiveDataHandler(data)
}
return this
}
func (this *peerImplementation) TriggerDisconnect() Connection {
for _, disconnectHandler := range this.disconnectHandlers {
disconnectHandler()
}
return this
}
func (this *peerImplementation) TriggerError(err error) Connection {
for _, errorHandler := range this.errorHandlers {
errorHandler(err)
}
return this
}
func (this *peerImplementation) HandleConnection() {
defer this.conn.Close()
defer this.TriggerDisconnect()
receiveBuffer := make([]byte, READ_BUFFER_SIZE)
for {
//this.conn.SetDeadline(time.Now().Add(this.timeout))
byteCount, err := this.conn.Read(receiveBuffer)
if err != nil {
if err != io.EOF {
this.TriggerError(err)
}
return
}
receivedData := make([]byte, byteCount)
copy(receivedData, receiveBuffer)
this.TriggerReceiveData(receivedData)
}
}
package tcp
import (
"github.com/iotaledger/goshimmer/packages/network"
"net"
"strconv"
)
type Server struct {
Socket net.Listener
Events serverEvents
}
func (this *Server) Shutdown() {
if this.Socket != nil {
socket := this.Socket
this.Socket = nil
socket.Close()
}
}
func (this *Server) Listen(port int) *Server {
socket, err := net.Listen("tcp4", "0.0.0.0:"+strconv.Itoa(port))
if err != nil {
this.Events.Error.Trigger(err)
return this
} else {
this.Socket = socket
}
this.Events.Start.Trigger()
defer this.Events.Shutdown.Trigger()
for this.Socket != nil {
if socket, err := this.Socket.Accept(); err != nil {
if this.Socket != nil {
this.Events.Error.Trigger(err)
}
} else {
peer := network.NewPeer("tcp", socket)
go this.Events.Connect.Trigger(peer)
}
}
return this
}
func NewServer() *Server {
return &Server{
Events: serverEvents{
Start: &callbackEvent{make(map[uintptr]Callback)},
Shutdown: &callbackEvent{make(map[uintptr]Callback)},
Connect: &peerConsumerEvent{make(map[uintptr]PeerConsumer)},
Error: &errorConsumerEvent{make(map[uintptr]ErrorConsumer)},
},
}
}
package tcp
import (
"github.com/iotaledger/goshimmer/packages/network"
"reflect"
)
type serverEvents struct {
Start *callbackEvent
Shutdown *callbackEvent
Connect *peerConsumerEvent
Error *errorConsumerEvent
}
// region callbackEvent /////////////////////////////////////////////////////////////////////////////////////////////////
type callbackEvent struct {
callbacks map[uintptr]Callback
}
func (this *callbackEvent) Attach(callback Callback) {
this.callbacks[reflect.ValueOf(callback).Pointer()] = callback
}
func (this *callbackEvent) Detach(callback Callback) {
delete(this.callbacks, reflect.ValueOf(callback).Pointer())
}
func (this *callbackEvent) Trigger() {
for _, callback := range this.callbacks {
callback()
}
}
// endregion ////////////////////////////////////////////////////////////////////////////////////////////////////////////
// region errorConsumerEvent ////////////////////////////////////////////////////////////////////////////////////////////
type errorConsumerEvent struct {
callbacks map[uintptr]ErrorConsumer
}
func (this *errorConsumerEvent) Attach(callback ErrorConsumer) {
this.callbacks[reflect.ValueOf(callback).Pointer()] = callback
}
func (this *errorConsumerEvent) Detach(callback ErrorConsumer) {
delete(this.callbacks, reflect.ValueOf(callback).Pointer())
}
func (this *errorConsumerEvent) Trigger(err error) {
for _, callback := range this.callbacks {
callback(err)
}
}
// endregion ////////////////////////////////////////////////////////////////////////////////////////////////////////////
// region peerConsumerEvent /////////////////////////////////////////////////////////////////////////////////////////////
type peerConsumerEvent struct {
callbacks map[uintptr]PeerConsumer
}
func (this *peerConsumerEvent) Attach(callback PeerConsumer) {
this.callbacks[reflect.ValueOf(callback).Pointer()] = callback
}
func (this *peerConsumerEvent) Detach(callback PeerConsumer) {
delete(this.callbacks, reflect.ValueOf(callback).Pointer())
}
func (this *peerConsumerEvent) Trigger(peer network.Connection) {
for _, callback := range this.callbacks {
callback(peer)
}
}
// endregion ////////////////////////////////////////////////////////////////////////////////////////////////////////////
package tcp
import "github.com/iotaledger/goshimmer/packages/network"
type Callback = func()
type ErrorConsumer = func(e error)
type PeerConsumer = func(peer network.Connection)
package udp
import (
"net"
"reflect"
)
//region peerConsumerEvent /////////////////////////////////////////////////////////////////////////////////////////////
type callbackEvent struct {
callbacks map[uintptr]Callback
}
func (this *callbackEvent) Attach(callback Callback) {
this.callbacks[reflect.ValueOf(callback).Pointer()] = callback
}
func (this *callbackEvent) Detach(callback Callback) {
delete(this.callbacks, reflect.ValueOf(callback).Pointer())
}
func (this *callbackEvent) Trigger() {
for _, callback := range this.callbacks {
callback()
}
}
//endregion ////////////////////////////////////////////////////////////////////////////////////////////////////////////
//region dataConsumerEvent /////////////////////////////////////////////////////////////////////////////////////////////
type dataConsumerEvent struct {
callbacks map[uintptr]AddressDataConsumer
}
func (this *dataConsumerEvent) Attach(callback AddressDataConsumer) {
this.callbacks[reflect.ValueOf(callback).Pointer()] = callback
}
func (this *dataConsumerEvent) Detach(callback AddressDataConsumer) {
delete(this.callbacks, reflect.ValueOf(callback).Pointer())
}
func (this *dataConsumerEvent) Trigger(addr *net.UDPAddr, data []byte) {
for _, callback := range this.callbacks {
callback(addr, data)
}
}
//endregion ////////////////////////////////////////////////////////////////////////////////////////////////////////////
//region errorConsumerEvent ////////////////////////////////////////////////////////////////////////////////////////////
type errorConsumerEvent struct {
callbacks map[uintptr]ErrorConsumer
}
func (this *errorConsumerEvent) Attach(callback ErrorConsumer) {
this.callbacks[reflect.ValueOf(callback).Pointer()] = callback
}
func (this *errorConsumerEvent) Detach(callback ErrorConsumer) {
delete(this.callbacks, reflect.ValueOf(callback).Pointer())
}
func (this *errorConsumerEvent) Trigger(err error) {
for _, callback := range this.callbacks {
callback(err)
}
}
//endregion ////////////////////////////////////////////////////////////////////////////////////////////////////////////
package udp
import (
"net"
)
type serverEvents struct {
Start *callbackEvent
Shutdown *callbackEvent
ReceiveData *dataConsumerEvent
Error *errorConsumerEvent
}
type Server struct {
Socket *net.UDPConn
Events serverEvents
}
func (this *Server) Shutdown() {
if this.Socket != nil {
socket := this.Socket
this.Socket = nil
socket.Close()
}
}
func (this *Server) Listen(address string, port int) {
if socket, err := net.ListenUDP("udp", &net.UDPAddr{
Port: port,
IP: net.ParseIP(address),
}); err != nil {
this.Events.Error.Trigger(err)
return
} else {
this.Socket = socket
}
this.Events.Start.Trigger()
defer this.Events.Shutdown.Trigger()
buf := make([]byte, 1500)
for this.Socket != nil {
if bytesRead, addr, err := this.Socket.ReadFromUDP(buf); err != nil {
if this.Socket != nil {
this.Events.Error.Trigger(err)
}
} else {
this.Events.ReceiveData.Trigger(addr, buf[:bytesRead])
}
}
}
func NewServer() *Server {
return &Server{
Events: serverEvents{
Start: &callbackEvent{make(map[uintptr]Callback)},
Shutdown: &callbackEvent{make(map[uintptr]Callback)},
ReceiveData: &dataConsumerEvent{make(map[uintptr]AddressDataConsumer)},
Error: &errorConsumerEvent{make(map[uintptr]ErrorConsumer)},
},
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment