Skip to content
Snippets Groups Projects
Unverified Commit 6edb4a48 authored by Hans Moog's avatar Hans Moog Committed by GitHub
Browse files

Develop.merge binary (#263)


* Feat: started to merge changes

* Refactor: moved parameter package to be a plugin (same with logger)

* Feat: first compiling version of new ontologoies merge

* Feat: ported additional plugins

* Feat: transaction get solid now

* Refactor: reverted some previous changes from debugging

* Feat: added a banner module for the cli interface

* Feat: added a plugin for the port checks

* Feat: fixed some bugs

* Refactor: reverted some changes

* Feat: reworked TransactionParser to use Errors

* Feat: TransactionParser uses Peer

* Feat: started to rework broadCastData webapi call

* Feat: refactored some plugins

* Fix: fixed test of tangle

* Refactor: changed tangle package in graph plugin

* Refactor: uncommented broken code

* Fix: fixed broken method signature in gossip test

* Feat: started adding value tangle

* Feat: adjusted to new hive.go

* Feat: upgraded hive.go

* Clean up PortCheck plugin and make it standalone #259 (#271)

Co-authored-by: default avatarHans Moog <hm@mkjc.net>

Co-authored-by: default avatarJonas Theis <mail@jonastheis.de>
parent 7f238124
No related branches found
No related tags found
No related merge requests found
Showing
with 541 additions and 112 deletions
...@@ -59,12 +59,16 @@ func TestTangle_AttachTransaction(t *testing.T) { ...@@ -59,12 +59,16 @@ func TestTangle_AttachTransaction(t *testing.T) {
} }
tangle.Events.TransactionAttached.Attach(events.NewClosure(func(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *transactionmetadata.CachedTransactionMetadata) { tangle.Events.TransactionAttached.Attach(events.NewClosure(func(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *transactionmetadata.CachedTransactionMetadata) {
cachedTransactionMetadata.Release()
cachedTransaction.Consume(func(transaction *transaction.Transaction) { cachedTransaction.Consume(func(transaction *transaction.Transaction) {
fmt.Println("ATTACHED:", transaction.GetId()) fmt.Println("ATTACHED:", transaction.GetId())
}) })
})) }))
tangle.Events.TransactionSolid.Attach(events.NewClosure(func(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *transactionmetadata.CachedTransactionMetadata) { tangle.Events.TransactionSolid.Attach(events.NewClosure(func(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *transactionmetadata.CachedTransactionMetadata) {
cachedTransactionMetadata.Release()
cachedTransaction.Consume(func(transaction *transaction.Transaction) { cachedTransaction.Consume(func(transaction *transaction.Transaction) {
fmt.Println("SOLID:", transaction.GetId()) fmt.Println("SOLID:", transaction.GetId())
}) })
......
package tipselector
import (
"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction"
"github.com/iotaledger/hive.go/events"
)
type Events struct {
TipAdded *events.Event
TipRemoved *events.Event
}
func transactionIdEvent(handler interface{}, params ...interface{}) {
handler.(func(transaction.Id))(params[0].(transaction.Id))
}
package tipselector
import (
"github.com/iotaledger/goshimmer/packages/binary/datastructure"
"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction"
"github.com/iotaledger/hive.go/events"
)
type TipSelector struct {
tips *datastructure.RandomMap
Events Events
}
func New() *TipSelector {
return &TipSelector{
tips: datastructure.NewRandomMap(),
Events: Events{
TipAdded: events.NewEvent(transactionIdEvent),
TipRemoved: events.NewEvent(transactionIdEvent),
},
}
}
func (tipSelector *TipSelector) AddTip(transaction *transaction.Transaction) {
transactionId := transaction.GetId()
if tipSelector.tips.Set(transactionId, transactionId) {
tipSelector.Events.TipAdded.Trigger(transactionId)
}
trunkTransactionId := transaction.GetTrunkTransactionId()
if _, deleted := tipSelector.tips.Delete(trunkTransactionId); deleted {
tipSelector.Events.TipRemoved.Trigger(trunkTransactionId)
}
branchTransactionId := transaction.GetBranchTransactionId()
if _, deleted := tipSelector.tips.Delete(branchTransactionId); deleted {
tipSelector.Events.TipRemoved.Trigger(branchTransactionId)
}
}
func (tipSelector *TipSelector) GetTips() (trunkTransaction, branchTransaction transaction.Id) {
tip := tipSelector.tips.RandomEntry()
if tip == nil {
trunkTransaction = transaction.EmptyId
branchTransaction = transaction.EmptyId
return
}
branchTransaction = tip.(transaction.Id)
if tipSelector.tips.Size() == 1 {
trunkTransaction = branchTransaction
return
}
trunkTransaction = tipSelector.tips.RandomEntry().(transaction.Id)
for trunkTransaction == branchTransaction && tipSelector.tips.Size() > 1 {
trunkTransaction = tipSelector.tips.RandomEntry().(transaction.Id)
}
return
}
func (tipSelector *TipSelector) GetTipCount() int {
return tipSelector.tips.Size()
}
package tipselector
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/iotaledger/goshimmer/packages/binary/identity"
"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction"
"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload/data"
)
func Test(t *testing.T) {
// create tip selector
tipSelector := New()
// check if first tips point to genesis
trunk1, branch1 := tipSelector.GetTips()
assert.Equal(t, transaction.EmptyId, trunk1)
assert.Equal(t, transaction.EmptyId, branch1)
// create a transaction and attach it
transaction1 := transaction.New(trunk1, branch1, identity.Generate(), data.New([]byte("testtransaction")))
tipSelector.AddTip(transaction1)
// check if the tip shows up in the tip count
assert.Equal(t, 1, tipSelector.GetTipCount())
// check if next tips point to our first transaction
trunk2, branch2 := tipSelector.GetTips()
assert.Equal(t, transaction1.GetId(), trunk2)
assert.Equal(t, transaction1.GetId(), branch2)
// create a 2nd transaction and attach it
transaction2 := transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), data.New([]byte("testtransaction")))
tipSelector.AddTip(transaction2)
// check if the tip shows up in the tip count
assert.Equal(t, 2, tipSelector.GetTipCount())
// attach a transaction to our two tips
trunk3, branch3 := tipSelector.GetTips()
transaction3 := transaction.New(trunk3, branch3, identity.Generate(), data.New([]byte("testtransaction")))
tipSelector.AddTip(transaction3)
// check if the tip shows replaces the current tips
trunk4, branch4 := tipSelector.GetTips()
assert.Equal(t, 1, tipSelector.GetTipCount())
assert.Equal(t, transaction3.GetId(), trunk4)
assert.Equal(t, transaction3.GetId(), branch4)
}
package builtinfilters package builtinfilters
import ( import (
"fmt"
"sync" "sync"
"github.com/iotaledger/hive.go/async" "github.com/iotaledger/hive.go/async"
"github.com/iotaledger/hive.go/autopeering/peer"
"github.com/iotaledger/hive.go/bytesfilter" "github.com/iotaledger/hive.go/bytesfilter"
) )
var ErrReceivedDuplicateBytes = fmt.Errorf("received duplicate bytes")
type RecentlySeenBytesFilter struct { type RecentlySeenBytesFilter struct {
bytesFilter *bytesfilter.BytesFilter bytesFilter *bytesfilter.BytesFilter
onAcceptCallback func(bytes []byte) onAcceptCallback func(bytes []byte, peer *peer.Peer)
onRejectCallback func(bytes []byte) onRejectCallback func(bytes []byte, err error, peer *peer.Peer)
workerPool async.WorkerPool workerPool async.WorkerPool
onAcceptCallbackMutex sync.RWMutex onAcceptCallbackMutex sync.RWMutex
...@@ -25,29 +29,29 @@ func NewRecentlySeenBytesFilter() (result *RecentlySeenBytesFilter) { ...@@ -25,29 +29,29 @@ func NewRecentlySeenBytesFilter() (result *RecentlySeenBytesFilter) {
return return
} }
func (filter *RecentlySeenBytesFilter) Filter(bytes []byte) { func (filter *RecentlySeenBytesFilter) Filter(bytes []byte, peer *peer.Peer) {
filter.workerPool.Submit(func() { filter.workerPool.Submit(func() {
if filter.bytesFilter.Add(bytes) { if filter.bytesFilter.Add(bytes) {
filter.getAcceptCallback()(bytes) filter.getAcceptCallback()(bytes, peer)
} else { } else {
filter.getRejectCallback()(bytes) filter.getRejectCallback()(bytes, ErrReceivedDuplicateBytes, peer)
} }
}) })
} }
func (filter *RecentlySeenBytesFilter) OnAccept(callback func(bytes []byte)) { func (filter *RecentlySeenBytesFilter) OnAccept(callback func(bytes []byte, peer *peer.Peer)) {
filter.onAcceptCallbackMutex.Lock() filter.onAcceptCallbackMutex.Lock()
filter.onAcceptCallback = callback filter.onAcceptCallback = callback
filter.onAcceptCallbackMutex.Unlock() filter.onAcceptCallbackMutex.Unlock()
} }
func (filter *RecentlySeenBytesFilter) OnReject(callback func(bytes []byte)) { func (filter *RecentlySeenBytesFilter) OnReject(callback func(bytes []byte, err error, peer *peer.Peer)) {
filter.onRejectCallbackMutex.Lock() filter.onRejectCallbackMutex.Lock()
filter.onRejectCallback = callback filter.onRejectCallback = callback
filter.onRejectCallbackMutex.Unlock() filter.onRejectCallbackMutex.Unlock()
} }
func (filter *RecentlySeenBytesFilter) getAcceptCallback() (result func(bytes []byte)) { func (filter *RecentlySeenBytesFilter) getAcceptCallback() (result func(bytes []byte, peer *peer.Peer)) {
filter.onAcceptCallbackMutex.Lock() filter.onAcceptCallbackMutex.Lock()
result = filter.onAcceptCallback result = filter.onAcceptCallback
filter.onAcceptCallbackMutex.Unlock() filter.onAcceptCallbackMutex.Unlock()
...@@ -55,7 +59,7 @@ func (filter *RecentlySeenBytesFilter) getAcceptCallback() (result func(bytes [] ...@@ -55,7 +59,7 @@ func (filter *RecentlySeenBytesFilter) getAcceptCallback() (result func(bytes []
return return
} }
func (filter *RecentlySeenBytesFilter) getRejectCallback() (result func(bytes []byte)) { func (filter *RecentlySeenBytesFilter) getRejectCallback() (result func(bytes []byte, err error, peer *peer.Peer)) {
filter.onRejectCallbackMutex.Lock() filter.onRejectCallbackMutex.Lock()
result = filter.onRejectCallback result = filter.onRejectCallback
filter.onRejectCallbackMutex.Unlock() filter.onRejectCallbackMutex.Unlock()
......
package builtinfilters package builtinfilters
import ( import (
"fmt"
"sync" "sync"
"github.com/iotaledger/hive.go/async" "github.com/iotaledger/hive.go/async"
"github.com/iotaledger/hive.go/autopeering/peer"
"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction"
) )
var ErrInvalidSignature = fmt.Errorf("invalid signature")
type TransactionSignatureFilter struct { type TransactionSignatureFilter struct {
onAcceptCallback func(tx *transaction.Transaction) onAcceptCallback func(tx *transaction.Transaction, peer *peer.Peer)
onRejectCallback func(tx *transaction.Transaction) onRejectCallback func(tx *transaction.Transaction, err error, peer *peer.Peer)
workerPool async.WorkerPool workerPool async.WorkerPool
onAcceptCallbackMutex sync.RWMutex onAcceptCallbackMutex sync.RWMutex
...@@ -23,23 +27,23 @@ func NewTransactionSignatureFilter() (result *TransactionSignatureFilter) { ...@@ -23,23 +27,23 @@ func NewTransactionSignatureFilter() (result *TransactionSignatureFilter) {
return return
} }
func (filter *TransactionSignatureFilter) Filter(tx *transaction.Transaction) { func (filter *TransactionSignatureFilter) Filter(tx *transaction.Transaction, peer *peer.Peer) {
filter.workerPool.Submit(func() { filter.workerPool.Submit(func() {
if tx.VerifySignature() { if tx.VerifySignature() {
filter.getAcceptCallback()(tx) filter.getAcceptCallback()(tx, peer)
} else { } else {
filter.getRejectCallback()(tx) filter.getRejectCallback()(tx, ErrInvalidSignature, peer)
} }
}) })
} }
func (filter *TransactionSignatureFilter) OnAccept(callback func(tx *transaction.Transaction)) { func (filter *TransactionSignatureFilter) OnAccept(callback func(tx *transaction.Transaction, peer *peer.Peer)) {
filter.onAcceptCallbackMutex.Lock() filter.onAcceptCallbackMutex.Lock()
filter.onAcceptCallback = callback filter.onAcceptCallback = callback
filter.onAcceptCallbackMutex.Unlock() filter.onAcceptCallbackMutex.Unlock()
} }
func (filter *TransactionSignatureFilter) OnReject(callback func(tx *transaction.Transaction)) { func (filter *TransactionSignatureFilter) OnReject(callback func(tx *transaction.Transaction, err error, peer *peer.Peer)) {
filter.onRejectCallbackMutex.Lock() filter.onRejectCallbackMutex.Lock()
filter.onRejectCallback = callback filter.onRejectCallback = callback
filter.onRejectCallbackMutex.Unlock() filter.onRejectCallbackMutex.Unlock()
...@@ -49,7 +53,7 @@ func (filter *TransactionSignatureFilter) Shutdown() { ...@@ -49,7 +53,7 @@ func (filter *TransactionSignatureFilter) Shutdown() {
filter.workerPool.ShutdownGracefully() filter.workerPool.ShutdownGracefully()
} }
func (filter *TransactionSignatureFilter) getAcceptCallback() (result func(tx *transaction.Transaction)) { func (filter *TransactionSignatureFilter) getAcceptCallback() (result func(tx *transaction.Transaction, peer *peer.Peer)) {
filter.onAcceptCallbackMutex.RLock() filter.onAcceptCallbackMutex.RLock()
result = filter.onAcceptCallback result = filter.onAcceptCallback
filter.onAcceptCallbackMutex.RUnlock() filter.onAcceptCallbackMutex.RUnlock()
...@@ -57,7 +61,7 @@ func (filter *TransactionSignatureFilter) getAcceptCallback() (result func(tx *t ...@@ -57,7 +61,7 @@ func (filter *TransactionSignatureFilter) getAcceptCallback() (result func(tx *t
return return
} }
func (filter *TransactionSignatureFilter) getRejectCallback() (result func(tx *transaction.Transaction)) { func (filter *TransactionSignatureFilter) getRejectCallback() (result func(tx *transaction.Transaction, err error, peer *peer.Peer)) {
filter.onRejectCallbackMutex.RLock() filter.onRejectCallbackMutex.RLock()
result = filter.onRejectCallback result = filter.onRejectCallback
filter.onRejectCallbackMutex.RUnlock() filter.onRejectCallbackMutex.RUnlock()
......
package transactionparser package transactionparser
import (
"github.com/iotaledger/hive.go/autopeering/peer"
)
type BytesFilter interface { type BytesFilter interface {
Filter(bytes []byte) Filter(bytes []byte, peer *peer.Peer)
OnAccept(callback func(bytes []byte)) OnAccept(callback func(bytes []byte, peer *peer.Peer))
OnReject(callback func(bytes []byte)) OnReject(callback func(bytes []byte, err error, peer *peer.Peer))
Shutdown() Shutdown()
} }
package transactionparser package transactionparser
import ( import (
"github.com/iotaledger/hive.go/autopeering/peer"
"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction"
) )
type TransactionFilter interface { type TransactionFilter interface {
Filter(tx *transaction.Transaction) Filter(tx *transaction.Transaction, peer *peer.Peer)
OnAccept(callback func(tx *transaction.Transaction)) OnAccept(callback func(tx *transaction.Transaction, peer *peer.Peer))
OnReject(callback func(tx *transaction.Transaction)) OnReject(callback func(tx *transaction.Transaction, err error, peer *peer.Peer))
Shutdown() Shutdown()
} }
...@@ -3,6 +3,8 @@ package transactionparser ...@@ -3,6 +3,8 @@ package transactionparser
import ( import (
"sync" "sync"
"github.com/iotaledger/hive.go/autopeering/peer"
"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction"
"github.com/iotaledger/goshimmer/packages/binary/tangle/transactionparser/builtinfilters" "github.com/iotaledger/goshimmer/packages/binary/tangle/transactionparser/builtinfilters"
...@@ -28,13 +30,13 @@ func New() (result *TransactionParser) { ...@@ -28,13 +30,13 @@ func New() (result *TransactionParser) {
Events: transactionParserEvents{ Events: transactionParserEvents{
BytesRejected: events.NewEvent(func(handler interface{}, params ...interface{}) { BytesRejected: events.NewEvent(func(handler interface{}, params ...interface{}) {
handler.(func([]byte))(params[0].([]byte)) handler.(func([]byte, error, *peer.Peer))(params[0].([]byte), params[1].(error), params[2].(*peer.Peer))
}), }),
TransactionParsed: events.NewEvent(func(handler interface{}, params ...interface{}) { TransactionParsed: events.NewEvent(func(handler interface{}, params ...interface{}) {
handler.(func(*transaction.Transaction))(params[0].(*transaction.Transaction)) handler.(func(*transaction.Transaction, *peer.Peer))(params[0].(*transaction.Transaction), params[1].(*peer.Peer))
}), }),
TransactionRejected: events.NewEvent(func(handler interface{}, params ...interface{}) { TransactionRejected: events.NewEvent(func(handler interface{}, params ...interface{}) {
handler.(func(*transaction.Transaction))(params[0].(*transaction.Transaction)) handler.(func(*transaction.Transaction, error, *peer.Peer))(params[0].(*transaction.Transaction), params[1].(error), params[2].(*peer.Peer))
}), }),
}, },
} }
...@@ -46,11 +48,11 @@ func New() (result *TransactionParser) { ...@@ -46,11 +48,11 @@ func New() (result *TransactionParser) {
return return
} }
func (transactionParser *TransactionParser) Parse(transactionBytes []byte) { func (transactionParser *TransactionParser) Parse(transactionBytes []byte, peer *peer.Peer) {
transactionParser.setupBytesFilterDataFlow() transactionParser.setupBytesFilterDataFlow()
transactionParser.setupTransactionsFilterDataFlow() transactionParser.setupTransactionsFilterDataFlow()
transactionParser.bytesFilters[0].Filter(transactionBytes) transactionParser.bytesFilters[0].Filter(transactionBytes, peer)
} }
func (transactionParser *TransactionParser) AddBytesFilter(filter BytesFilter) { func (transactionParser *TransactionParser) AddBytesFilter(filter BytesFilter) {
...@@ -99,7 +101,9 @@ func (transactionParser *TransactionParser) setupBytesFilterDataFlow() { ...@@ -99,7 +101,9 @@ func (transactionParser *TransactionParser) setupBytesFilterDataFlow() {
} else { } else {
transactionParser.bytesFilters[i].OnAccept(transactionParser.bytesFilters[i+1].Filter) transactionParser.bytesFilters[i].OnAccept(transactionParser.bytesFilters[i+1].Filter)
} }
transactionParser.bytesFilters[i].OnReject(func(bytes []byte) { transactionParser.Events.BytesRejected.Trigger(bytes) }) transactionParser.bytesFilters[i].OnReject(func(bytes []byte, err error, peer *peer.Peer) {
transactionParser.Events.BytesRejected.Trigger(bytes, err, peer)
})
} }
} }
transactionParser.bytesFiltersMutex.Unlock() transactionParser.bytesFiltersMutex.Unlock()
...@@ -117,21 +121,24 @@ func (transactionParser *TransactionParser) setupTransactionsFilterDataFlow() { ...@@ -117,21 +121,24 @@ func (transactionParser *TransactionParser) setupTransactionsFilterDataFlow() {
numberOfTransactionFilters := len(transactionParser.transactionFilters) numberOfTransactionFilters := len(transactionParser.transactionFilters)
for i := 0; i < numberOfTransactionFilters; i++ { for i := 0; i < numberOfTransactionFilters; i++ {
if i == numberOfTransactionFilters-1 { if i == numberOfTransactionFilters-1 {
transactionParser.transactionFilters[i].OnAccept(func(tx *transaction.Transaction) { transactionParser.Events.TransactionParsed.Trigger(tx) }) transactionParser.transactionFilters[i].OnAccept(func(tx *transaction.Transaction, peer *peer.Peer) {
transactionParser.Events.TransactionParsed.Trigger(tx, peer)
})
} else { } else {
transactionParser.transactionFilters[i].OnAccept(transactionParser.transactionFilters[i+1].Filter) transactionParser.transactionFilters[i].OnAccept(transactionParser.transactionFilters[i+1].Filter)
} }
transactionParser.transactionFilters[i].OnReject(func(tx *transaction.Transaction) { transactionParser.Events.TransactionRejected.Trigger(tx) }) transactionParser.transactionFilters[i].OnReject(func(tx *transaction.Transaction, err error, peer *peer.Peer) {
transactionParser.Events.TransactionRejected.Trigger(tx, err, peer)
})
} }
} }
transactionParser.transactionFiltersMutex.Unlock() transactionParser.transactionFiltersMutex.Unlock()
} }
func (transactionParser *TransactionParser) parseTransaction(bytes []byte) { func (transactionParser *TransactionParser) parseTransaction(bytes []byte, peer *peer.Peer) {
if parsedTransaction, err := transaction.FromBytes(bytes); err != nil { if parsedTransaction, err := transaction.FromBytes(bytes); err != nil {
// trigger parsingError transactionParser.Events.BytesRejected.Trigger(bytes, err, peer)
panic(err)
} else { } else {
transactionParser.transactionFilters[0].Filter(parsedTransaction) transactionParser.transactionFilters[0].Filter(parsedTransaction, peer)
} }
} }
...@@ -19,7 +19,7 @@ func BenchmarkTransactionParser_ParseBytesSame(b *testing.B) { ...@@ -19,7 +19,7 @@ func BenchmarkTransactionParser_ParseBytesSame(b *testing.B) {
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
txParser.Parse(txBytes) txParser.Parse(txBytes, nil)
} }
txParser.Shutdown() txParser.Shutdown()
...@@ -36,7 +36,7 @@ func BenchmarkTransactionParser_ParseBytesDifferent(b *testing.B) { ...@@ -36,7 +36,7 @@ func BenchmarkTransactionParser_ParseBytesDifferent(b *testing.B) {
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
txParser.Parse(transactionBytes[i]) txParser.Parse(transactionBytes[i], nil)
} }
txParser.Shutdown() txParser.Shutdown()
...@@ -46,7 +46,7 @@ func TestTransactionParser_ParseTransaction(t *testing.T) { ...@@ -46,7 +46,7 @@ func TestTransactionParser_ParseTransaction(t *testing.T) {
tx := transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), data.New([]byte("Test"))) tx := transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), data.New([]byte("Test")))
txParser := New() txParser := New()
txParser.Parse(tx.GetBytes()) txParser.Parse(tx.GetBytes(), nil)
txParser.Events.TransactionParsed.Attach(events.NewClosure(func(tx *transaction.Transaction) { txParser.Events.TransactionParsed.Attach(events.NewClosure(func(tx *transaction.Transaction) {
fmt.Println("PARSED!!!") fmt.Println("PARSED!!!")
......
package valuetangle
import (
"sync"
"github.com/iotaledger/hive.go/objectstorage"
"golang.org/x/crypto/blake2b"
"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload"
)
type Payload struct {
objectstorage.StorableObjectFlags
id *PayloadId
trunkPayloadId PayloadId
branchPayloadId PayloadId
transfer *Transfer
bytes []byte
idMutex sync.RWMutex
bytesMutex sync.RWMutex
}
func NewPayload(trunkPayloadId, branchPayloadId PayloadId, valueTransfer *Transfer) *Payload {
return &Payload{
trunkPayloadId: trunkPayloadId,
branchPayloadId: branchPayloadId,
transfer: valueTransfer,
}
}
func (payload *Payload) GetId() PayloadId {
// acquire lock for reading id
payload.idMutex.RLock()
// return if id has been calculated already
if payload.id != nil {
defer payload.idMutex.RUnlock()
return *payload.id
}
// switch to write lock
payload.idMutex.RUnlock()
payload.idMutex.Lock()
defer payload.idMutex.Unlock()
// return if id has been calculated in the mean time
if payload.id != nil {
return *payload.id
}
// otherwise calculate the id
transferId := payload.GetTransfer().GetId()
marshalUtil := marshalutil.New(PayloadIdLength + PayloadIdLength + TransferIdLength)
marshalUtil.WriteBytes(payload.trunkPayloadId[:])
marshalUtil.WriteBytes(payload.branchPayloadId[:])
marshalUtil.WriteBytes(transferId[:])
var id PayloadId = blake2b.Sum256(marshalUtil.Bytes())
payload.id = &id
return id
}
func (payload *Payload) GetTrunkPayloadId() PayloadId {
return payload.trunkPayloadId
}
func (payload *Payload) GetBranchPayloadId() PayloadId {
return payload.branchPayloadId
}
func (payload *Payload) GetTransfer() *Transfer {
return payload.transfer
}
// region Payload implementation ///////////////////////////////////////////////////////////////////////////////////////
var Type = payload.Type(1)
func (payload *Payload) GetType() payload.Type {
return Type
}
func (payload *Payload) MarshalBinary() (bytes []byte, err error) {
// acquire lock for reading bytes
payload.bytesMutex.RLock()
// return if bytes have been determined already
if bytes = payload.bytes; bytes != nil {
defer payload.bytesMutex.RUnlock()
return
}
// switch to write lock
payload.bytesMutex.RUnlock()
payload.bytesMutex.Lock()
defer payload.bytesMutex.Unlock()
// return if bytes have been determined in the mean time
if bytes = payload.bytes; bytes != nil {
return
}
// retrieve bytes of transfer
transferBytes, err := payload.GetTransfer().MarshalBinary()
if err != nil {
return
}
// marshal fields
marshalUtil := marshalutil.New(PayloadIdLength + PayloadIdLength + TransferIdLength)
marshalUtil.WriteBytes(payload.trunkPayloadId[:])
marshalUtil.WriteBytes(payload.branchPayloadId[:])
marshalUtil.WriteBytes(transferBytes)
bytes = marshalUtil.Bytes()
// store result
payload.bytes = bytes
return
}
func (payload *Payload) UnmarshalBinary(data []byte) (err error) {
marshalUtil := marshalutil.New(data)
trunkTransactionIdBytes, err := marshalUtil.ReadBytes(PayloadIdLength)
if err != nil {
return
}
branchTransactionIdBytes, err := marshalUtil.ReadBytes(PayloadIdLength)
if err != nil {
return
}
valueTransfer := &Transfer{}
if err = valueTransfer.UnmarshalBinary(marshalUtil.ReadRemainingBytes()); err != nil {
return
}
payload.trunkPayloadId = NewPayloadId(trunkTransactionIdBytes)
payload.branchPayloadId = NewPayloadId(branchTransactionIdBytes)
payload.transfer = valueTransfer
payload.bytes = data
return
}
func init() {
payload.RegisterType(Type, func(data []byte) (payload payload.Payload, err error) {
payload = &Payload{}
err = payload.UnmarshalBinary(data)
return
})
}
// define contract (ensure that the struct fulfills the corresponding interface)
var _ payload.Payload = &Payload{}
// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
// region StorableObject implementation ////////////////////////////////////////////////////////////////////////////////
// MarshalBinary() (bytes []byte, err error) already implemented by Payload
// UnmarshalBinary(data []byte) (err error) already implemented by Payload
func (payload *Payload) GetStorageKey() []byte {
id := payload.GetId()
return id[:]
}
func (payload *Payload) Update(other objectstorage.StorableObject) {
panic("a Payload should never be updated")
}
// define contract (ensure that the struct fulfills the corresponding interface)
var _ objectstorage.StorableObject = &Payload{}
// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
package valuetangle
import (
"github.com/mr-tron/base58"
)
type PayloadId [PayloadIdLength]byte
func NewPayloadId(idBytes []byte) (result PayloadId) {
copy(result[:], idBytes)
return
}
func (id PayloadId) String() string {
return base58.Encode(id[:])
}
var EmptyPayloadId PayloadId
const PayloadIdLength = 32
package test
import (
"fmt"
"testing"
"github.com/iotaledger/goshimmer/packages/binary/valuetangle"
)
func TestPayload(t *testing.T) {
transfer := valuetangle.NewTransfer()
fmt.Println(transfer.GetId())
payload := valuetangle.NewPayload(valuetangle.EmptyPayloadId, valuetangle.EmptyPayloadId, transfer)
fmt.Println(payload.GetId())
}
package valuetangle
import (
"sync"
"github.com/iotaledger/hive.go/objectstorage"
"golang.org/x/crypto/blake2b"
)
type Transfer struct {
objectstorage.StorableObjectFlags
id *TransferId
bytes []byte
idMutex sync.RWMutex
bytesMutex sync.RWMutex
}
func NewTransfer() *Transfer {
return &Transfer{}
}
func FromStorage(key []byte) *Transfer {
id := NewTransferId(key)
return &Transfer{
id: &id,
}
}
func (transfer *Transfer) GetId() TransferId {
// acquire lock for reading id
transfer.idMutex.RLock()
// return if id has been calculated already
if transfer.id != nil {
defer transfer.idMutex.RUnlock()
return *transfer.id
}
// switch to write lock
transfer.idMutex.RUnlock()
transfer.idMutex.Lock()
defer transfer.idMutex.Unlock()
// return if id has been calculated in the mean time
if transfer.id != nil {
return *transfer.id
}
// otherwise calculate the PayloadId
transfer.id = transfer.calculateId()
return *transfer.id
}
func (transfer *Transfer) calculateId() *TransferId {
bytes, _ := transfer.MarshalBinary()
id := blake2b.Sum256(bytes)
result := NewTransferId(id[:])
return &result
}
func (transfer *Transfer) Update(other objectstorage.StorableObject) {
panic("implement me")
}
func (transfer *Transfer) GetStorageKey() []byte {
panic("implement me")
}
func (transfer *Transfer) MarshalBinary() ([]byte, error) {
return nil, nil
}
func (transfer *Transfer) UnmarshalBinary(data []byte) error {
panic("implement me")
}
// define contracts (ensure that the struct fulfills the corresponding interfaces
var _ objectstorage.StorableObject = &Transfer{}
package valuetangle
import (
"github.com/mr-tron/base58"
)
type TransferId [TransferIdLength]byte
func NewTransferId(idBytes []byte) (result TransferId) {
copy(result[:], idBytes)
return
}
func (id TransferId) String() string {
return base58.Encode(id[:])
}
const TransferIdLength = 32
...@@ -8,9 +8,10 @@ import ( ...@@ -8,9 +8,10 @@ import (
"github.com/dgraph-io/badger/v2" "github.com/dgraph-io/badger/v2"
"github.com/dgraph-io/badger/v2/options" "github.com/dgraph-io/badger/v2/options"
"github.com/iotaledger/goshimmer/packages/parameter"
"github.com/iotaledger/hive.go/database" "github.com/iotaledger/hive.go/database"
"github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/logger"
"github.com/iotaledger/goshimmer/plugins/config"
) )
var ( var (
...@@ -34,7 +35,7 @@ func Get(dbPrefix byte, optionalBadger ...*badger.DB) (Database, error) { ...@@ -34,7 +35,7 @@ func Get(dbPrefix byte, optionalBadger ...*badger.DB) (Database, error) {
func GetBadgerInstance() *badger.DB { func GetBadgerInstance() *badger.DB {
once.Do(func() { once.Do(func() {
dbDir := parameter.NodeConfig.GetString(CFG_DIRECTORY) dbDir := config.Node.GetString(CFG_DIRECTORY)
var dbDirClear bool var dbDirClear bool
// check whether the database is new, by checking whether any file exists within // check whether the database is new, by checking whether any file exists within
...@@ -57,12 +58,16 @@ func GetBadgerInstance() *badger.DB { ...@@ -57,12 +58,16 @@ func GetBadgerInstance() *badger.DB {
opts = opts.WithTruncate(true) opts = opts.WithTruncate(true)
} }
opts.SyncWrites = false
opts.TableLoadingMode = options.MemoryMap
opts.ValueLogLoadingMode = options.MemoryMap
opts.CompactL0OnClose = false opts.CompactL0OnClose = false
opts.KeepL0InMemory = false opts.KeepL0InMemory = false
opts.VerifyValueChecksum = false opts.VerifyValueChecksum = false
opts.ZSTDCompressionLevel = 1 opts.ZSTDCompressionLevel = 1
opts.Compression = options.None opts.Compression = options.None
opts.MaxCacheSize = 50000000 opts.MaxCacheSize = 50000000
opts.EventLogging = false
db, err := database.CreateDB(dbDir, opts) db, err := database.CreateDB(dbDir, opts)
if err != nil { if err != nil {
......
...@@ -6,6 +6,8 @@ import ( ...@@ -6,6 +6,8 @@ import (
"net" "net"
"sync" "sync"
"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
pb "github.com/iotaledger/goshimmer/packages/gossip/proto" pb "github.com/iotaledger/goshimmer/packages/gossip/proto"
"github.com/iotaledger/goshimmer/packages/gossip/server" "github.com/iotaledger/goshimmer/packages/gossip/server"
...@@ -24,7 +26,7 @@ var ( ...@@ -24,7 +26,7 @@ var (
) )
// GetTransaction defines a function that returns the transaction data with the given hash. // GetTransaction defines a function that returns the transaction data with the given hash.
type GetTransaction func(txHash []byte) ([]byte, error) type GetTransaction func(transactionId transaction.Id) ([]byte, error)
type Manager struct { type Manager struct {
local *peer.Local local *peer.Local
...@@ -254,7 +256,7 @@ func (m *Manager) handlePacket(data []byte, p *peer.Peer) error { ...@@ -254,7 +256,7 @@ func (m *Manager) handlePacket(data []byte, p *peer.Peer) error {
} }
m.log.Debugw("received message", "type", "TRANSACTION_REQUEST", "id", p.ID()) m.log.Debugw("received message", "type", "TRANSACTION_REQUEST", "id", p.ID())
// do something // do something
tx, err := m.getTransaction(msg.GetHash()) tx, err := m.getTransaction(transaction.NewId(msg.GetHash()))
if err != nil { if err != nil {
m.log.Debugw("error getting transaction", "hash", msg.GetHash(), "err", err) m.log.Debugw("error getting transaction", "hash", msg.GetHash(), "err", err)
} else { } else {
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction"
"github.com/iotaledger/goshimmer/packages/database/mapdb" "github.com/iotaledger/goshimmer/packages/database/mapdb"
pb "github.com/iotaledger/goshimmer/packages/gossip/proto" pb "github.com/iotaledger/goshimmer/packages/gossip/proto"
"github.com/iotaledger/goshimmer/packages/gossip/server" "github.com/iotaledger/goshimmer/packages/gossip/server"
...@@ -26,7 +27,7 @@ var ( ...@@ -26,7 +27,7 @@ var (
testTxData = []byte("testTx") testTxData = []byte("testTx")
) )
func getTestTransaction([]byte) ([]byte, error) { return testTxData, nil } func getTestTransaction(transaction.Id) ([]byte, error) { return testTxData, nil }
func TestClose(t *testing.T) { func TestClose(t *testing.T) {
_, detach := newEventMock(t) _, detach := newEventMock(t)
......
package parameter
import (
"github.com/iotaledger/hive.go/logger"
"github.com/iotaledger/hive.go/parameter"
flag "github.com/spf13/pflag"
"github.com/spf13/viper"
)
var (
// flags
configName = flag.StringP("config", "c", "config", "Filename of the config file without the file extension")
configDirPath = flag.StringP("config-dir", "d", ".", "Path to the directory containing the config file")
// viper
NodeConfig *viper.Viper
// logger
defaultLoggerConfig = logger.Config{
Level: "info",
DisableCaller: false,
DisableStacktrace: false,
Encoding: "console",
OutputPaths: []string{"goshimmer.log"},
DisableEvents: false,
}
)
func init() {
// set the default logger config
NodeConfig = viper.New()
NodeConfig.SetDefault(logger.ViperKey, defaultLoggerConfig)
}
// FetchConfig fetches config values from a dir defined via CLI flag --config-dir (or the current working dir if not set).
//
// It automatically reads in a single config file starting with "config" (can be changed via the --config CLI flag)
// and ending with: .json, .toml, .yaml or .yml (in this sequence).
func FetchConfig(printConfig bool, ignoreSettingsAtPrint ...[]string) error {
err := parameter.LoadConfigFile(NodeConfig, *configDirPath, *configName, true, false)
if err != nil {
return err
}
if printConfig {
parameter.PrintConfig(NodeConfig, ignoreSettingsAtPrint...)
}
return nil
}
// LoadDefaultConfig only binds the flags, but does not load any config file.
func LoadDefaultConfig(printConfig bool) error {
// only bind the flags
flag.Parse()
err := NodeConfig.BindPFlags(flag.CommandLine)
if err != nil {
return err
}
if printConfig {
parameter.PrintConfig(NodeConfig)
}
return nil
}
...@@ -3,15 +3,13 @@ package shutdown ...@@ -3,15 +3,13 @@ package shutdown
const ( const (
ShutdownPriorityTangle = iota ShutdownPriorityTangle = iota
ShutdownPriorityRemoteLog ShutdownPriorityRemoteLog
ShutdownPrioritySolidifier
ShutdownPriorityBundleProcessor
ShutdownPriorityAnalysis ShutdownPriorityAnalysis
ShutdownPriorityMetrics ShutdownPriorityMetrics
ShutdownPriorityAutopeering ShutdownPriorityAutopeering
ShutdownPriorityGossip ShutdownPriorityGossip
ShutdownPriorityWebAPI ShutdownPriorityWebAPI
ShutdownPriorityGraph
ShutdownPriorityTangleSpammer
ShutdownPrioritySPA ShutdownPrioritySPA
ShutdownPriorityGraph
ShutdownPrioritySpammer
ShutdownPriorityBadgerGarbageCollection ShutdownPriorityBadgerGarbageCollection
) )
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment