Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,16 @@ CONFIG_FILE3=tests/system/config.test-3.yml
SETUP_SCRIPT=tests/scripts/setup-supernodes.sh

# Install Lumera
# Optional: specify lumera binary path to skip download
LUMERAD_BINARY ?=
# Optional: specify installation mode (latest-release, latest-tag, or vX.Y.Z)
INSTALL_MODE ?=latest-tag

install-lumera:
@echo "Installing Lumera..."
@chmod +x tests/scripts/install-lumera.sh
@sudo tests/scripts/install-lumera.sh latest-tag

@sudo LUMERAD_BINARY="$(LUMERAD_BINARY)" tests/scripts/install-lumera.sh $(INSTALL_MODE)
@echo "PtTDUHythfRfXHh63yzyiGDid4TZj2P76Zd,18749999981413" > ~/claims.csv
# Setup supernode environments
setup-supernodes:
@echo "Setting up all supernode environments..."
Expand Down
6 changes: 1 addition & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ replace github.com/LumeraProtocol/supernode/supernode => ./supernode

require (
cosmossdk.io/math v1.5.3
github.com/LumeraProtocol/lumera v1.5.0
github.com/LumeraProtocol/lumera v1.6.0
github.com/LumeraProtocol/rq-go v0.2.1
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
github.com/cenkalti/backoff/v4 v4.3.0
Expand All @@ -28,19 +28,16 @@ require (
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.9.1
github.com/shirou/gopsutil/v3 v3.24.5
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.1
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.10.0
github.com/x-cray/logrus-prefixed-formatter v0.5.2
go.uber.org/mock v0.5.2
go.uber.org/ratelimit v0.3.1
golang.org/x/crypto v0.36.0
golang.org/x/sync v0.12.0
golang.org/x/sys v0.31.0
google.golang.org/grpc v1.71.0
google.golang.org/protobuf v1.36.6
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
lukechampine.com/blake3 v1.4.0
)
Expand Down Expand Up @@ -134,7 +131,6 @@ require (
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
Expand Down
13 changes: 2 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/LumeraProtocol/lumera v1.5.0 h1:LDPtd155PjG/LKk34x/3vhC9H+J9tHoxwrcwRMG6jzM=
github.com/LumeraProtocol/lumera v1.5.0/go.mod h1:c1M+sjewuCvxw+pznwlspUzenDJI8Y+suKB3RFKS2Wo=
github.com/LumeraProtocol/lumera v1.6.0 h1:5I172U/f1Migt7tRxnywhz5aRKCpBOx/IMgOzhJfTP0=
github.com/LumeraProtocol/lumera v1.6.0/go.mod h1:c1M+sjewuCvxw+pznwlspUzenDJI8Y+suKB3RFKS2Wo=
github.com/LumeraProtocol/rq-go v0.2.1 h1:8B3UzRChLsGMmvZ+UVbJsJj6JZzL9P9iYxbdUwGsQI4=
github.com/LumeraProtocol/rq-go v0.2.1/go.mod h1:APnKCZRh1Es2Vtrd2w4kCLgAyaL5Bqrkz/BURoRJ+O8=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
Expand Down Expand Up @@ -558,8 +558,6 @@ github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q=
github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
Expand Down Expand Up @@ -733,8 +731,6 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
Expand Down Expand Up @@ -798,8 +794,6 @@ github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down Expand Up @@ -987,7 +981,6 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down Expand Up @@ -1110,8 +1103,6 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
Expand Down
49 changes: 25 additions & 24 deletions p2p/kademlia/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package kademlia
import (
"context"
"fmt"
"os"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -34,11 +33,6 @@ func (s *DHT) parseNode(extP2P string, selfAddr string) (*Node, error) {
return nil, errors.New("empty address")
}

/*if strings.Contains(extP2P, "0.0.0.0") {
fmt.Println("skippping node")
return nil, errors.New("invalid address")
}*/

if extP2P == selfAddr {
return nil, errors.New("self address")
}
Expand All @@ -61,24 +55,12 @@ func (s *DHT) parseNode(extP2P string, selfAddr string) (*Node, error) {
if err != nil {
return nil, errors.New("invalid port number")
}

// For system testing, use port+1 if SYSTEM_TEST=true
if os.Getenv("SYSTEM_TEST") == "true" {
port = uint16(portNum) + 1
logtrace.Info(context.Background(), "Using port+1 for system testing", logtrace.Fields{
logtrace.FieldModule: "p2p",
"original_port": portNum,
"adjusted_port": port,
})
} else {
// For normal P2P operation, always use the default port
port = defaultNetworkPort
}
port = uint16(portNum)
}
} else {
// No port in the address
ip = extP2P
port = defaultNetworkPort
port = defaultSuperNodeP2PPort
}

if ip == "" {
Expand Down Expand Up @@ -170,21 +152,40 @@ func (s *DHT) ConfigureBootstrapNodes(ctx context.Context, bootstrapNodes string
continue
}

// Parse the node from the IP address
node, err := s.parseNode(latestIP, selfAddress)
// Extract IP from the address (remove port if present)
var ip string
if idx := strings.LastIndex(latestIP, ":"); idx != -1 {
ip = latestIP[:idx]
} else {
ip = latestIP
}

// Use p2p_port from supernode record
p2pPort := defaultSuperNodeP2PPort
if supernode.P2PPort != "" {
if port, err := strconv.ParseUint(supernode.P2PPort, 10, 16); err == nil {
p2pPort = int(port)
}
}

// Create full address with p2p port for validation
fullAddress := fmt.Sprintf("%s:%d", ip, p2pPort)

// Parse the node from the full address
node, err := s.parseNode(fullAddress, selfAddress)
if err != nil {
logtrace.Warn(ctx, "Skip Bad Bootstrap Address", logtrace.Fields{
logtrace.FieldModule: "p2p",
logtrace.FieldError: err.Error(),
"address": latestIP,
"address": fullAddress,
"supernode": supernode.SupernodeAccount,
})
continue
}

// Store the supernode account as the node ID
node.ID = []byte(supernode.SupernodeAccount)
mapNodes[latestIP] = node
mapNodes[fullAddress] = node
}

// Convert the map to a slice
Expand Down
108 changes: 90 additions & 18 deletions sdk/action/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import (
"context"
"fmt"

"github.com/LumeraProtocol/supernode/sdk/adapters/lumera"
"github.com/LumeraProtocol/supernode/sdk/adapters/supernodeservice"
"github.com/LumeraProtocol/supernode/sdk/config"
"github.com/LumeraProtocol/supernode/sdk/event"
"github.com/LumeraProtocol/supernode/sdk/log"
"github.com/LumeraProtocol/supernode/sdk/net"
"github.com/LumeraProtocol/supernode/sdk/task"

"github.com/cosmos/cosmos-sdk/crypto/keyring"
Expand All @@ -16,24 +19,25 @@ import (
//
//go:generate mockery --name=Client --output=testutil/mocks --outpkg=mocks --filename=client_mock.go
type Client interface {
// - signature: Base64-encoded cryptographic signature of the file's data hash (blake3)
// 1- hash(blake3) > 2- sign > 3- base64
// The signature must be created by the same account that created the Lumera action.
// It must be a digital signature of the data hash found in the action's CASCADE metadata.
// StartCascade initiates a cascade operation with file path, action ID, and signature
// signature: Base64-encoded signature of file's blake3 hash by action creator
StartCascade(ctx context.Context, filePath string, actionID string, signature string) (string, error)
DeleteTask(ctx context.Context, taskID string) error
GetTask(ctx context.Context, taskID string) (*task.TaskEntry, bool)
SubscribeToEvents(ctx context.Context, eventType event.EventType, handler event.Handler) error
SubscribeToAllEvents(ctx context.Context, handler event.Handler) error
DownloadCascade(ctx context.Context, actionID, outputPath string) (string, error)
GetSupernodeStatus(ctx context.Context, supernodeAddress string) (*supernodeservice.SupernodeStatusresponse, error)
// DownloadCascade downloads cascade to outputDir, filename determined by action ID
DownloadCascade(ctx context.Context, actionID, outputDir string) (string, error)
}

// ClientImpl implements the Client interface
type ClientImpl struct {
config config.Config
taskManager task.Manager
logger log.Logger
keyring keyring.Keyring
config config.Config
taskManager task.Manager
logger log.Logger
keyring keyring.Keyring
lumeraClient lumera.Client
}

// Verify interface compliance at compile time
Expand All @@ -45,15 +49,31 @@ func NewClient(ctx context.Context, config config.Config, logger log.Logger) (Cl
logger = log.NewNoopLogger()
}

taskManager, err := task.NewManager(ctx, config, logger)
// Create lumera client once
lumeraClient, err := lumera.NewAdapter(ctx,
lumera.ConfigParams{
GRPCAddr: config.Lumera.GRPCAddr,
ChainID: config.Lumera.ChainID,
KeyName: config.Account.KeyName,
Keyring: config.Account.Keyring,
},
logger)
if err != nil {
return nil, fmt.Errorf("failed to create lumera client: %w", err)
}

// Create task manager with shared lumera client
taskManager, err := task.NewManagerWithLumeraClient(ctx, config, logger, lumeraClient)
if err != nil {
return nil, fmt.Errorf("failed to create task manager: %w", err)
}

return &ClientImpl{
config: config,
taskManager: taskManager,
logger: logger,
config: config,
taskManager: taskManager,
logger: logger,
keyring: config.Account.Keyring,
lumeraClient: lumeraClient,
}, nil
}

Expand Down Expand Up @@ -130,16 +150,68 @@ func (c *ClientImpl) SubscribeToAllEvents(ctx context.Context, handler event.Han
return nil
}

func (c *ClientImpl) DownloadCascade(
ctx context.Context,
actionID, outputPath string,
) (string, error) {
// GetSupernodeStatus retrieves the status of a specific supernode by its address
func (c *ClientImpl) GetSupernodeStatus(ctx context.Context, supernodeAddress string) (*supernodeservice.SupernodeStatusresponse, error) {
if supernodeAddress == "" {
c.logger.Error(ctx, "Empty supernode address provided")
return nil, fmt.Errorf("supernode address cannot be empty")
}

c.logger.Debug(ctx, "Getting supernode status", "address", supernodeAddress)

// Get supernode details from blockchain
supernode, err := c.lumeraClient.GetSupernodeBySupernodeAddress(ctx, supernodeAddress)
if err != nil {
c.logger.Error(ctx, "Failed to get supernode details", "address", supernodeAddress, "error", err)
return nil, fmt.Errorf("failed to get supernode details: %w", err)
}

// Get the latest IP address for the supernode
if len(supernode.PrevIpAddresses) == 0 {
return nil, fmt.Errorf("no IP addresses found for supernode %s", supernodeAddress)
}

ipAddress := supernode.PrevIpAddresses[0].Address

// Create lumera supernode object for network client
lumeraSupernode := lumera.Supernode{
CosmosAddress: supernodeAddress,
GrpcEndpoint: ipAddress,
State: lumera.SUPERNODE_STATE_ACTIVE, // Assume active since we're querying
}

// Create network client factory
clientFactory := net.NewClientFactory(ctx, c.logger, c.keyring, c.lumeraClient, net.FactoryConfig{
LocalCosmosAddress: c.config.Account.LocalCosmosAddress,
PeerType: c.config.Account.PeerType,
})

// Create client for the specific supernode
supernodeClient, err := clientFactory.CreateClient(ctx, lumeraSupernode)
if err != nil {
c.logger.Error(ctx, "Failed to create supernode client", "address", supernodeAddress, "error", err)
return nil, fmt.Errorf("failed to create supernode client: %w", err)
}
defer supernodeClient.Close(ctx)

// Get the supernode status
status, err := supernodeClient.GetSupernodeStatus(ctx)
if err != nil {
c.logger.Error(ctx, "Failed to get supernode status", "address", supernodeAddress, "error", err)
return nil, fmt.Errorf("failed to get supernode status: %w", err)
}

c.logger.Info(ctx, "Successfully retrieved supernode status", "address", supernodeAddress)
return status, nil
}

func (c *ClientImpl) DownloadCascade(ctx context.Context, actionID, outputDir string) (string, error) {

if actionID == "" {
return "", fmt.Errorf("actionID is empty")
}

taskID, err := c.taskManager.CreateDownloadTask(ctx, actionID, outputPath)
taskID, err := c.taskManager.CreateDownloadTask(ctx, actionID, outputDir)
if err != nil {
return "", fmt.Errorf("create download task: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion sdk/adapters/lumera/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
actiontypes "github.com/LumeraProtocol/lumera/x/action/v1/types"

sntypes "github.com/LumeraProtocol/lumera/x/supernode/v1/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
lumeraclient "github.com/LumeraProtocol/supernode/pkg/lumera"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/golang/protobuf/proto"
)

Expand Down
Loading
Loading