diff --git a/Makefile b/Makefile index dcb37dc6..92aeaa62 100644 --- a/Makefile +++ b/Makefile @@ -130,9 +130,9 @@ SETUP_SCRIPT=tests/scripts/setup-supernodes.sh # Install Lumera # Optional: specify lumera binary path to skip download LUMERAD_BINARY ?= -# Derive default Lumera version from go.mod (strip pseudo-version suffix if present) -LUMERA_DEFAULT_VERSION := $(shell awk '/github.com\/LumeraProtocol\/lumera[[:space:]]+v/ {print $$2; exit}' go.mod | sed 's/-.*//') -# Optional: specify installation mode (latest-release, latest-tag, or vX.Y.Z) +# Derive default Lumera version from go.mod +LUMERA_DEFAULT_VERSION := $(shell awk '/github.com\/LumeraProtocol\/lumera[[:space:]]+v/ {print $$2; exit}' go.mod) +# Optional: specify installation mode (latest-release, latest-tag, or vX.Y.Z[...]) INSTALL_MODE ?= $(if $(LUMERA_DEFAULT_VERSION),$(LUMERA_DEFAULT_VERSION),latest-release) install-lumera: @@ -192,4 +192,4 @@ release: git tag $(NEXT_TAG) git push upstream $(NEXT_TAG) - @echo "Release complete: $(NEXT_TAG) pushed to upstream" + @echo "Release complete: $(NEXT_TAG) pushed to upstream" \ No newline at end of file diff --git a/go.mod b/go.mod index 6c842cca..ae837e25 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( cosmossdk.io/math v1.5.3 github.com/AlecAivazis/survey/v2 v2.3.7 github.com/DataDog/zstd v1.5.7 - github.com/LumeraProtocol/lumera v1.8.5 + github.com/LumeraProtocol/lumera v1.8.6-rc2 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 diff --git a/go.sum b/go.sum index 1dfe6235..ab08b5ae 100644 --- a/go.sum +++ b/go.sum @@ -76,8 +76,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/LumeraProtocol/lumera v1.8.5 h1:VfRm9bEWYehd7Ek6YJFdQBFXH47SCuDO6IFdzq3y5+g= -github.com/LumeraProtocol/lumera v1.8.5/go.mod h1:DcG+PermGhl5uA51VaSA0EC+FXpDVm2XgifmYL9jJvE= +github.com/LumeraProtocol/lumera v1.8.6-rc2 h1:o4f3HOpmpk6VU+PiFOExx6F6doffLCKJUcDQzQ59TbE= +github.com/LumeraProtocol/lumera v1.8.6-rc2/go.mod h1:DcG+PermGhl5uA51VaSA0EC+FXpDVm2XgifmYL9jJvE= 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/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= diff --git a/pkg/lumera/Readme.md b/pkg/lumera/Readme.md index 4c33b34f..b25d43f3 100644 --- a/pkg/lumera/Readme.md +++ b/pkg/lumera/Readme.md @@ -53,6 +53,7 @@ resp, err := cli.ActionMsg().RequestAction( metadataJSON, // stringified JSON "23800ulume", // positive integer ulume amount fmt.Sprintf("%d", time.Now().Add(25*time.Hour).Unix()), // future expiry + "0", // fileSizeKbs (KiB; 0 if unknown) ) ``` @@ -68,6 +69,7 @@ Validation rules (built-in) - `actionType`, `metadata`, `price`, `expirationTime` required. - `price`: must be `ulume`. - `expirationTime`: future Unix seconds. + - `fileSizeKbs`: optional; if set, must be integer `>= 0`. - FinalizeCascadeAction: - `actionId` required; `rqIdsIds` must have non-empty entries. diff --git a/pkg/lumera/modules/action_msg/action_msg_mock.go b/pkg/lumera/modules/action_msg/action_msg_mock.go index c0d74bea..b8a3f46e 100644 --- a/pkg/lumera/modules/action_msg/action_msg_mock.go +++ b/pkg/lumera/modules/action_msg/action_msg_mock.go @@ -57,18 +57,18 @@ func (mr *MockModuleMockRecorder) FinalizeCascadeAction(ctx, actionId, rqIdsIds } // RequestAction mocks base method. -func (m *MockModule) RequestAction(ctx context.Context, actionType, metadata, price, expirationTime string) (*tx.BroadcastTxResponse, error) { +func (m *MockModule) RequestAction(ctx context.Context, actionType, metadata, price, expirationTime, fileSizeKbs string) (*tx.BroadcastTxResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RequestAction", ctx, actionType, metadata, price, expirationTime) + ret := m.ctrl.Call(m, "RequestAction", ctx, actionType, metadata, price, expirationTime, fileSizeKbs) ret0, _ := ret[0].(*tx.BroadcastTxResponse) ret1, _ := ret[1].(error) return ret0, ret1 } // RequestAction indicates an expected call of RequestAction. -func (mr *MockModuleMockRecorder) RequestAction(ctx, actionType, metadata, price, expirationTime any) *gomock.Call { +func (mr *MockModuleMockRecorder) RequestAction(ctx, actionType, metadata, price, expirationTime, fileSizeKbs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestAction", reflect.TypeOf((*MockModule)(nil).RequestAction), ctx, actionType, metadata, price, expirationTime) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestAction", reflect.TypeOf((*MockModule)(nil).RequestAction), ctx, actionType, metadata, price, expirationTime, fileSizeKbs) } // SimulateFinalizeCascadeAction mocks base method. diff --git a/pkg/lumera/modules/action_msg/helpers.go b/pkg/lumera/modules/action_msg/helpers.go index a1fb7e71..0ba722e0 100644 --- a/pkg/lumera/modules/action_msg/helpers.go +++ b/pkg/lumera/modules/action_msg/helpers.go @@ -10,7 +10,7 @@ import ( "github.com/LumeraProtocol/supernode/v2/pkg/lumera/util" ) -func validateRequestActionParams(actionType, metadata, price, expirationTime string) error { +func validateRequestActionParams(actionType, metadata, price, expirationTime, fileSizeKbs string) error { if actionType == "" { return fmt.Errorf("action type cannot be empty") } @@ -36,6 +36,15 @@ func validateRequestActionParams(actionType, metadata, price, expirationTime str if exp <= time.Now().Add(30*time.Second).Unix() { return fmt.Errorf("expiration time must be in the future") } + if fileSizeKbs != "" { + parsed, err := strconv.ParseInt(fileSizeKbs, 10, 64) + if err != nil { + return fmt.Errorf("invalid fileSizeKbs: %w", err) + } + if parsed < 0 { + return fmt.Errorf("fileSizeKbs must be >= 0") + } + } return nil } @@ -54,13 +63,14 @@ func validateFinalizeActionParams(actionId string, rqIdsIds []string) error { return nil } -func createRequestActionMessage(creator, actionType, metadata, price, expirationTime string) *actiontypes.MsgRequestAction { +func createRequestActionMessage(creator, actionType, metadata, price, expirationTime, fileSizeKbs string) *actiontypes.MsgRequestAction { return &actiontypes.MsgRequestAction{ Creator: creator, ActionType: actionType, Metadata: metadata, Price: price, ExpirationTime: expirationTime, + FileSizeKbs: fileSizeKbs, } } diff --git a/pkg/lumera/modules/action_msg/impl.go b/pkg/lumera/modules/action_msg/impl.go index 804fcb88..8e282225 100644 --- a/pkg/lumera/modules/action_msg/impl.go +++ b/pkg/lumera/modules/action_msg/impl.go @@ -46,8 +46,8 @@ func newModule(conn *grpc.ClientConn, authmodule auth.Module, txmodule txmod.Mod }, nil } -func (m *module) RequestAction(ctx context.Context, actionType, metadata, price, expirationTime string) (*sdktx.BroadcastTxResponse, error) { - if err := validateRequestActionParams(actionType, metadata, price, expirationTime); err != nil { +func (m *module) RequestAction(ctx context.Context, actionType, metadata, price, expirationTime, fileSizeKbs string) (*sdktx.BroadcastTxResponse, error) { + if err := validateRequestActionParams(actionType, metadata, price, expirationTime, fileSizeKbs); err != nil { return nil, err } @@ -55,7 +55,7 @@ func (m *module) RequestAction(ctx context.Context, actionType, metadata, price, defer m.mu.Unlock() return m.txHelper.ExecuteTransaction(ctx, func(creator string) (types.Msg, error) { - return createRequestActionMessage(creator, actionType, metadata, price, expirationTime), nil + return createRequestActionMessage(creator, actionType, metadata, price, expirationTime, fileSizeKbs), nil }) } diff --git a/pkg/lumera/modules/action_msg/interface.go b/pkg/lumera/modules/action_msg/interface.go index f45af851..82652bd8 100644 --- a/pkg/lumera/modules/action_msg/interface.go +++ b/pkg/lumera/modules/action_msg/interface.go @@ -13,7 +13,7 @@ import ( type Module interface { // FinalizeCascadeAction finalizes a CASCADE action with the given parameters - RequestAction(ctx context.Context, actionType, metadata, price, expirationTime string) (*sdktx.BroadcastTxResponse, error) + RequestAction(ctx context.Context, actionType, metadata, price, expirationTime, fileSizeKbs string) (*sdktx.BroadcastTxResponse, error) FinalizeCascadeAction(ctx context.Context, actionId string, rqIdsIds []string) (*sdktx.BroadcastTxResponse, error) // SimulateFinalizeCascadeAction simulates the finalize action (no broadcast) SimulateFinalizeCascadeAction(ctx context.Context, actionId string, rqIdsIds []string) (*sdktx.SimulateResponse, error) diff --git a/pkg/testutil/lumera.go b/pkg/testutil/lumera.go index 20596b85..4258599a 100644 --- a/pkg/testutil/lumera.go +++ b/pkg/testutil/lumera.go @@ -143,7 +143,7 @@ func (m *MockActionModule) GetParams(ctx context.Context) (*types.QueryParamsRes type MockActionMsgModule struct{} // RequestAction mocks the behavior of requesting an action. -func (m *MockActionMsgModule) RequestAction(ctx context.Context, actionType, metadata, price, expirationTime string) (*sdktx.BroadcastTxResponse, error) { +func (m *MockActionMsgModule) RequestAction(ctx context.Context, actionType, metadata, price, expirationTime, fileSizeKbs string) (*sdktx.BroadcastTxResponse, error) { // Mock implementation returns success with empty result return &sdktx.BroadcastTxResponse{}, nil } diff --git a/sdk/README.md b/sdk/README.md index c79db01e..5eeb12de 100644 --- a/sdk/README.md +++ b/sdk/README.md @@ -16,7 +16,7 @@ Under the hood: encodes file to a single‑block layout, signs layout/index (cre 2) Submit RequestAction (via pkg/lumera) ``` b, _ := json.Marshal(meta) -resp, err := lumeraClient.ActionMsg().RequestAction(ctx, "CASCADE", string(b), price, expiration) +resp, err := lumeraClient.ActionMsg().RequestAction(ctx, "CASCADE", string(b), price, expiration, "0") if err != nil { /* handle */ } // Extract actionID from tx events or query later ``` diff --git a/sdk/adapters/lumera/adapter.go b/sdk/adapters/lumera/adapter.go index 57c00b7e..8137a4b9 100644 --- a/sdk/adapters/lumera/adapter.go +++ b/sdk/adapters/lumera/adapter.go @@ -376,6 +376,7 @@ func toSdkAction(resp *actiontypes.QueryGetActionResponse) Action { State: ACTION_STATE(resp.Action.State.String()), Height: resp.Action.BlockHeight, ExpirationTime: resp.Action.ExpirationTime, + FileSizeKbs: resp.Action.FileSizeKbs, ActionType: resp.Action.ActionType.String(), Metadata: resp.Action.Metadata, Creator: resp.Action.Creator, diff --git a/sdk/adapters/lumera/types.go b/sdk/adapters/lumera/types.go index 300510eb..238a9e77 100644 --- a/sdk/adapters/lumera/types.go +++ b/sdk/adapters/lumera/types.go @@ -29,6 +29,7 @@ type Action struct { State ACTION_STATE Height int64 ExpirationTime int64 + FileSizeKbs int64 ActionType string // Type of the action (e.g., CASCADE) Metadata []byte // Raw metadata bytes Creator string // Creator of the action diff --git a/tests/scripts/install-lumera.sh b/tests/scripts/install-lumera.sh index 594a6ef6..d11a450a 100755 --- a/tests/scripts/install-lumera.sh +++ b/tests/scripts/install-lumera.sh @@ -42,7 +42,7 @@ if [ "$MODE" == "latest-tag" ]; then if command -v jq >/dev/null 2>&1; then TAG_NAME=$(curl -s "$GITHUB_API/tags" | jq -r '.[0].name') DOWNLOAD_URL=$(curl -s "$GITHUB_API/releases/tags/$TAG_NAME" \ - | jq -r '.assets[] | select(.name | test("linux_amd64.tar.gz$")) | .browser_download_url') + | jq -r '.assets[]? | select(.name | test("linux_amd64.tar.gz$")) | .browser_download_url') else TAG_NAME=$(curl -s "$GITHUB_API/tags" | grep '"name"' | head -n 1 | sed -E 's/.*"([^"]+)".*/\1/') DOWNLOAD_URL=$(curl -s "$GITHUB_API/releases/tags/$TAG_NAME" \ @@ -50,11 +50,11 @@ if [ "$MODE" == "latest-tag" ]; then | sed 's/.*"browser_download_url"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/') fi -elif [[ "$MODE" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then +elif [[ "$MODE" =~ ^v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then TAG_NAME="$MODE" if command -v jq >/dev/null 2>&1; then DOWNLOAD_URL=$(curl -s "$GITHUB_API/releases/tags/$TAG_NAME" \ - | jq -r '.assets[] | select(.name | test("linux_amd64.tar.gz$")) | .browser_download_url') + | jq -r '.assets[]? | select(.name | test("linux_amd64.tar.gz$")) | .browser_download_url') else DOWNLOAD_URL=$(curl -s "$GITHUB_API/releases/tags/$TAG_NAME" \ | grep -o '"browser_download_url"[[:space:]]*:[[:space:]]*"[^"]*linux_amd64\.tar\.gz[^"]*"' \ @@ -67,7 +67,7 @@ elif [ "$MODE" == "latest-release" ]; then # Extract tag name and download URL if command -v jq >/dev/null 2>&1; then TAG_NAME=$(echo "$RELEASE_INFO" | jq -r '.tag_name') - DOWNLOAD_URL=$(echo "$RELEASE_INFO" | jq -r '.assets[] | select(.name | test("linux_amd64.tar.gz$")) | .browser_download_url') + DOWNLOAD_URL=$(echo "$RELEASE_INFO" | jq -r '.assets[]? | select(.name | test("linux_amd64.tar.gz$")) | .browser_download_url') else TAG_NAME=$(echo "$RELEASE_INFO" | grep -o '"tag_name"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/') DOWNLOAD_URL=$(echo "$RELEASE_INFO" | grep -o '"browser_download_url"[[:space:]]*:[[:space:]]*"[^"]*linux_amd64\.tar\.gz[^"]*"' | sed 's/.*"browser_download_url"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/') @@ -114,4 +114,4 @@ fi # Clean up cd "$ORIG_DIR" -rm -rf "$TEMP_DIR" +rm -rf "$TEMP_DIR" \ No newline at end of file diff --git a/tests/system/e2e_cascade_test.go b/tests/system/e2e_cascade_test.go index 41ed525a..89274e33 100644 --- a/tests/system/e2e_cascade_test.go +++ b/tests/system/e2e_cascade_test.go @@ -9,6 +9,7 @@ import ( "os" "os/exec" "path/filepath" + "strconv" "strings" "testing" "time" @@ -297,7 +298,14 @@ func TestCascadeE2E(t *testing.T) { t.Logf("Requesting cascade action with metadata: %s", metadata) t.Logf("Action type: %s, Price: %s, Expiration: %s", actionType, autoPrice, expirationTime) - response, err := lumeraClinet.ActionMsg().RequestAction(ctx, actionType, metadata, autoPrice, expirationTime) + fi, err := os.Stat(testFileFullpath) + require.NoError(t, err, "Failed to stat test file") + fileSizeKbs := int64(0) + if fi != nil && fi.Size() > 0 { + fileSizeKbs = (fi.Size() + 1023) / 1024 + } + + response, err := lumeraClinet.ActionMsg().RequestAction(ctx, actionType, metadata, autoPrice, expirationTime, strconv.FormatInt(fileSizeKbs, 10)) require.NoError(t, err, "RequestAction failed") require.NotNil(t, resp, "RequestAction returned nil response") diff --git a/tests/system/go.mod b/tests/system/go.mod index 4fac1d6a..e220e08c 100644 --- a/tests/system/go.mod +++ b/tests/system/go.mod @@ -54,7 +54,7 @@ require ( github.com/99designs/keyring v1.2.2 // indirect github.com/DataDog/datadog-go v4.8.3+incompatible // indirect github.com/DataDog/zstd v1.5.7 // indirect - github.com/LumeraProtocol/lumera v1.8.4 // indirect + github.com/LumeraProtocol/lumera v1.8.6-rc2 // indirect github.com/LumeraProtocol/rq-go v0.2.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/tests/system/go.sum b/tests/system/go.sum index 9e5e89ad..59e6866c 100644 --- a/tests/system/go.sum +++ b/tests/system/go.sum @@ -72,8 +72,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/LumeraProtocol/lumera v1.8.4 h1:6XzLS9gd0m3lOnppNS05WuZx4VCBEGvUN/KpVkSjqro= -github.com/LumeraProtocol/lumera v1.8.4/go.mod h1:twrSLfuXcHvmfQoN5e02Bg7rfeevUjF34SVqEJIvH1E= +github.com/LumeraProtocol/lumera v1.8.6-rc2 h1:o4f3HOpmpk6VU+PiFOExx6F6doffLCKJUcDQzQ59TbE= +github.com/LumeraProtocol/lumera v1.8.6-rc2/go.mod h1:DcG+PermGhl5uA51VaSA0EC+FXpDVm2XgifmYL9jJvE= 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/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=