Skip to content

Commit 53bcfdf

Browse files
authored
Merge pull request #5 from LumeraProtocol/event-change
added go-sdk events, updated supernode to v2.4.10
2 parents f8f63c4 + 0e5c7ca commit 53bcfdf

6 files changed

Lines changed: 104 additions & 46 deletions

File tree

cascade/cascade.go

Lines changed: 89 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"fmt"
77
"time"
8+
"path/filepath"
89

910
actiontypes "github.com/LumeraProtocol/lumera/x/action/v1/types"
1011
"github.com/LumeraProtocol/sdk-go/blockchain"
@@ -15,8 +16,8 @@ import (
1516

1617
// UploadOptions configures cascade upload
1718
type UploadOptions struct {
18-
Public bool
19-
FileName string
19+
ID string // optional custom ID for the upload
20+
Public bool // whether the uploaded file will be accessible publicly
2021
}
2122

2223
// UploadOption is a functional option for Upload
@@ -29,32 +30,29 @@ func WithPublic(public bool) UploadOption {
2930
}
3031
}
3132

32-
// WithFileName sets a custom filename
33-
func WithFileName(name string) UploadOption {
33+
// WithID sets a custom ID
34+
func WithID(id string) UploadOption {
3435
return func(o *UploadOptions) {
35-
o.FileName = name
36+
o.ID = id
3637
}
3738
}
38-
3939
// CreateRequestActionMessage builds Cascade metadata and constructs a MsgRequestAction without broadcasting it.
4040
// Returns the built Cosmos message and the serialized metadata bytes used in the message.
41-
func (c *Client) CreateRequestActionMessage(ctx context.Context, creator string, filePath string, opts ...UploadOption) (*actiontypes.MsgRequestAction, []byte, error) {
42-
// Apply options
43-
options := &UploadOptions{Public: false}
44-
for _, opt := range opts {
45-
opt(options)
41+
func (c *Client) CreateRequestActionMessage(ctx context.Context, creator string, filePath string, options *UploadOptions) (*actiontypes.MsgRequestAction, []byte, error) {
42+
var isPublic bool
43+
if options != nil {
44+
isPublic = options.Public
4645
}
47-
4846
// Build metadata with SuperNode SDK
49-
meta, price, expiration, err := c.snClient.BuildCascadeMetadataFromFile(ctx, filePath, options.Public)
47+
meta, price, expiration, err := c.snClient.BuildCascadeMetadataFromFile(ctx, filePath, isPublic)
5048
if err != nil {
5149
return nil, nil, fmt.Errorf("failed to build metadata: %w", err)
5250
}
5351
metaBytes, err := json.Marshal(&meta)
5452
if err != nil {
5553
return nil, nil, fmt.Errorf("failed to marshal metadata: %w", err)
5654
}
57-
c.logf("cascade: built metadata for %s (public=%t price=%s expires=%s)", filePath, options.Public, price, expiration)
55+
c.logf("cascade: built metadata for %s (public=%t price=%s expires=%s)", filePath, isPublic, price, expiration)
5856

5957
// Construct the action message
6058
msg := blockchain.NewMsgRequestAction(creator, actiontypes.ActionTypeCascade, string(metaBytes), price, expiration)
@@ -63,7 +61,8 @@ func (c *Client) CreateRequestActionMessage(ctx context.Context, creator string,
6361

6462
// SendRequestActionMessage signs, simulates and broadcasts the provided request message.
6563
// "memo" can be used to pass an optional filename or idempotency key.
66-
func (c *Client) SendRequestActionMessage(ctx context.Context, bc *blockchain.Client, msg *actiontypes.MsgRequestAction, memo string) (*types.ActionResult, error) {
64+
func (c *Client) SendRequestActionMessage(ctx context.Context, bc *blockchain.Client, msg *actiontypes.MsgRequestAction,
65+
memo string, options *UploadOptions) (*types.ActionResult, error) {
6766
if bc == nil || msg == nil {
6867
return nil, fmt.Errorf("blockchain client and msg are required")
6968
}
@@ -73,16 +72,22 @@ func (c *Client) SendRequestActionMessage(ctx context.Context, bc *blockchain.Cl
7372
at = actiontypes.ActionType(v)
7473
}
7574

75+
var id string
76+
if options != nil {
77+
id = options.ID
78+
}
79+
7680
// Request Action transaction
7781
taskType := normalizeTaskType(msg.GetActionType())
7882
c.emitClientEvent(ctx, sdkEvent.Event{
79-
Type: sdkEvent.SDKActionRegistrationRequested,
83+
Type: sdkEvent.SDKGoActionRegistrationRequested,
8084
TaskType: taskType,
85+
TaskID: id,
8186
Timestamp: time.Now(),
8287
Data: sdkEvent.EventData{
83-
sdkEvent.KeyEventType: taskType,
8488
sdkEvent.KeyPrice: msg.Price,
8589
sdkEvent.KeyExpiration: msg.ExpirationTime,
90+
sdkEvent.KeyMessage: "Action registration requested",
8691
},
8792
})
8893

@@ -94,14 +99,15 @@ func (c *Client) SendRequestActionMessage(ctx context.Context, bc *blockchain.Cl
9499

95100
actionID := ar.ActionID
96101
c.emitClientEvent(ctx, sdkEvent.Event{
97-
Type: sdkEvent.SDKActionRegistrationConfirmed,
102+
Type: sdkEvent.SDKGoActionRegistrationConfirmed,
98103
ActionID: actionID,
104+
TaskID: id,
99105
TaskType: taskType,
100106
Timestamp: time.Now(),
101107
Data: sdkEvent.EventData{
102-
sdkEvent.KeyActionID: actionID,
103108
sdkEvent.KeyTxHash: ar.TxHash,
104109
sdkEvent.KeyBlockHeight: ar.Height,
110+
sdkEvent.KeyMessage: "Action registration confirmed",
105111
},
106112
})
107113
c.logf("cascade: request action confirmed action_id=%s height=%d tx=%s", actionID, ar.Height, ar.TxHash)
@@ -144,6 +150,16 @@ func (c *Client) UploadToSupernode(ctx context.Context, actionID string, filePat
144150
if err != nil {
145151
return "", fmt.Errorf("failed to start cascade: %w", err)
146152
}
153+
// emit upload started event
154+
c.emitClientEvent(ctx, sdkEvent.Event{
155+
Type: sdkEvent.SDKGoUploadStarted,
156+
ActionID: actionID,
157+
TaskID: taskID,
158+
Data: sdkEvent.EventData{
159+
sdkEvent.KeyMessage: "Cascade upload task started",
160+
},
161+
Timestamp: time.Now(),
162+
})
147163

148164
// Wait for task completion
149165
if task, err := c.tasks.Wait(ctx, taskID); err != nil {
@@ -155,20 +171,28 @@ func (c *Client) UploadToSupernode(ctx context.Context, actionID string, filePat
155171
}
156172

157173
// Upload provides a one-shot convenience helper that performs:
158-
// 1) CreateRequestActionMessage 2) SendRequestActionMessage 3) UploadToSupernode
174+
// 1) CreateRequestActionMessage
175+
// 2) SendRequestActionMessage
176+
// 3) UploadToSupernode
159177
func (c *Client) Upload(ctx context.Context, creator string, bc *blockchain.Client, filePath string, opts ...UploadOption) (*types.CascadeResult, error) {
178+
179+
// Apply upload options
180+
options := &UploadOptions{Public: false}
181+
for _, opt := range opts {
182+
opt(options)
183+
}
184+
160185
// Build message
161-
msg, _, err := c.CreateRequestActionMessage(ctx, creator, filePath, opts...)
186+
msg, _, err := c.CreateRequestActionMessage(ctx, creator, filePath, options)
162187
if err != nil {
163188
return nil, err
164189
}
165190

191+
// extract filename from path
192+
fileName := filepath.Base(filePath)
193+
166194
// Broadcast
167-
options := &UploadOptions{Public: false}
168-
for _, opt := range opts {
169-
opt(options)
170-
}
171-
ar, err := c.SendRequestActionMessage(ctx, bc, msg, options.FileName)
195+
ar, err := c.SendRequestActionMessage(ctx, bc, msg, fileName, options)
172196
if err != nil {
173197
return nil, fmt.Errorf("request action tx: %w", err)
174198
}
@@ -205,14 +229,36 @@ func (c *Client) Download(ctx context.Context, actionID string, outputDir string
205229
opt(options)
206230
}
207231

232+
taskType := string(types.ActionTypeCascade)
233+
c.logf("cascade: starting download, action=%s dest=%s", actionID, outputDir)
234+
c.emitClientEvent(ctx, sdkEvent.Event{
235+
Type: sdkEvent.SDKGoDownloadStarted,
236+
ActionID: actionID,
237+
TaskType: taskType,
238+
Data: sdkEvent.EventData{
239+
sdkEvent.KeyMessage: "Cascade download task started",
240+
},
241+
Timestamp: time.Now(),
242+
})
243+
208244
// Create download signature
209245
signature, err := c.snClient.GenerateDownloadSignature(ctx, actionID, c.config.Address)
210246
if err != nil {
211247
return nil, fmt.Errorf("failed to create signature: %w", err)
212248
}
213249

250+
c.logf("cascade: download signature generated, action=%s", actionID)
251+
c.emitClientEvent(ctx, sdkEvent.Event{
252+
Type: sdkEvent.SDKGoDownloadSignatureGenerated,
253+
ActionID: actionID,
254+
TaskType: taskType,
255+
Data: sdkEvent.EventData{
256+
sdkEvent.KeyMessage: "Cascade download signature generated",
257+
},
258+
Timestamp: time.Now(),
259+
})
260+
214261
// Start download via SuperNode SDK
215-
c.logf("cascade: starting download action_id=%s dest=%s", actionID, outputDir)
216262
taskID, err := c.snClient.DownloadCascade(ctx, actionID, outputDir, signature)
217263
if err != nil {
218264
return nil, fmt.Errorf("failed to start download: %w", err)
@@ -223,13 +269,26 @@ func (c *Client) Download(ctx context.Context, actionID string, outputDir string
223269
if err != nil {
224270
return nil, fmt.Errorf("download failed: %w", err)
225271
}
226-
c.logf("cascade: download completed action_id=%s task_id=%s", actionID, task.TaskID)
227272

228-
return &types.DownloadResult{
273+
result := &types.DownloadResult{
229274
ActionID: actionID,
230275
TaskID: task.TaskID,
231276
OutputPath: outputDir + "/" + actionID,
232-
}, nil
277+
}
278+
279+
c.logf("cascade: download completed action_id=%s task_id=%s", actionID, taskID)
280+
c.emitClientEvent(ctx, sdkEvent.Event{
281+
Type: sdkEvent.SDKGoDownloadCompleted,
282+
ActionID: actionID,
283+
TaskType: taskType,
284+
TaskID: taskID,
285+
Data: sdkEvent.EventData{
286+
sdkEvent.KeyMessage: "Cascade download task completed",
287+
},
288+
Timestamp: time.Now(),
289+
})
290+
291+
return result, nil
233292
}
234293

235294
func (c *Client) emitClientEvent(ctx context.Context, evt sdkEvent.Event) {

cascade/client.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"sync"
77
"time"
8+
"strings"
89

910
"github.com/LumeraProtocol/lumera/x/lumeraid/securekeyx"
1011
snsdk "github.com/LumeraProtocol/supernode/v2/sdk/action"
@@ -89,12 +90,8 @@ func (c *Client) Close() error {
8990
}
9091

9192
func (c *Client) isLocalEventType(t sdkEvent.EventType) bool {
92-
switch t {
93-
case sdkEvent.SDKActionRegistrationRequested, sdkEvent.SDKActionRegistrationConfirmed:
94-
return true
95-
default:
96-
return false
97-
}
93+
// EventType format: type:subtype
94+
return strings.HasPrefix(string(t), "sdk-go:")
9895
}
9996

10097
func (c *Client) addLocalSubscriber(t sdkEvent.EventType, handler sdkEvent.Handler) {

cascade/event/types.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,12 @@ const (
5252
SupernodeUnknown EventType = "supernode:unknown"
5353
SupernodeFinalizeSimulationFailed EventType = "supernode:finalize_simulation_failed"
5454

55-
SDKActionRegistrationRequested EventType = "sdk:action_registration_requested"
56-
SDKActionRegistrationConfirmed EventType = "sdk:action_registration_confirmed"
55+
SDKGoActionRegistrationRequested EventType = "sdk-go:action_registration_requested"
56+
SDKGoActionRegistrationConfirmed EventType = "sdk-go:action_registration_confirmed"
57+
SDKGoUploadStarted EventType = "sdk-go:upload_started"
58+
SDKGoDownloadStarted EventType = "sdk-go:download_started"
59+
SDKGoDownloadCompleted EventType = "sdk-go:download_completed"
60+
SDKGoDownloadSignatureGenerated EventType = "sdk-go:download_signature_generated"
5761
)
5862

5963
// EventDataKey identifies metadata entries.

examples/cascade-upload/main.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ func main() {
2525

2626
filePath := flag.String("file-path", "", "Path to file to upload (required)")
2727
public := flag.Bool("public", true, "Whether upload is public")
28-
upFileName := flag.String("file-name", "", "Optional filename override")
2928
actionID := flag.String("action-id", "", "Existing action ID to upload bytes for (skips on-chain request)")
3029
flag.Parse()
3130

@@ -61,6 +60,9 @@ func main() {
6160
}
6261
defer client.Close() //nolint:errcheck
6362

63+
opts := []cascade.UploadOption{cascade.WithPublic(*public)}
64+
opts = append(opts, cascade.WithID("example-upload-001")) // optional custom ID for action registration tracking
65+
6466
aid := strings.TrimSpace(*actionID)
6567
if aid != "" {
6668
fmt.Println("Uploading file bytes to SuperNodes for existing action...")
@@ -83,10 +85,6 @@ func main() {
8385
}
8486

8587
fmt.Println("Uploading file...")
86-
opts := []cascade.UploadOption{cascade.WithPublic(*public)}
87-
if fn := strings.TrimSpace(*upFileName); fn != "" {
88-
opts = append(opts, cascade.WithFileName(fn))
89-
}
9088
result, err := client.Cascade.Upload(ctx, address, client.Blockchain, *filePath, opts...)
9189
if err != nil {
9290
log.Fatalf("Upload failed: %v", err)

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ require (
1919
github.com/LumeraProtocol/lumera v1.8.5
2020

2121
// SuperNode SDK for storage operations
22-
github.com/LumeraProtocol/supernode/v2 v2.4.9
22+
github.com/LumeraProtocol/supernode/v2 v2.4.10
2323
github.com/cometbft/cometbft v0.38.18
2424
github.com/cosmos/cosmos-sdk v0.53.0
2525

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ github.com/LumeraProtocol/lumera v1.8.5 h1:VfRm9bEWYehd7Ek6YJFdQBFXH47SCuDO6IFdz
7878
github.com/LumeraProtocol/lumera v1.8.5/go.mod h1:DcG+PermGhl5uA51VaSA0EC+FXpDVm2XgifmYL9jJvE=
7979
github.com/LumeraProtocol/rq-go v0.2.1 h1:8B3UzRChLsGMmvZ+UVbJsJj6JZzL9P9iYxbdUwGsQI4=
8080
github.com/LumeraProtocol/rq-go v0.2.1/go.mod h1:APnKCZRh1Es2Vtrd2w4kCLgAyaL5Bqrkz/BURoRJ+O8=
81-
github.com/LumeraProtocol/supernode/v2 v2.4.9 h1:OTncBhdIxp2ttUkDAce98NeH1KGDzdR/1UmJ8LmhiZU=
82-
github.com/LumeraProtocol/supernode/v2 v2.4.9/go.mod h1:zIwd8SoIoBEzw1ErqVlsKW2iAJ6vpwOBCK4nCpl2Kso=
81+
github.com/LumeraProtocol/supernode/v2 v2.4.10 h1:kM2N7pKw9Y+gQGVLiRaCX8/H+5aSk6n3VvNZ9RBLMZg=
82+
github.com/LumeraProtocol/supernode/v2 v2.4.10/go.mod h1:zIwd8SoIoBEzw1ErqVlsKW2iAJ6vpwOBCK4nCpl2Kso=
8383
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
8484
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
8585
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=

0 commit comments

Comments
 (0)