diff --git a/crates/bindings-cpp/include/spacetimedb/procedure_context.h b/crates/bindings-cpp/include/spacetimedb/procedure_context.h index 1ee1b88f71f..f9107d70251 100644 --- a/crates/bindings-cpp/include/spacetimedb/procedure_context.h +++ b/crates/bindings-cpp/include/spacetimedb/procedure_context.h @@ -97,17 +97,22 @@ struct ProcedureContext { * * Example: * @code - * auto module_id = ctx.identity(); + * auto module_id = ctx.database_identity(); * std::string url = "http://localhost:3000/v1/database/" + * module_id.to_hex() + "/schema?version=9"; * @endcode */ - Identity identity() const { + Identity database_identity() const { std::array id_bytes; ::identity(id_bytes.data()); return Identity(id_bytes); } + [[deprecated("Use database_identity() instead.")]] + Identity identity() const { + return database_identity(); + } + /** * @brief Get the random number generator for this procedure call * diff --git a/crates/bindings-cpp/include/spacetimedb/reducer_context.h b/crates/bindings-cpp/include/spacetimedb/reducer_context.h index 307c107e566..8c8fba26e72 100644 --- a/crates/bindings-cpp/include/spacetimedb/reducer_context.h +++ b/crates/bindings-cpp/include/spacetimedb/reducer_context.h @@ -58,11 +58,16 @@ struct ReducerContext { return *rng_instance; } - Identity identity() const { + Identity database_identity() const { std::array buffer; ::identity(buffer.data()); return Identity(buffer); } + + [[deprecated("Use database_identity() instead.")]] + Identity identity() const { + return database_identity(); + } /** * Generate a new random UUID v4. diff --git a/crates/bindings-cpp/include/spacetimedb/tx_context.h b/crates/bindings-cpp/include/spacetimedb/tx_context.h index 68d1d3181e5..1a04ef027e1 100644 --- a/crates/bindings-cpp/include/spacetimedb/tx_context.h +++ b/crates/bindings-cpp/include/spacetimedb/tx_context.h @@ -69,7 +69,9 @@ struct TxContext { // Access to ReducerContext methods Identity sender() const { return ctx_.sender(); } const AuthCtx& sender_auth() const { return ctx_.sender_auth(); } - Identity identity() const { return ctx_.identity(); } + Identity database_identity() const { return ctx_.database_identity(); } + [[deprecated("Use database_identity() instead.")]] + Identity identity() const { return database_identity(); } StdbRng& rng() const { return ctx_.rng(); } /** diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs index 3ce055b4bc7..bb33a8b65e8 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs @@ -655,9 +655,13 @@ public sealed record ReducerContext : DbContext, Internal.IReducerContext // **Note:** must be 0..=u32::MAX internal int CounterUuid; + public Identity DatabaseIdentity => Internal.IReducerContext.GetDatabaseIdentity(); - // We need this property to be non-static for parity with client SDK. - public Identity Identity => Internal.IReducerContext.GetIdentity(); + // We keep this property for compatibility with existing module code. + [global::System.Obsolete( + "ReducerContext.Identity is deprecated. Use DatabaseIdentity instead." + )] + public Identity Identity => DatabaseIdentity; internal ReducerContext( Identity identity, diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/explicitnames/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/explicitnames/snapshots/Module#FFI.verified.cs index a9774bfc69e..c963576250f 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/explicitnames/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/explicitnames/snapshots/Module#FFI.verified.cs @@ -57,9 +57,13 @@ public sealed record ReducerContext : DbContext, Internal.IReducerContext // **Note:** must be 0..=u32::MAX internal int CounterUuid; + public Identity DatabaseIdentity => Internal.IReducerContext.GetDatabaseIdentity(); - // We need this property to be non-static for parity with client SDK. - public Identity Identity => Internal.IReducerContext.GetIdentity(); + // We keep this property for compatibility with existing module code. + [global::System.Obsolete( + "ReducerContext.Identity is deprecated. Use DatabaseIdentity instead." + )] + public Identity Identity => DatabaseIdentity; internal ReducerContext( Identity identity, diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs index 4632875e05f..4c6be2c99c4 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs @@ -499,9 +499,13 @@ public sealed record ReducerContext : DbContext, Internal.IReducerContext // **Note:** must be 0..=u32::MAX internal int CounterUuid; + public Identity DatabaseIdentity => Internal.IReducerContext.GetDatabaseIdentity(); - // We need this property to be non-static for parity with client SDK. - public Identity Identity => Internal.IReducerContext.GetIdentity(); + // We keep this property for compatibility with existing module code. + [global::System.Obsolete( + "ReducerContext.Identity is deprecated. Use DatabaseIdentity instead." + )] + public Identity Identity => DatabaseIdentity; internal ReducerContext( Identity identity, diff --git a/crates/bindings-csharp/Codegen/Module.cs b/crates/bindings-csharp/Codegen/Module.cs index e778b6d69cc..f6ffa50b941 100644 --- a/crates/bindings-csharp/Codegen/Module.cs +++ b/crates/bindings-csharp/Codegen/Module.cs @@ -2189,8 +2189,10 @@ public sealed record ReducerContext : DbContext, Internal.IReducerContext public readonly AuthCtx SenderAuth; // **Note:** must be 0..=u32::MAX internal int CounterUuid; - // We need this property to be non-static for parity with client SDK. - public Identity Identity => Internal.IReducerContext.GetIdentity(); + public Identity DatabaseIdentity => Internal.IReducerContext.GetDatabaseIdentity(); + // We keep this property for compatibility with existing module code. + [global::System.Obsolete("ReducerContext.Identity is deprecated. Use DatabaseIdentity instead.")] + public Identity Identity => DatabaseIdentity; internal ReducerContext(Identity identity, ConnectionId? connectionId, Random random, Timestamp time, AuthCtx? senderAuth = null) diff --git a/crates/bindings-csharp/Runtime/Internal/IReducer.cs b/crates/bindings-csharp/Runtime/Internal/IReducer.cs index ec2e698a160..878c98a2a2e 100644 --- a/crates/bindings-csharp/Runtime/Internal/IReducer.cs +++ b/crates/bindings-csharp/Runtime/Internal/IReducer.cs @@ -1,15 +1,19 @@ namespace SpacetimeDB.Internal; +using System; using System.Text; using SpacetimeDB.BSATN; public interface IReducerContext { - public static Identity GetIdentity() + public static Identity GetDatabaseIdentity() { FFI.identity(out var identity); return identity; } + + [Obsolete("IReducerContext.GetIdentity() is deprecated. Use GetDatabaseIdentity() instead.")] + public static Identity GetIdentity() => GetDatabaseIdentity(); } public interface IReducer diff --git a/crates/bindings-typescript/src/lib/reducers.ts b/crates/bindings-typescript/src/lib/reducers.ts index a4252ba68c0..0eae2adc2a9 100644 --- a/crates/bindings-typescript/src/lib/reducers.ts +++ b/crates/bindings-typescript/src/lib/reducers.ts @@ -103,6 +103,8 @@ export interface JwtClaims { */ export type ReducerCtx = Readonly<{ sender: Identity; + databaseIdentity: Identity; + /** @deprecated Use `databaseIdentity` instead. */ identity: Identity; timestamp: Timestamp; connectionId: ConnectionId | null; diff --git a/crates/bindings-typescript/src/server/procedures.ts b/crates/bindings-typescript/src/server/procedures.ts index 5e0791c15c6..39e5f58542f 100644 --- a/crates/bindings-typescript/src/server/procedures.ts +++ b/crates/bindings-typescript/src/server/procedures.ts @@ -75,6 +75,8 @@ export interface ProcedureOpts { export interface ProcedureCtx { readonly sender: Identity; + readonly databaseIdentity: Identity; + /** @deprecated Use `databaseIdentity` instead. */ readonly identity: Identity; readonly timestamp: Timestamp; readonly connectionId: ConnectionId | null; @@ -195,10 +197,14 @@ const ProcedureCtxImpl = class ProcedureCtx this.#dbView = dbView; } - get identity() { + get databaseIdentity() { return (this.#identity ??= new Identity(sys.identity())); } + get identity() { + return this.databaseIdentity; + } + get random() { return (this.#random ??= makeRandom(this.timestamp)); } diff --git a/crates/bindings-typescript/src/server/runtime.ts b/crates/bindings-typescript/src/server/runtime.ts index e05d4c7f3e5..5031b1d850c 100644 --- a/crates/bindings-typescript/src/server/runtime.ts +++ b/crates/bindings-typescript/src/server/runtime.ts @@ -221,10 +221,14 @@ export const ReducerCtxImpl = class ReducerCtx< me.#senderAuth = undefined; } - get identity() { + get databaseIdentity() { return (this.#identity ??= new Identity(sys.identity())); } + get identity() { + return this.databaseIdentity; + } + get senderAuth() { return (this.#senderAuth ??= AuthCtxImpl.fromSystemTables( this.connectionId, diff --git a/crates/bindings/src/lib.rs b/crates/bindings/src/lib.rs index 9e02a3a97f0..68689ba3234 100644 --- a/crates/bindings/src/lib.rs +++ b/crates/bindings/src/lib.rs @@ -687,7 +687,7 @@ pub use spacetimedb_bindings_macro::table; /// /// #[reducer] /// fn scheduled(ctx: &ReducerContext, args: ScheduledArgs) -> Result<(), String> { -/// if ctx.sender() != ctx.identity() { +/// if ctx.sender() != ctx.database_identity() { /// return Err("Reducer `scheduled` may not be invoked by clients, only via scheduling.".into()); /// } /// // Reducer body... @@ -1081,7 +1081,7 @@ impl ReducerContext { } /// Read the current module's [`Identity`]. - pub fn identity(&self) -> Identity { + pub fn database_identity(&self) -> Identity { // Hypothetically, we *could* read the module identity out of the system tables. // However, this would be: // - Onerous, because we have no tooling to inspect the system tables from module code. @@ -1093,6 +1093,12 @@ impl ReducerContext { Identity::from_byte_array(spacetimedb_bindings_sys::identity()) } + /// Read the current module's [`Identity`]. + #[deprecated(note = "Use `ReducerContext::database_identity` instead.")] + pub fn identity(&self) -> Identity { + self.database_identity() + } + /// Create an anonymous (no sender) read-only view context pub fn as_anonymous_read_only(&self) -> AnonymousViewContext { AnonymousViewContext::default() diff --git a/modules/module-test-cpp/src/lib.cpp b/modules/module-test-cpp/src/lib.cpp index a50f8e74fc8..bc5305b1f16 100644 --- a/modules/module-test-cpp/src/lib.cpp +++ b/modules/module-test-cpp/src/lib.cpp @@ -280,7 +280,7 @@ SPACETIMEDB_REDUCER(list_over_age, ReducerContext ctx, uint8_t age) { // Log module identity SPACETIMEDB_REDUCER(log_module_identity, ReducerContext ctx) { - LOG_INFO("Module identity: " + ctx.identity().to_string()); + LOG_INFO("Module identity: " + ctx.database_identity().to_string()); return Ok(); } @@ -550,8 +550,8 @@ SPACETIMEDB_REDUCER(test_btree_index_args, ReducerContext ctx) { // Test reducer for assertions SPACETIMEDB_REDUCER(assert_caller_identity_is_module_identity, ReducerContext ctx) { - LOG_INFO("Sender: " + ctx.sender().to_string() + " Identity: " + ctx.identity().to_string()); - if (ctx.sender() != ctx.identity()) { + LOG_INFO("Sender: " + ctx.sender().to_string() + " Identity: " + ctx.database_identity().to_string()); + if (ctx.sender() != ctx.database_identity()) { LOG_ERROR("Assertion failed: caller identity does not match module identity"); } else { LOG_INFO("Assertion passed: caller identity matches module identity"); @@ -693,7 +693,7 @@ SPACETIMEDB_PROCEDURE(Unit, with_tx, ProcedureContext ctx) { // Hit SpacetimeDB's schema HTTP route and return its result as a string SPACETIMEDB_PROCEDURE(std::string, get_my_schema_via_http, ProcedureContext ctx) { - Identity module_identity = ctx.identity(); + Identity module_identity = ctx.database_identity(); std::string url = "http://localhost:3000/v1/database/" + module_identity.to_string() + "/schema?version=9"; auto result = ctx.http.get(url); diff --git a/modules/module-test-cs/Lib.cs b/modules/module-test-cs/Lib.cs index da038502546..3c0524bb4e0 100644 --- a/modules/module-test-cs/Lib.cs +++ b/modules/module-test-cs/Lib.cs @@ -272,7 +272,7 @@ public static void list_over_age(ReducerContext ctx, byte age) public static void log_module_identity(ReducerContext ctx) { // Note: converting to lowercase to match the Rust formatting. - Log.Info($"Module identity: {ctx.Identity.ToString().ToLower()}"); + Log.Info($"Module identity: {ctx.DatabaseIdentity.ToString().ToLower()}"); } [Reducer] @@ -464,7 +464,7 @@ public static void test_btree_index_args(ReducerContext ctx) public static void assert_caller_identity_is_module_identity(ReducerContext ctx) { var caller = ctx.Sender; - var owner = ctx.Identity; + var owner = ctx.DatabaseIdentity; if (!caller.Equals(owner)) { throw new Exception($"Caller {caller} is not the owner {owner}"); diff --git a/modules/module-test-ts/src/index.ts b/modules/module-test-ts/src/index.ts index 2c9db37d9ad..431f7bc76eb 100644 --- a/modules/module-test-ts/src/index.ts +++ b/modules/module-test-ts/src/index.ts @@ -294,7 +294,7 @@ export const listOverAge = spacetimedb.reducer( // log_module_identity() export const log_module_identity = spacetimedb.reducer(ctx => { - console.info(`Module identity: ${ctx.identity}`); + console.info(`Module identity: ${ctx.databaseIdentity}`); }); // test(arg: TestAlias(TestA), arg2: TestB, arg3: TestC, arg4: TestF) @@ -457,7 +457,7 @@ export const test_btree_index_args = spacetimedb.reducer(ctx => { export const assert_caller_identity_is_module_identity = spacetimedb.reducer( ctx => { const caller = ctx.sender; - const owner = ctx.identity; + const owner = ctx.databaseIdentity; if (String(caller) !== String(owner)) { throw new Error(`Caller ${caller} is not the owner ${owner}`); } else { @@ -470,7 +470,7 @@ export const assert_caller_identity_is_module_identity = spacetimedb.reducer( // // This is a silly thing to do, but an effective test of the procedure HTTP API. export const getMySchemaViaHttp = spacetimedb.procedure(t.string(), ctx => { - const module_identity = ctx.identity; + const module_identity = ctx.databaseIdentity; try { const response = ctx.http.fetch( `http://localhost:3000/v1/database/${module_identity}/schema?version=9` diff --git a/modules/module-test/src/lib.rs b/modules/module-test/src/lib.rs index e8a7d35ee2c..b883bcbc171 100644 --- a/modules/module-test/src/lib.rs +++ b/modules/module-test/src/lib.rs @@ -263,7 +263,7 @@ pub fn list_over_age(ctx: &ReducerContext, age: u8) { #[spacetimedb::reducer] fn log_module_identity(ctx: &ReducerContext) { - log::info!("Module identity: {}", ctx.identity()); + log::info!("Module identity: {}", ctx.database_identity()); } #[spacetimedb::reducer] @@ -471,7 +471,7 @@ fn test_btree_index_args(ctx: &ReducerContext) { #[spacetimedb::reducer] fn assert_caller_identity_is_module_identity(ctx: &ReducerContext) { let caller = ctx.sender(); - let owner = ctx.identity(); + let owner = ctx.database_identity(); if caller != owner { panic!("Caller {caller} is not the owner {owner}"); } else { diff --git a/modules/sdk-test-procedure-cpp/src/lib.cpp b/modules/sdk-test-procedure-cpp/src/lib.cpp index df9f54ae1f4..31e3669703a 100644 --- a/modules/sdk-test-procedure-cpp/src/lib.cpp +++ b/modules/sdk-test-procedure-cpp/src/lib.cpp @@ -142,7 +142,7 @@ SPACETIMEDB_PROCEDURE(Unit, insert_with_tx_rollback, ProcedureContext ctx) { // Test HTTP GET request to the module's own schema endpoint SPACETIMEDB_PROCEDURE(std::string, read_my_schema, ProcedureContext ctx) { // Get the module identity (database address) - Identity module_identity = ctx.identity(); + Identity module_identity = ctx.database_identity(); std::string identity_hex = module_identity.to_hex_string(); LOG_INFO("read_my_schema using identity: " + identity_hex); diff --git a/modules/sdk-test-procedure-ts/src/index.ts b/modules/sdk-test-procedure-ts/src/index.ts index c9cd308d780..f89aa76665a 100644 --- a/modules/sdk-test-procedure-ts/src/index.ts +++ b/modules/sdk-test-procedure-ts/src/index.ts @@ -91,7 +91,7 @@ export const will_panic = spacetimedb.procedure(t.unit(), _ctx => { }); export const read_my_schema = spacetimedb.procedure(t.string(), ctx => { - const module_identity = ctx.identity; + const module_identity = ctx.databaseIdentity; const response = ctx.http.fetch( `http://localhost:3000/v1/database/${module_identity}/schema?version=9` );