Skip to content
Snippets Groups Projects
Commit fea368cb authored by capossele's avatar capossele
Browse files

Merge remote-tracking branch 'origin/develop' into feat/autopeering-version

parents 467edf8c fc533afd
No related branches found
No related tags found
No related merge requests found
Showing
with 508 additions and 160 deletions
......@@ -15,6 +15,8 @@ jobs:
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Copy config.default.json to config.json
run: cp config.default.json config.json
- name: Release GoShimmer
run: goreleaser --rm-dist
env:
......
......@@ -27,3 +27,5 @@ objectsdb/
.DS_Store
shimmer
goshimmer
config.json
\ No newline at end of file
......@@ -148,7 +148,16 @@ If Go is installed, you should see the version that's installed.
2. Change into the `goshimmer` directory
3. Use one of the following commands to build your executable file, depending on your operating system
3. Copy and adjust `config.default.json`
```bash
# Linux and macOS
cp config.default.json config.json
# Windows
copy config.default.json config.json
```
4. Use one of the following commands to build your executable file, depending on your operating system
```bash
# Linux and macOS
......
File moved
module github.com/iotaledger/goshimmer
go 1.13
go 1.14
require (
github.com/dgraph-io/badger/v2 v2.0.2
......
......@@ -4,66 +4,21 @@ import (
"net/http"
_ "net/http/pprof"
"github.com/iotaledger/goshimmer/plugins/analysis"
"github.com/iotaledger/goshimmer/plugins/autopeering"
"github.com/iotaledger/goshimmer/plugins/banner"
"github.com/iotaledger/goshimmer/plugins/cli"
"github.com/iotaledger/goshimmer/pluginmgr/core"
"github.com/iotaledger/goshimmer/pluginmgr/research"
"github.com/iotaledger/goshimmer/pluginmgr/ui"
"github.com/iotaledger/goshimmer/pluginmgr/webapi"
"github.com/iotaledger/goshimmer/plugins/config"
"github.com/iotaledger/goshimmer/plugins/gossip"
"github.com/iotaledger/goshimmer/plugins/gracefulshutdown"
"github.com/iotaledger/goshimmer/plugins/logger"
"github.com/iotaledger/goshimmer/plugins/metrics"
"github.com/iotaledger/goshimmer/plugins/portcheck"
"github.com/iotaledger/goshimmer/plugins/remotelog"
"github.com/iotaledger/goshimmer/plugins/spa"
"github.com/iotaledger/goshimmer/plugins/tangle"
"github.com/iotaledger/goshimmer/plugins/webapi"
webapi_broadcastData "github.com/iotaledger/goshimmer/plugins/webapi/broadcastData"
webapi_gtta "github.com/iotaledger/goshimmer/plugins/webapi/gtta"
webapi_spammer "github.com/iotaledger/goshimmer/plugins/webapi/spammer"
webapi_auth "github.com/iotaledger/goshimmer/plugins/webauth"
"github.com/iotaledger/hive.go/node"
)
func main() {
config.Init()
go http.ListenAndServe("localhost:6061", nil) // pprof Server for Debbuging Mutexes
node.Run(
node.Plugins(
banner.PLUGIN,
config.PLUGIN,
logger.PLUGIN,
cli.PLUGIN,
remotelog.PLUGIN,
portcheck.PLUGIN,
autopeering.PLUGIN,
tangle.PLUGIN,
gossip.PLUGIN,
gracefulshutdown.PLUGIN,
analysis.PLUGIN,
metrics.PLUGIN,
webapi.PLUGIN,
webapi_auth.PLUGIN,
webapi_gtta.PLUGIN,
webapi_spammer.PLUGIN,
webapi_broadcastData.PLUGIN,
spa.PLUGIN,
/*
webapi_getTransactionTrytesByHash.PLUGIN,
webapi_getTransactionObjectsByHash.PLUGIN,
webapi_findTransactionHashes.PLUGIN,
webapi_getNeighbors.PLUGIN,
//graph.PLUGIN,
*/
),
core.PLUGINS,
research.PLUGINS,
ui.PLUGINS,
webapi.PLUGINS,
)
}
package orderedmap
type Element struct {
key interface{}
value interface{}
prev *Element
next *Element
}
package orderedmap
import (
"sync"
)
type OrderedMap struct {
head *Element
tail *Element
dictionary map[interface{}]*Element
size int
mutex sync.RWMutex
}
func New() *OrderedMap {
return &OrderedMap{
dictionary: make(map[interface{}]*Element),
}
}
func (orderedMap *OrderedMap) Get(key interface{}) (interface{}, bool) {
orderedMap.mutex.RLock()
defer orderedMap.mutex.RUnlock()
if orderedMapElement, orderedMapElementExists := orderedMap.dictionary[key]; !orderedMapElementExists {
return nil, false
} else {
return orderedMapElement.value, true
}
}
func (orderedMap *OrderedMap) Set(key interface{}, newValue interface{}) bool {
if oldValue, oldValueExists := orderedMap.Get(key); oldValueExists && oldValue == newValue {
return false
}
orderedMap.mutex.Lock()
defer orderedMap.mutex.Unlock()
if oldValue, oldValueExists := orderedMap.dictionary[key]; oldValueExists {
if oldValue.value == newValue {
return false
}
oldValue.value = newValue
return true
}
newElement := &Element{
key: key,
value: newValue,
}
if orderedMap.head == nil {
orderedMap.head = newElement
} else {
orderedMap.tail.next = newElement
newElement.prev = orderedMap.tail
}
orderedMap.tail = newElement
orderedMap.size++
orderedMap.dictionary[key] = newElement
return true
}
func (orderedMap *OrderedMap) ForEach(consumer func(key, value interface{}) bool) {
currentEntry := orderedMap.head
for currentEntry != nil {
if !consumer(currentEntry.key, currentEntry.value) {
return
}
currentEntry = currentEntry.next
}
}
func (orderedMap *OrderedMap) Delete(key interface{}) bool {
if _, valueExists := orderedMap.Get(key); !valueExists {
return false
}
orderedMap.mutex.Lock()
defer orderedMap.mutex.Unlock()
value, valueExists := orderedMap.dictionary[key]
if !valueExists {
return false
}
delete(orderedMap.dictionary, key)
orderedMap.size--
if value.prev != nil {
value.prev.next = value.next
} else {
orderedMap.head = value.next
}
if value.next != nil {
value.next.prev = value.prev
} else {
orderedMap.tail = value.prev
}
return true
}
func (orderedMap *OrderedMap) Size() int {
orderedMap.mutex.RLock()
defer orderedMap.mutex.RUnlock()
return orderedMap.size
}
package orderedmap
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestOrderedMap_Size(t *testing.T) {
orderedMap := New()
assert.Equal(t, 0, orderedMap.Size())
orderedMap.Set(1, 1)
assert.Equal(t, 1, orderedMap.Size())
orderedMap.Set(3, 1)
orderedMap.Set(2, 1)
assert.Equal(t, 3, orderedMap.Size())
orderedMap.Set(2, 2)
assert.Equal(t, 3, orderedMap.Size())
orderedMap.Delete(2)
assert.Equal(t, 2, orderedMap.Size())
}
......@@ -38,6 +38,23 @@ func New(args ...interface{}) *MarshalUtil {
}
}
func (util *MarshalUtil) Parse(parser func(data []byte) (interface{}, error, int)) (result interface{}, err error) {
result, err, readBytes := parser(util.bytes[util.readOffset:])
if err == nil {
util.ReadSeek(util.readOffset + readBytes)
}
return
}
func (util *MarshalUtil) ReadOffset() int {
return util.readOffset
}
func (util *MarshalUtil) WriteOffset() int {
return util.writeOffset
}
func (util *MarshalUtil) WriteSeek(offset int) {
util.writeOffset = offset
}
......
package marshalutil
import (
"encoding/binary"
)
const UINT32_SIZE = 4
func (util *MarshalUtil) WriteUint32(value uint32) {
writeEndOffset := util.expandWriteCapacity(UINT32_SIZE)
binary.LittleEndian.PutUint32(util.bytes[util.writeOffset:writeEndOffset], value)
util.WriteSeek(writeEndOffset)
}
func (util *MarshalUtil) ReadUint32() (uint32, error) {
readEndOffset, err := util.checkReadCapacity(UINT32_SIZE)
if err != nil {
return 0, err
}
defer util.ReadSeek(readEndOffset)
return binary.LittleEndian.Uint32(util.bytes[util.readOffset:readEndOffset]), nil
}
......@@ -8,6 +8,7 @@ import (
)
type Events struct {
// Get's called whenever a transaction
TransactionAttached *events.Event
TransactionSolid *events.Event
MissingTransactionReceived *events.Event
......
......@@ -74,7 +74,7 @@ func (tangle *Tangle) GetTransactionMetadata(transactionId transaction.Id) *tran
return &transactionmetadata.CachedTransactionMetadata{CachedObject: tangle.transactionMetadataStorage.Load(transactionId[:])}
}
// Retrieves the approvers of a transaction from the tangle.
// GetApprovers retrieves the approvers of a transaction from the tangle.
func (tangle *Tangle) GetApprovers(transactionId transaction.Id) approver.CachedApprovers {
approvers := make(approver.CachedApprovers, 0)
tangle.approverStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool {
......
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 valuetransfers
import (
"github.com/mr-tron/base58"
)
type AddressVersion = byte
type AddressDigest = []byte
type Address [AddressLength]byte
func NewAddress(bytes []byte) (address Address) {
copy(address[:], bytes)
return
}
func (address *Address) GetVersion() AddressVersion {
return address[0]
}
func (address *Address) GetDigest() AddressDigest {
return address[1:]
}
func (address Address) ToBytes() []byte {
return address[:]
}
func (address Address) String() string {
return "Address(" + base58.Encode(address.ToBytes()) + ")"
}
const AddressLength = 33
package valuetransfers
import (
"github.com/mr-tron/base58"
"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
)
type Color [ColorLength]byte
func ColorFromBytes(bytes []byte) (result Color, err error, consumedBytes int) {
colorBytes, err := marshalutil.New(bytes).ReadBytes(ColorLength)
if err != nil {
return
}
copy(result[:], colorBytes)
consumedBytes = ColorLength
return
}
const ColorLength = 32
func (color Color) Bytes() []byte {
return color[:]
}
func (color Color) String() string {
if color == COLOR_IOTA {
return "IOTA"
}
return base58.Encode(color[:])
}
var COLOR_IOTA Color = [32]byte{}
package valuetransfers
import (
"strconv"
"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
)
type ColoredBalance struct {
color Color
balance int64
}
func NewColoredBalance(color Color, balance int64) (result *ColoredBalance) {
result = &ColoredBalance{
color: color,
balance: balance,
}
return
}
func ColoredBalanceFromBytes(bytes []byte) (result *ColoredBalance, err error, consumedBytes int) {
result = &ColoredBalance{}
marshalUtil := marshalutil.New(bytes)
if color, colorErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) {
return ColorFromBytes(data)
}); colorErr != nil {
return nil, colorErr, marshalUtil.ReadOffset()
} else {
result.color = color.(Color)
}
result.balance, err = marshalUtil.ReadInt64()
if err != nil {
return
}
consumedBytes = marshalUtil.ReadOffset()
return
}
func (balance *ColoredBalance) ToBytes() []byte {
marshalUtil := marshalutil.New(ColorLength + marshalutil.UINT32_SIZE)
marshalUtil.WriteBytes(balance.color.Bytes())
marshalUtil.WriteInt64(balance.balance)
return marshalUtil.Bytes()
}
func (balance *ColoredBalance) String() string {
return strconv.FormatInt(balance.balance, 10) + " " + balance.color.String()
}
package valuetransfers
import (
"github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap"
"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
)
type Outputs struct {
*orderedmap.OrderedMap
}
func NewOutputs(outputs map[Address][]*ColoredBalance) (result *Outputs) {
result = &Outputs{orderedmap.New()}
for address, balances := range outputs {
result.Add(address, balances)
}
return
}
// OutputsFromBytes reads the bytes and unmarshals the given information into an *Outputs object. It either creates a
// new object, or uses the optional object provided in the arguments.
func OutputsFromBytes(bytes []byte, optionalTargetObject ...*Outputs) (result *Outputs, err error, consumedBytes int) {
// determine the target object that will hold the unmarshaled information
switch len(optionalTargetObject) {
case 0:
result = &Outputs{orderedmap.New()}
case 1:
result = optionalTargetObject[0]
default:
panic("too many arguments in call to OutputFromBytes")
}
// initialize helper
marshalUtil := marshalutil.New(bytes)
// read number of addresses in the outputs
addressCount, addressCountErr := marshalUtil.ReadUint32()
if addressCountErr != nil {
err = addressCountErr
return
}
// iterate the corresponding times and collect addresses + their details
for i := uint32(0); i < addressCount; i++ {
// read address
addressBytes, addressErr := marshalUtil.ReadBytes(AddressLength)
if addressErr != nil {
err = addressErr
return
}
address := NewAddress(addressBytes)
// read number of balances in the outputs
balanceCount, balanceCountErr := marshalUtil.ReadUint32()
if balanceCountErr != nil {
err = balanceCountErr
return
}
// iterate the corresponding times and collect balances
coloredBalances := make([]*ColoredBalance, balanceCount)
for j := uint32(0); j < balanceCount; j++ {
coloredBalance, coloredBalanceErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return ColoredBalanceFromBytes(data) })
if coloredBalanceErr != nil {
err = coloredBalanceErr
return
}
coloredBalances[j] = coloredBalance.(*ColoredBalance)
}
// add the gathered information as an output
result.Add(address, coloredBalances)
}
// return the number of bytes we processed
consumedBytes = marshalUtil.ReadOffset()
return
}
func (outputs *Outputs) Add(address Address, balances []*ColoredBalance) *Outputs {
outputs.Set(address, balances)
return outputs
}
func (outputs *Outputs) ForEach(consumer func(address Address, balances []*ColoredBalance)) {
outputs.OrderedMap.ForEach(func(key, value interface{}) bool {
consumer(key.(Address), value.([]*ColoredBalance))
return true
})
}
func (outputs *Outputs) Bytes() []byte {
marshalUtil := marshalutil.New()
if outputs == nil {
marshalUtil.WriteUint32(0)
return marshalUtil.Bytes()
}
marshalUtil.WriteUint32(uint32(outputs.Size()))
outputs.ForEach(func(address Address, balances []*ColoredBalance) {
marshalUtil.WriteBytes(address.ToBytes())
marshalUtil.WriteUint32(uint32(len(balances)))
for _, balance := range balances {
marshalUtil.WriteBytes(balance.ToBytes())
}
})
return marshalUtil.Bytes()
}
func (outputs *Outputs) String() string {
if outputs == nil {
return "<nil>"
}
result := "[\n"
empty := true
outputs.ForEach(func(address Address, balances []*ColoredBalance) {
empty = false
result += " " + address.String() + ": [\n"
balancesEmpty := true
for _, balance := range balances {
balancesEmpty = false
result += " " + balance.String() + ",\n"
}
if balancesEmpty {
result += " <empty>\n"
}
result += " ]\n"
})
if empty {
result += " <empty>\n"
}
return result + "]"
}
package valuetangle
package valuetransfers
import (
"sync"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment