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) {
tx.SetTail(true)
tx.SetAddress(targetAddress)
tx.SetBranchTransactionHash(tipselection.GetRandomTip())
tx.SetTrunkTransactionHash(tipselection.GetRandomTip())
tx.SetTrunkTransactionHash(tipselection.GetRandomTip(tx.GetBranchTransactionHash()))
tx.SetTimestamp(uint(time.Now().Unix()))
if err := tx.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE); err != nil {
log.Warn("PoW failed", err)
......
......@@ -5,17 +5,23 @@ import (
"github.com/iotaledger/goshimmer/plugins/tangle"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/hive.go/node"
"github.com/iotaledger/iota.go/trinary"
)
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) {
tips.Delete(transaction.GetBranchTransactionHash())
tips.Delete(transaction.GetTrunkTransactionHash())
tips.Set(transaction.GetHash(), transaction.GetHash())
mutex.Lock()
defer mutex.Unlock()
delete(tipSet, transaction.GetBranchTransactionHash())
delete(tipSet, transaction.GetTrunkTransactionHash())
tipSet[transaction.GetHash()] = struct{}{}
}))
}
func run(run *node.Plugin) {
func run(*node.Plugin) {
}
package tipselection
import (
"github.com/iotaledger/goshimmer/packages/datastructure"
"math/rand"
"sync"
"github.com/iotaledger/goshimmer/packages/model/meta_transaction"
"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) {
if randomTipHash := tips.RandomEntry(); randomTipHash != nil {
result = randomTipHash.(trinary.Trytes)
} else {
result = meta_transaction.BRANCH_NULL_HASH
var ignore trinary.Hash
if len(excluding) > 0 {
ignore = excluding[0]
}
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 {
return tips.Size()
mutex.RLock()
defer mutex.RUnlock()
return len(tipSet)
}
package tipselection
import (
"fmt"
"log"
"testing"
"github.com/iotaledger/goshimmer/packages/model/meta_transaction"
"github.com/iotaledger/goshimmer/packages/model/value_transaction"
"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)
for i := 0; i < 1000; i++ {
tx := value_transaction.New()
tx.SetValue(int64(i + 1))
tx.SetBranchTransactionHash(GetRandomTip())
tx.SetTrunkTransactionHash(GetRandomTip())
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)
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 {
tx.SetSignatureMessageFragment(trytes)
tx.SetValue(0)
tx.SetBranchTransactionHash(tipselection.GetRandomTip())
tx.SetTrunkTransactionHash(tipselection.GetRandomTip())
tx.SetTrunkTransactionHash(tipselection.GetRandomTip(tx.GetBranchTransactionHash()))
tx.SetTimestamp(uint(time.Now().Unix()))
if err := tx.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE); err != nil {
log.Warnf("PoW failed: %s", err)
......
......@@ -17,7 +17,7 @@ var PLUGIN = node.NewPlugin("WebAPI GTTA Endpoint", node.Disabled, func(plugin *
func Handler(c echo.Context) error {
branchTransactionHash := tipselection.GetRandomTip()
trunkTransactionHash := tipselection.GetRandomTip()
trunkTransactionHash := tipselection.GetRandomTip(branchTransactionHash)
return c.JSON(http.StatusOK, Response{
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