Skip to content
Snippets Groups Projects
Unverified Commit 38608819 authored by RUANO RINCON Santiago's avatar RUANO RINCON Santiago
Browse files

TBR: PoW plugin requirements (again)

parent facb02cf
No related branches found
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))
}
......@@ -8,6 +8,7 @@ import (
"time"
"github.com/cockroachdb/errors"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/hive.go/logger"
_ "golang.org/x/crypto/blake2b" // required by crypto.BLAKE2b_512
......@@ -22,10 +23,14 @@ var (
hash = crypto.BLAKE2b_512
// configured via parameters
difficultyMutex sync.RWMutex
difficulty int
numWorkers int
timeout time.Duration
parentsRefreshInterval time.Duration
powEvents *PowEvents
eventsOnce sync.Once
)
var (
......@@ -38,6 +43,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 = Parameters.Difficulty
......@@ -46,10 +53,22 @@ func Worker() *pow.Worker {
parentsRefreshInterval = Parameters.ParentsRefreshInterval
// create the worker
worker = pow.New(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 +76,9 @@ func DoPOW(msg []byte) (uint64, error) {
return 0, err
}
difficultyMutex.RLock()
defer difficultyMutex.RUnlock()
// get the PoW worker
worker := Worker()
......@@ -64,7 +86,20 @@ func DoPOW(msg []byte) (uint64, error) {
ctx, cancel := context.WithTimeout(context.Background(), parentsRefreshInterval)
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)
// log.Debugw("PoW stopped", "nonce", nonce, "err", err)
......@@ -79,3 +114,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
}
......@@ -13,6 +13,7 @@ import (
"github.com/iotaledger/goshimmer/plugins/webapi/ledgerstate"
"github.com/iotaledger/goshimmer/plugins/webapi/mana"
"github.com/iotaledger/goshimmer/plugins/webapi/message"
"github.com/iotaledger/goshimmer/plugins/webapi/pow"
"github.com/iotaledger/goshimmer/plugins/webapi/snapshot"
drngTools "github.com/iotaledger/goshimmer/plugins/webapi/tools/drng"
msgTools "github.com/iotaledger/goshimmer/plugins/webapi/tools/message"
......
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
deps = new(dependencies)
)
type dependencies struct {
Server *echo.Echo
}
func init() {
Plugin = node.NewPlugin(PluginName, deps, node.Enabled, configure)
}
func configure(plugin *node.Plugin) {
deps.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"`
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment