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

:beers: Add tutorial

parent 8cd10312
Branches extra/tutorial
No related tags found
No related merge requests found
package pow
import (
"time"
"github.com/iotaledger/hive.go/events"
)
type PowEvents struct {
// PowDone defines the pow done event.
PowDone *events.Event
}
// PowDoneEvent is used to pass information through a PowDone event.
type PowDoneEvent struct {
Difficulty int
Duration time.Duration
}
func powDoneEventCaller(handler interface{}, params ...interface{}) {
handler.(func(ev *PowDoneEvent))(params[0].(*PowDoneEvent))
}
......@@ -10,6 +10,7 @@ import (
"github.com/iotaledger/goshimmer/packages/pow"
"github.com/iotaledger/goshimmer/plugins/config"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/hive.go/logger"
_ "golang.org/x/crypto/blake2b" // required by crypto.BLAKE2b_512
)
......@@ -24,9 +25,13 @@ var (
hash = crypto.BLAKE2b_512
// configured via parameters
difficultyMutex sync.RWMutex
difficulty int
numWorkers int
timeout time.Duration
powEvents *PowEvents
eventsOnce sync.Once
)
var (
......@@ -39,6 +44,8 @@ var (
// Worker returns the PoW worker instance of the PoW plugin.
func Worker() *pow.Worker {
workerOnce.Do(func() {
difficultyMutex.Lock()
defer difficultyMutex.Unlock()
log = logger.NewLogger(PluginName)
// load the parameters
difficulty = config.Node().Int(CfgPOWDifficulty)
......@@ -46,10 +53,21 @@ func Worker() *pow.Worker {
timeout = config.Node().Duration(CfgPOWTimeout)
// create the worker
worker = pow.New(hash, numWorkers)
// ensure events are initialized
Events()
})
return worker
}
// Events returns the pow events.
func Events() *PowEvents {
eventsOnce.Do(func() {
// init the events
powEvents = &PowEvents{events.NewEvent(powDoneEventCaller)}
})
return powEvents
}
// DoPOW performs the PoW on the provided msg and returns the nonce.
func DoPOW(msg []byte) (uint64, error) {
content, err := powData(msg)
......@@ -57,6 +75,9 @@ func DoPOW(msg []byte) (uint64, error) {
return 0, err
}
difficultyMutex.RLock()
defer difficultyMutex.RUnlock()
// get the PoW worker
worker := Worker()
......@@ -64,7 +85,17 @@ func DoPOW(msg []byte) (uint64, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
start := time.Now()
nonce, err := worker.Mine(ctx, content[:len(content)-pow.NonceBytes], difficulty)
duration := time.Since(start)
ev := &PowDoneEvent{
Difficulty: difficulty,
Duration: duration,
}
Events().PowDone.Trigger(ev)
log.Debugw("PoW stopped", "nonce", nonce, "err", err)
......@@ -79,3 +110,11 @@ func powData(msgBytes []byte) ([]byte, error) {
}
return msgBytes[:contentLength], nil
}
// Tune changes pow difficulty at runtime.
func Tune(d int) {
difficultyMutex.Lock()
defer difficultyMutex.Unlock()
difficulty = d
}
......@@ -7,6 +7,7 @@ import (
"github.com/iotaledger/goshimmer/plugins/networkdelay"
"github.com/iotaledger/goshimmer/plugins/prometheus"
"github.com/iotaledger/goshimmer/plugins/remotelog"
"github.com/iotaledger/goshimmer/plugins/tutorial"
"github.com/iotaledger/hive.go/node"
)
......@@ -18,4 +19,5 @@ var Research = node.Plugins(
analysisdashboard.Plugin(),
prometheus.Plugin(),
networkdelay.App(),
tutorial.Plugin(),
)
package tutorial
import (
"sync"
"github.com/iotaledger/goshimmer/packages/tangle"
"github.com/iotaledger/goshimmer/plugins/messagelayer"
"github.com/iotaledger/goshimmer/plugins/pow"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/hive.go/logger"
"github.com/iotaledger/hive.go/node"
)
// PluginName is the name of the tutorial plugin.
const PluginName = "tutorial"
var (
// plugin is the plugin instance of the web API plugin.
plugin *node.Plugin
pluginOnce sync.Once
// log is the logger used by this plugin.
log *logger.Logger
)
// Plugin gets the plugin instance.
func Plugin() *node.Plugin {
pluginOnce.Do(func() {
plugin = node.NewPlugin(PluginName, node.Disabled, configure, run)
})
return plugin
}
func configure(*node.Plugin) {
log = logger.NewLogger(PluginName)
messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
defer cachedMsgEvent.MessageMetadata.Release()
cachedMsgEvent.Message.Consume(func(message *tangle.Message) {
log.Info(message.IssuingTime().UnixNano(), message.ID(), "-->", message.StrongParents(), message.WeakParents())
})
}))
pow.Events().PowDone.Attach(events.NewClosure(func(ev *pow.PowDoneEvent) {
log.Info(ev.Difficulty, ev.Duration)
}))
}
func run(*node.Plugin) {
log.Infof("Starting %s ...", PluginName)
}
......@@ -9,6 +9,7 @@ import (
"github.com/iotaledger/goshimmer/plugins/webapi/healthz"
"github.com/iotaledger/goshimmer/plugins/webapi/info"
"github.com/iotaledger/goshimmer/plugins/webapi/message"
"github.com/iotaledger/goshimmer/plugins/webapi/pow"
"github.com/iotaledger/goshimmer/plugins/webapi/tools"
"github.com/iotaledger/goshimmer/plugins/webapi/value"
"github.com/iotaledger/hive.go/node"
......@@ -26,4 +27,5 @@ var WebAPI = node.Plugins(
info.Plugin(),
value.Plugin(),
tools.Plugin(),
pow.Plugin(),
)
package pow
import (
"fmt"
"net/http"
"sync"
"github.com/iotaledger/goshimmer/plugins/pow"
"github.com/iotaledger/goshimmer/plugins/webapi"
"github.com/iotaledger/hive.go/node"
"github.com/labstack/echo"
)
// PluginName is the name of the web API PoW endpoint plugin.
const PluginName = "WebAPI PoW Endpoint"
var (
// plugin is the plugin instance of the web API PoW endpoint plugin.
plugin *node.Plugin
once sync.Once
)
func configure(plugin *node.Plugin) {
webapi.Server().GET("pow/tune", handler)
}
// Plugin gets the plugin instance.
func Plugin() *node.Plugin {
once.Do(func() {
plugin = node.NewPlugin(PluginName, node.Enabled, configure)
})
return plugin
}
// tune sets the pow difficulty
func handler(c echo.Context) error {
var request Request
if err := c.Bind(&request); err != nil {
return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
}
pow.Tune(request.Difficulty)
return c.JSON(http.StatusOK, Response{Message: fmt.Sprintf("PoW difficulty changed to %d", request.Difficulty)})
}
// Response is the HTTP response of a pow tune request.
type Response struct {
Message string `json:"message"`
Error string `json:"error"`
}
// Request contains the parameters of a pow tune request.
type Request struct {
Difficulty int `json:"difficulty"`
}
......@@ -41,7 +41,7 @@ services:
--config=/tmp/config.json
--database.directory=/tmp/mainnetdb
--autopeering.seed=base58:8q491c3YWjbPwLmF2WD95YmCgh61j2kenCKHfGfByoWi
--node.enablePlugins=prometheus,spammer,faucet,syncbeacon
--node.enablePlugins=prometheus,spammer,faucet,syncbeacon,tutorial
--node.disablePlugins=syncbeaconfollower,clock
--faucet.seed=7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih
--valueLayer.snapshot.file=/tmp/assets/7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih.bin
......@@ -65,7 +65,7 @@ services:
command: >
--config=/tmp/config.json
--database.directory=/tmp/mainnetdb
--node.enablePlugins=bootstrap
--node.enablePlugins=bootstrap,spammer
--valueLayer.snapshot.file=/tmp/assets/7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih.bin
--node.disablePlugins=portcheck,clock
--syncbeaconfollower.followNodes=EYsaGXnUVA9aTYL9FwYEvoQ8d1HCJveQVL7vogu6pqCP
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment