Select Git revision
explorer_routes.go
jkrvivian
authored and
GitHub
committed
* fix: Rename SPA to dashboard and disable portcheck of peer_replica * feat: Add data & unknown type of payload to dashboard * refactor: Implement paylaod interface that allows different json structs * feat: Implement Drng paylaod * refactor: Use Listgroup for layout consistency * doc: Add description * feat: Implement Value payload handler * feat: Add Value payload layout * refactor: Refactor payload layouts * refactor: Remove debug print out * fix: Remove redundant assignment * refactor: Fix* refactor: Fix
explorer_routes.go 3.40 KiB
package dashboard
import (
"fmt"
"net/http"
"sync"
"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
"github.com/iotaledger/goshimmer/plugins/messagelayer"
"github.com/labstack/echo"
)
// ExplorerMessage defines the struct of the ExplorerMessage.
type ExplorerMessage struct {
// ID is the message ID.
ID string `json:"id"`
// Timestamp is the timestamp of the message.
Timestamp uint `json:"timestamp"`
// TrunkMessageId is the Trunk ID of the message.
TrunkMessageID string `json:"trunk_message_id"`
// BranchMessageId is the Branch ID of the message.
BranchMessageID string `json:"branch_message_id"`
// Solid defines the solid status of the message.
Solid bool `json:"solid"`
// PayloadType defines the type of the payload.
PayloadType uint32 `json:"payload_type"`
// Payload is the content of the payload.
Payload interface{} `json:"payload"`
}
func createExplorerMessage(msg *message.Message) (*ExplorerMessage, error) {
messageID := msg.Id()
messageMetadata := messagelayer.Tangle.MessageMetadata(messageID)
t := &ExplorerMessage{
ID: messageID.String(),
Timestamp: 0,
TrunkMessageID: msg.TrunkId().String(),
BranchMessageID: msg.BranchId().String(),
Solid: messageMetadata.Unwrap().IsSolid(),
PayloadType: msg.Payload().Type(),
Payload: ProcessPayload(msg.Payload()),
}
return t, nil
}
// ExplorerAddress defines the struct of the ExplorerAddress.
type ExplorerAddress struct {
// Messagess hold the list of *ExplorerMessage.
Messages []*ExplorerMessage `json:"message"`
}
// SearchResult defines the struct of the SearchResult.
type SearchResult struct {
// Message is the *ExplorerMessage.
Message *ExplorerMessage `json:"message"`
// Address is the *ExplorerAddress.
Address *ExplorerAddress `json:"address"`
}
func setupExplorerRoutes(routeGroup *echo.Group) {
routeGroup.GET("/message/:id", func(c echo.Context) (err error) {
messageID, err := message.NewId(c.Param("id"))
if err != nil {
return
}
t, err := findMessage(messageID)
if err != nil {
return
}
return c.JSON(http.StatusOK, t)
})
routeGroup.GET("/address/:id", func(c echo.Context) error {
addr, err := findAddress(c.Param("id"))
if err != nil {
return err
}
return c.JSON(http.StatusOK, addr)
})
routeGroup.GET("/search/:search", func(c echo.Context) error {
search := c.Param("search")
result := &SearchResult{}
if len(search) < 81 {
return fmt.Errorf("%w: search ID %s", ErrInvalidParameter, search)
}
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
messageID, err := message.NewId(search)
if err != nil {
return
}
msg, err := findMessage(messageID)
if err == nil {
result.Message = msg
}
}()
go func() {
defer wg.Done()
addr, err := findAddress(search)
if err == nil {
result.Address = addr
}
}()
wg.Wait()
return c.JSON(http.StatusOK, result)
})
}
func findMessage(messageID message.Id) (explorerMsg *ExplorerMessage, err error) {
if !messagelayer.Tangle.Message(messageID).Consume(func(msg *message.Message) {
explorerMsg, err = createExplorerMessage(msg)
}) {
err = fmt.Errorf("%w: message %s", ErrNotFound, messageID.String())
}
return
}
func findAddress(address string) (*ExplorerAddress, error) {
return nil, fmt.Errorf("%w: address %s", ErrNotFound, address)
// TODO: ADD ADDRESS LOOKUPS ONCE THE VALUE TRANSFER ONTOLOGY IS MERGED
}