Skip to content
Snippets Groups Projects
Unverified Commit 247b38d5 authored by Wolfgang Welz's avatar Wolfgang Welz Committed by GitHub
Browse files

allow excluding a tip in GetRandomTip (#192)

parent 02794bd1
No related branches found
No related tags found
No related merge requests found
...@@ -63,7 +63,7 @@ func Start(tps uint64) { ...@@ -63,7 +63,7 @@ func Start(tps uint64) {
tx.SetTail(true) tx.SetTail(true)
tx.SetAddress(targetAddress) tx.SetAddress(targetAddress)
tx.SetBranchTransactionHash(tipselection.GetRandomTip()) tx.SetBranchTransactionHash(tipselection.GetRandomTip())
tx.SetTrunkTransactionHash(tipselection.GetRandomTip()) tx.SetTrunkTransactionHash(tipselection.GetRandomTip(tx.GetBranchTransactionHash()))
tx.SetTimestamp(uint(time.Now().Unix())) tx.SetTimestamp(uint(time.Now().Unix()))
if err := tx.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE); err != nil { if err := tx.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE); err != nil {
log.Warn("PoW failed", err) log.Warn("PoW failed", err)
......
...@@ -5,17 +5,23 @@ import ( ...@@ -5,17 +5,23 @@ import (
"github.com/iotaledger/goshimmer/plugins/tangle" "github.com/iotaledger/goshimmer/plugins/tangle"
"github.com/iotaledger/hive.go/events" "github.com/iotaledger/hive.go/events"
"github.com/iotaledger/hive.go/node" "github.com/iotaledger/hive.go/node"
"github.com/iotaledger/iota.go/trinary"
) )
var PLUGIN = node.NewPlugin("Tipselection", node.Enabled, configure, run) var PLUGIN = node.NewPlugin("Tipselection", node.Enabled, configure, run)
func configure(node *node.Plugin) { func configure(*node.Plugin) {
tipSet = make(map[trinary.Hash]struct{})
tangle.Events.TransactionSolid.Attach(events.NewClosure(func(transaction *value_transaction.ValueTransaction) { tangle.Events.TransactionSolid.Attach(events.NewClosure(func(transaction *value_transaction.ValueTransaction) {
tips.Delete(transaction.GetBranchTransactionHash()) mutex.Lock()
tips.Delete(transaction.GetTrunkTransactionHash()) defer mutex.Unlock()
tips.Set(transaction.GetHash(), transaction.GetHash())
delete(tipSet, transaction.GetBranchTransactionHash())
delete(tipSet, transaction.GetTrunkTransactionHash())
tipSet[transaction.GetHash()] = struct{}{}
})) }))
} }
func run(run *node.Plugin) { func run(*node.Plugin) {
} }
package tipselection package tipselection
import ( import (
"github.com/iotaledger/goshimmer/packages/datastructure" "math/rand"
"sync"
"github.com/iotaledger/goshimmer/packages/model/meta_transaction" "github.com/iotaledger/goshimmer/packages/model/meta_transaction"
"github.com/iotaledger/iota.go/trinary" "github.com/iotaledger/iota.go/trinary"
) )
var tips = datastructure.NewRandomMap() var (
tipSet map[trinary.Hash]struct{}
mutex sync.RWMutex
)
func GetRandomTip(excluding ...trinary.Hash) trinary.Trytes {
mutex.RLock()
defer mutex.RUnlock()
numTips := len(tipSet)
if numTips == 0 {
return meta_transaction.BRANCH_NULL_HASH
}
func GetRandomTip() (result trinary.Trytes) { var ignore trinary.Hash
if randomTipHash := tips.RandomEntry(); randomTipHash != nil { if len(excluding) > 0 {
result = randomTipHash.(trinary.Trytes) ignore = excluding[0]
} else { }
result = meta_transaction.BRANCH_NULL_HASH if _, contains := tipSet[ignore]; contains {
if numTips == 1 {
return ignore
}
numTips -= 1
} }
return i := rand.Intn(numTips)
for k := range tipSet {
if k == ignore {
continue
}
if i == 0 {
return k
}
i--
}
panic("unreachable")
} }
func GetTipsCount() int { func GetTipsCount() int {
return tips.Size() mutex.RLock()
defer mutex.RUnlock()
return len(tipSet)
} }
package tipselection package tipselection
import ( import (
"fmt" "log"
"testing" "testing"
"github.com/iotaledger/goshimmer/packages/model/meta_transaction"
"github.com/iotaledger/goshimmer/packages/model/value_transaction" "github.com/iotaledger/goshimmer/packages/model/value_transaction"
"github.com/iotaledger/goshimmer/plugins/tangle" "github.com/iotaledger/goshimmer/plugins/tangle"
"github.com/iotaledger/hive.go/logger"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func Test(t *testing.T) { func init() {
if err := logger.InitGlobalLogger(viper.New()); err != nil {
log.Fatal(err)
}
}
func TestEmptyTipSet(t *testing.T) {
configure(nil)
assert.Equal(t, 0, GetTipsCount())
assert.Equal(t, meta_transaction.BRANCH_NULL_HASH, GetRandomTip())
}
func TestSingleTip(t *testing.T) {
configure(nil) configure(nil)
for i := 0; i < 1000; i++ { tx := value_transaction.New()
tx := value_transaction.New() tx.SetValue(int64(1))
tx.SetValue(int64(i + 1)) tx.SetBranchTransactionHash(meta_transaction.BRANCH_NULL_HASH)
tx.SetBranchTransactionHash(GetRandomTip()) tx.SetTrunkTransactionHash(meta_transaction.BRANCH_NULL_HASH)
tx.SetTrunkTransactionHash(GetRandomTip())
tangle.Events.TransactionSolid.Trigger(tx) tangle.Events.TransactionSolid.Trigger(tx)
fmt.Println(GetTipsCount()) assert.Equal(t, 1, GetTipsCount())
}
tip1 := GetRandomTip()
assert.NotNil(t, tip1)
tip2 := GetRandomTip(tip1)
assert.NotNil(t, tip2)
assert.Equal(t, tip1, tip2)
}
func TestGetRandomTip(t *testing.T) {
configure(nil)
tx := value_transaction.New()
tx.SetValue(int64(1))
tx.SetBranchTransactionHash(meta_transaction.BRANCH_NULL_HASH)
tx.SetTrunkTransactionHash(meta_transaction.BRANCH_NULL_HASH)
tangle.Events.TransactionSolid.Trigger(tx)
tx = value_transaction.New()
tx.SetValue(int64(2))
tx.SetBranchTransactionHash(meta_transaction.BRANCH_NULL_HASH)
tx.SetTrunkTransactionHash(meta_transaction.BRANCH_NULL_HASH)
tangle.Events.TransactionSolid.Trigger(tx)
assert.Equal(t, 2, GetTipsCount())
tip1 := GetRandomTip()
require.NotNil(t, tip1)
tip2 := GetRandomTip(tip1)
require.NotNil(t, tip2)
require.NotEqual(t, tip1, tip2)
tx = value_transaction.New()
tx.SetValue(int64(3))
tx.SetBranchTransactionHash(tip1)
tx.SetTrunkTransactionHash(tip2)
tangle.Events.TransactionSolid.Trigger(tx)
assert.Equal(t, 1, GetTipsCount())
assert.Equal(t, tx.GetHash(), GetRandomTip())
} }
...@@ -66,7 +66,7 @@ func broadcastData(c echo.Context) error { ...@@ -66,7 +66,7 @@ func broadcastData(c echo.Context) error {
tx.SetSignatureMessageFragment(trytes) tx.SetSignatureMessageFragment(trytes)
tx.SetValue(0) tx.SetValue(0)
tx.SetBranchTransactionHash(tipselection.GetRandomTip()) tx.SetBranchTransactionHash(tipselection.GetRandomTip())
tx.SetTrunkTransactionHash(tipselection.GetRandomTip()) tx.SetTrunkTransactionHash(tipselection.GetRandomTip(tx.GetBranchTransactionHash()))
tx.SetTimestamp(uint(time.Now().Unix())) tx.SetTimestamp(uint(time.Now().Unix()))
if err := tx.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE); err != nil { if err := tx.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE); err != nil {
log.Warnf("PoW failed: %s", err) log.Warnf("PoW failed: %s", err)
......
...@@ -17,7 +17,7 @@ var PLUGIN = node.NewPlugin("WebAPI GTTA Endpoint", node.Disabled, func(plugin * ...@@ -17,7 +17,7 @@ var PLUGIN = node.NewPlugin("WebAPI GTTA Endpoint", node.Disabled, func(plugin *
func Handler(c echo.Context) error { func Handler(c echo.Context) error {
branchTransactionHash := tipselection.GetRandomTip() branchTransactionHash := tipselection.GetRandomTip()
trunkTransactionHash := tipselection.GetRandomTip() trunkTransactionHash := tipselection.GetRandomTip(branchTransactionHash)
return c.JSON(http.StatusOK, Response{ return c.JSON(http.StatusOK, Response{
BranchTransaction: branchTransactionHash, BranchTransaction: branchTransactionHash,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment