v0.3.4-pre.002
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# file: Cargo.toml
|
||||
# version: 364
|
||||
# version: 365
|
||||
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["crates/ksp-app-config-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.3.4-pre.1"
|
||||
version = "0.3.4-pre.2"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
DO $ksp$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'pk_ksp_raw_account_states'
|
||||
AND conrelid = to_regclass('ksp_raw_account_states')
|
||||
) THEN
|
||||
ALTER TABLE ksp_raw_account_states ADD CONSTRAINT pk_ksp_raw_account_states PRIMARY KEY (pubkey, slot, state_hash);
|
||||
END IF;
|
||||
END
|
||||
$ksp$;
|
||||
@@ -0,0 +1,12 @@
|
||||
DO $ksp$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'pk_ksp_raw_account_observations'
|
||||
AND conrelid = to_regclass('ksp_raw_account_observations')
|
||||
) THEN
|
||||
ALTER TABLE ksp_raw_account_observations ADD CONSTRAINT pk_ksp_raw_account_observations PRIMARY KEY (observation_key);
|
||||
END IF;
|
||||
END
|
||||
$ksp$;
|
||||
@@ -0,0 +1,14 @@
|
||||
DO $ksp$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'fk_ksp_raw_account_observations_state'
|
||||
AND conrelid = to_regclass('ksp_raw_account_observations')
|
||||
) THEN
|
||||
ALTER TABLE ksp_raw_account_observations
|
||||
ADD CONSTRAINT fk_ksp_raw_account_observations_state FOREIGN KEY (account_pubkey, account_slot, account_state_hash)
|
||||
REFERENCES ksp_raw_account_states(pubkey, slot, state_hash) ON DELETE RESTRICT;
|
||||
END IF;
|
||||
END
|
||||
$ksp$;
|
||||
@@ -0,0 +1,19 @@
|
||||
CREATE TABLE IF NOT EXISTS ksp_raw_account_states (
|
||||
pubkey BYTEA NOT NULL,
|
||||
slot NUMERIC(20, 0) NOT NULL,
|
||||
state_hash BYTEA NOT NULL,
|
||||
lamports NUMERIC(20, 0) NOT NULL,
|
||||
owner BYTEA NOT NULL,
|
||||
executable BOOLEAN NOT NULL,
|
||||
rent_epoch NUMERIC(20, 0) NOT NULL,
|
||||
data BYTEA NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE ksp_raw_account_states ADD COLUMN IF NOT EXISTS pubkey BYTEA NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_states ADD COLUMN IF NOT EXISTS slot NUMERIC(20, 0) NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_states ADD COLUMN IF NOT EXISTS state_hash BYTEA NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_states ADD COLUMN IF NOT EXISTS lamports NUMERIC(20, 0) NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_states ADD COLUMN IF NOT EXISTS owner BYTEA NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_states ADD COLUMN IF NOT EXISTS executable BOOLEAN NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_states ADD COLUMN IF NOT EXISTS rent_epoch NUMERIC(20, 0) NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_states ADD COLUMN IF NOT EXISTS data BYTEA NOT NULL;
|
||||
@@ -0,0 +1,41 @@
|
||||
CREATE TABLE IF NOT EXISTS ksp_raw_account_observations (
|
||||
observation_key BYTEA NOT NULL,
|
||||
account_pubkey BYTEA NOT NULL,
|
||||
account_slot NUMERIC(20, 0) NOT NULL,
|
||||
account_state_hash BYTEA NOT NULL,
|
||||
provider TEXT NOT NULL,
|
||||
protocol TEXT NOT NULL,
|
||||
acquisition_method TEXT NOT NULL,
|
||||
origin TEXT NOT NULL,
|
||||
received_at_unix_millis BIGINT NOT NULL,
|
||||
capture_session_id TEXT NULL,
|
||||
commitment TEXT NULL,
|
||||
endpoint_id TEXT NULL,
|
||||
filter_id TEXT NULL,
|
||||
observed_at_unix_millis BIGINT NULL,
|
||||
source_payload_hash BYTEA NULL,
|
||||
source_payload_size_bytes BIGINT NULL,
|
||||
is_startup BOOLEAN NULL,
|
||||
transaction_signature BYTEA NULL,
|
||||
write_version NUMERIC(20, 0) NULL
|
||||
);
|
||||
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS observation_key BYTEA NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS account_pubkey BYTEA NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS account_slot NUMERIC(20, 0) NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS account_state_hash BYTEA NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS provider TEXT NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS protocol TEXT NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS acquisition_method TEXT NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS origin TEXT NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS received_at_unix_millis BIGINT NOT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS capture_session_id TEXT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS commitment TEXT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS endpoint_id TEXT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS filter_id TEXT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS observed_at_unix_millis BIGINT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS source_payload_hash BYTEA NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS source_payload_size_bytes BIGINT NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS is_startup BOOLEAN NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS transaction_signature BYTEA NULL;
|
||||
ALTER TABLE ksp_raw_account_observations ADD COLUMN IF NOT EXISTS write_version NUMERIC(20, 0) NULL;
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/src/lib.rs
|
||||
// version: 14
|
||||
// version: 15
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -21,6 +21,8 @@
|
||||
//! with compare-and-transition outcomes and explicit rejection of `Compacted`.
|
||||
//! `0.3.3-pre.008` implements all six `RawTransaction*` capabilities directly on
|
||||
//! `PostgresBackend` while preserving the existing narrow backend bridge.
|
||||
//! `0.3.4-pre.002` registers additive V002 and its two minimal RAW account
|
||||
//! tables with canonical state/observation PKs and the observation-state FK.
|
||||
//!
|
||||
//! This crate depends on `ksp-store-api` and never on `ksp-store-lib`. The
|
||||
//! common facade consumes only this crate's narrow backend bridge and never
|
||||
@@ -93,6 +95,8 @@ pub(crate) use self::schema::SchemaResourceState;
|
||||
pub(crate) use self::schema::V000_RESOURCES;
|
||||
/// Private V001 schema resource inventory consumed by the migration engine.
|
||||
pub(crate) use self::schema::V001_RESOURCES;
|
||||
/// Private V002 schema resource inventory consumed by the migration engine.
|
||||
pub(crate) use self::schema::V002_RESOURCES;
|
||||
/// Private physical schema resource inspector consumed by the migration engine.
|
||||
pub(crate) use self::schema::inspect_resource;
|
||||
/// Private V001 adoption probe consumed by the migration engine.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/src/migration.rs
|
||||
// version: 7
|
||||
// version: 8
|
||||
|
||||
use sha2::Digest; // rust-rules: trait-import
|
||||
|
||||
@@ -19,6 +19,13 @@ const EMBEDDED_MIGRATIONS: &[EmbeddedMigration] = &[
|
||||
resources: crate::V001_RESOURCES,
|
||||
version: 1,
|
||||
},
|
||||
EmbeddedMigration {
|
||||
checksum: MigrationChecksum::Resources,
|
||||
hook: MigrationHook::None,
|
||||
name: "raw_account_state",
|
||||
resources: crate::V002_RESOURCES,
|
||||
version: 2,
|
||||
},
|
||||
];
|
||||
const HEX_LOWER: &[u8; 16] = b"0123456789abcdef";
|
||||
const HISTORY_INSERT_SQL: &str = "INSERT INTO ksp_store_schema_migrations (version, name, checksum, applied_at) VALUES ($1, $2, $3, CURRENT_TIMESTAMP)";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/src/schema.rs
|
||||
// version: 7
|
||||
// version: 8
|
||||
|
||||
/// Immutable V000 physical schema resource inventory.
|
||||
pub(crate) const V000_RESOURCES: &[SchemaResource] = &[SchemaResource {
|
||||
@@ -378,6 +378,55 @@ pub(crate) const V001_RESOURCES: &[SchemaResource] = &[
|
||||
sql: include_str!("../migrations/v001_raw_transaction/indexes/001_ix_ksp_raw_transactions_slot_signature.sql"),
|
||||
},
|
||||
];
|
||||
/// V002 physical schema resource inventory for the minimal RAW account state foundation.
|
||||
pub(crate) const V002_RESOURCES: &[SchemaResource] = &[
|
||||
SchemaResource {
|
||||
id: "tables/001_ksp_raw_account_states.sql",
|
||||
object: SchemaObjectContract::Table(TableContract {
|
||||
columns: RAW_ACCOUNT_STATES_COLUMNS,
|
||||
name: "ksp_raw_account_states",
|
||||
primary_key_columns: std::option::Option::None,
|
||||
}),
|
||||
repair_existing: true,
|
||||
sql: include_str!("../migrations/v002_raw_account_state/tables/001_ksp_raw_account_states.sql"),
|
||||
},
|
||||
SchemaResource {
|
||||
id: "tables/002_ksp_raw_account_observations.sql",
|
||||
object: SchemaObjectContract::Table(TableContract {
|
||||
columns: RAW_ACCOUNT_OBSERVATIONS_COLUMNS,
|
||||
name: "ksp_raw_account_observations",
|
||||
primary_key_columns: std::option::Option::None,
|
||||
}),
|
||||
repair_existing: true,
|
||||
sql: include_str!("../migrations/v002_raw_account_state/tables/002_ksp_raw_account_observations.sql"),
|
||||
},
|
||||
SchemaResource {
|
||||
id: "constraints/001_pk_ksp_raw_account_states.sql",
|
||||
object: SchemaObjectContract::Constraint(ConstraintContract { kind: "p", name: "pk_ksp_raw_account_states", table: "ksp_raw_account_states" }),
|
||||
repair_existing: true,
|
||||
sql: include_str!("../migrations/v002_raw_account_state/constraints/001_pk_ksp_raw_account_states.sql"),
|
||||
},
|
||||
SchemaResource {
|
||||
id: "constraints/002_pk_ksp_raw_account_observations.sql",
|
||||
object: SchemaObjectContract::Constraint(ConstraintContract {
|
||||
kind: "p",
|
||||
name: "pk_ksp_raw_account_observations",
|
||||
table: "ksp_raw_account_observations",
|
||||
}),
|
||||
repair_existing: true,
|
||||
sql: include_str!("../migrations/v002_raw_account_state/constraints/002_pk_ksp_raw_account_observations.sql"),
|
||||
},
|
||||
SchemaResource {
|
||||
id: "constraints/003_fk_ksp_raw_account_observations_state.sql",
|
||||
object: SchemaObjectContract::Constraint(ConstraintContract {
|
||||
kind: "f",
|
||||
name: "fk_ksp_raw_account_observations_state",
|
||||
table: "ksp_raw_account_observations",
|
||||
}),
|
||||
repair_existing: true,
|
||||
sql: include_str!("../migrations/v002_raw_account_state/constraints/003_fk_ksp_raw_account_observations_state.sql"),
|
||||
},
|
||||
];
|
||||
|
||||
const COLUMN_LOAD_SQL: &str = r#"SELECT column_name::TEXT, udt_name::TEXT, (is_nullable = 'YES') AS nullable, numeric_precision::INTEGER, numeric_scale::INTEGER, column_default::TEXT, is_identity::TEXT, is_generated::TEXT
|
||||
FROM information_schema.columns
|
||||
@@ -710,6 +759,199 @@ const RAW_TRANSACTION_OBSERVATIONS_COLUMNS: &[ColumnContract] = &[
|
||||
udt_name: "int8",
|
||||
},
|
||||
];
|
||||
const RAW_ACCOUNT_STATES_COLUMNS: &[ColumnContract] = &[
|
||||
ColumnContract {
|
||||
name: "pubkey",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bytea",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "slot",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::Some(20),
|
||||
numeric_scale: std::option::Option::Some(0),
|
||||
udt_name: "numeric",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "state_hash",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bytea",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "lamports",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::Some(20),
|
||||
numeric_scale: std::option::Option::Some(0),
|
||||
udt_name: "numeric",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "owner",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bytea",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "executable",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bool",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "rent_epoch",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::Some(20),
|
||||
numeric_scale: std::option::Option::Some(0),
|
||||
udt_name: "numeric",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "data",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bytea",
|
||||
},
|
||||
];
|
||||
const RAW_ACCOUNT_OBSERVATIONS_COLUMNS: &[ColumnContract] = &[
|
||||
ColumnContract {
|
||||
name: "observation_key",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bytea",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "account_pubkey",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bytea",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "account_slot",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::Some(20),
|
||||
numeric_scale: std::option::Option::Some(0),
|
||||
udt_name: "numeric",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "account_state_hash",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bytea",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "provider",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "text",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "protocol",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "text",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "acquisition_method",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "text",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "origin",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "text",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "received_at_unix_millis",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "int8",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "capture_session_id",
|
||||
nullable: true,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "text",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "commitment",
|
||||
nullable: true,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "text",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "endpoint_id",
|
||||
nullable: true,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "text",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "filter_id",
|
||||
nullable: true,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "text",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "observed_at_unix_millis",
|
||||
nullable: true,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "int8",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "source_payload_hash",
|
||||
nullable: true,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bytea",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "source_payload_size_bytes",
|
||||
nullable: true,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "int8",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "is_startup",
|
||||
nullable: true,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bool",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "transaction_signature",
|
||||
nullable: true,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "bytea",
|
||||
},
|
||||
ColumnContract {
|
||||
name: "write_version",
|
||||
nullable: true,
|
||||
numeric_precision: std::option::Option::Some(20),
|
||||
numeric_scale: std::option::Option::Some(0),
|
||||
udt_name: "numeric",
|
||||
},
|
||||
];
|
||||
const RAW_TRANSACTION_ARCHIVE_PAYLOADS_COLUMNS: &[ColumnContract] = &[
|
||||
ColumnContract {
|
||||
name: "signature",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/tests/dependency_boundary.rs
|
||||
// version: 14
|
||||
// version: 15
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -23,6 +23,7 @@ fn pre_005_backend_owns_exact_physical_runtime_dependencies_without_reverse_faca
|
||||
let bootstrap_sql = include_str!("../migrations/v000_bootstrap/tables/001_ksp_store_schema_migrations.sql");
|
||||
assert!(migration.contains("crate::V000_RESOURCES"));
|
||||
assert!(migration.contains("crate::V001_RESOURCES"));
|
||||
assert!(migration.contains("crate::V002_RESOURCES"));
|
||||
assert!(schema.contains("../migrations/v000_bootstrap/tables/001_ksp_store_schema_migrations.sql"));
|
||||
assert!(schema.contains("../migrations/v001_raw_transaction/tables/001_ksp_store_identity.sql"));
|
||||
assert!(bootstrap_sql.contains("ksp_store_schema_migrations"));
|
||||
@@ -113,7 +114,7 @@ fn pre_003_fix_001_migration_engine_uses_split_schema_contract_and_binds_network
|
||||
assert!(observation_table.contains("CREATE TABLE IF NOT EXISTS ksp_raw_transaction_observations"));
|
||||
assert!(archive_table.contains("CREATE TABLE IF NOT EXISTS ksp_raw_transaction_archive_payloads"));
|
||||
assert!(index.contains("CREATE INDEX IF NOT EXISTS ix_ksp_raw_transactions_slot_signature"));
|
||||
for forbidden in ["impl ksp_store_api::RawTransaction", "repository", "sqlx", "RawAccountState"] {
|
||||
for forbidden in ["impl ksp_store_api::RawTransaction", "impl ksp_store_api::RawAccount", "repository", "sqlx"] {
|
||||
assert!(!migration.contains(forbidden), "repository/cross-scope implementation leaked into migration engine: {forbidden}");
|
||||
assert!(!schema.contains(forbidden), "repository/cross-scope implementation leaked into schema contract: {forbidden}");
|
||||
}
|
||||
@@ -124,6 +125,25 @@ fn pre_003_fix_001_migration_engine_uses_split_schema_contract_and_binds_network
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_002_v002_is_migration_only_and_does_not_open_account_repository_or_runtime_dispatch() {
|
||||
let crate_root = include_str!("../src/lib.rs");
|
||||
let migration = include_str!("../src/migration.rs");
|
||||
let schema = include_str!("../src/schema.rs");
|
||||
let runtime = include_str!("../src/runtime.rs");
|
||||
let states = include_str!("../migrations/v002_raw_account_state/tables/001_ksp_raw_account_states.sql");
|
||||
let observations = include_str!("../migrations/v002_raw_account_state/tables/002_ksp_raw_account_observations.sql");
|
||||
assert!(migration.contains("name: \"raw_account_state\""));
|
||||
assert!(migration.contains("resources: crate::V002_RESOURCES"));
|
||||
assert!(schema.contains("pub(crate) const V002_RESOURCES"));
|
||||
assert!(states.contains("ksp_raw_account_states"));
|
||||
assert!(observations.contains("ksp_raw_account_observations"));
|
||||
assert!(!crate_root.contains("mod raw_account;"));
|
||||
assert!(!runtime.contains("impl ksp_store_api::RawAccount"));
|
||||
assert!(!std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src/raw_account.rs").exists());
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_004_raw_read_sql_and_mapping_remain_backend_private() {
|
||||
let crate_root = include_str!("../src/lib.rs");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/tests/hardening_completeness.rs
|
||||
// version: 11
|
||||
// version: 12
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -279,7 +279,9 @@ fn pre_010_raw_transaction_capability_implementation_inventory_is_exact_and_raw_
|
||||
assert!(!runtime.contains(forbidden), "RawAccountState scope opened during RawTransaction hardening: {forbidden}");
|
||||
}
|
||||
let migration = include_str!("../src/migration.rs");
|
||||
assert!(!migration.contains("ksp_raw_account"));
|
||||
assert!(migration.contains("raw_account_state"));
|
||||
assert!(migration.contains("crate::V002_RESOURCES"));
|
||||
assert!(!runtime.contains("mod raw_account"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/tests/postgres_foundation_live.rs
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -153,7 +153,7 @@ async fn run_foundation_scenario(admin: &mut tokio_postgres::Client, uri: &str,
|
||||
}
|
||||
*owns_schema = true;
|
||||
let initial_health = initial.health().await;
|
||||
if !initial_health.is_ready() || initial_health.migration_version() != std::option::Option::Some(1) || initial_health.pending_migration_count() != 0 {
|
||||
if !initial_health.is_ready() || initial_health.migration_version() != std::option::Option::Some(2) || initial_health.pending_migration_count() != 0 {
|
||||
return std::result::Result::Err(LiveFailure::new("initial_health"));
|
||||
}
|
||||
let initial_close = close_backend(initial).await;
|
||||
@@ -167,7 +167,7 @@ async fn run_foundation_scenario(admin: &mut tokio_postgres::Client, uri: &str,
|
||||
};
|
||||
let idempotent_health = idempotent.health().await;
|
||||
if !idempotent_health.is_ready()
|
||||
|| idempotent_health.migration_version() != std::option::Option::Some(1)
|
||||
|| idempotent_health.migration_version() != std::option::Option::Some(2)
|
||||
|| idempotent_health.pending_migration_count() != 0
|
||||
{
|
||||
return std::result::Result::Err(LiveFailure::new("idempotent_health"));
|
||||
@@ -250,7 +250,7 @@ async fn run_foundation_scenario(admin: &mut tokio_postgres::Client, uri: &str,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let final_health = final_backend.health().await;
|
||||
if !final_health.is_ready() || final_health.migration_version() != std::option::Option::Some(1) || final_health.pending_migration_count() != 0 {
|
||||
if !final_health.is_ready() || final_health.migration_version() != std::option::Option::Some(2) || final_health.pending_migration_count() != 0 {
|
||||
return std::result::Result::Err(LiveFailure::new("final_health"));
|
||||
}
|
||||
return close_backend(final_backend).await;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -150,7 +150,7 @@ async fn run_raw_transaction_scenario(admin: &mut tokio_postgres::Client, uri: &
|
||||
};
|
||||
*owns_schema = true;
|
||||
let initial_health = initial.health().await;
|
||||
if !initial_health.is_ready() || initial_health.migration_version() != std::option::Option::Some(1) || initial_health.pending_migration_count() != 0 {
|
||||
if !initial_health.is_ready() || initial_health.migration_version() != std::option::Option::Some(2) || initial_health.pending_migration_count() != 0 {
|
||||
return std::result::Result::Err(LiveFailure::new("initial_health"));
|
||||
}
|
||||
let wrong_network_result = open_backend_result(uri, "testnet", true, true).await;
|
||||
@@ -211,7 +211,7 @@ async fn run_raw_transaction_scenario(admin: &mut tokio_postgres::Client, uri: &
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let reopened_health = reopened.health().await;
|
||||
if !reopened_health.is_ready() || reopened_health.migration_version() != std::option::Option::Some(1) {
|
||||
if !reopened_health.is_ready() || reopened_health.migration_version() != std::option::Option::Some(2) {
|
||||
return std::result::Result::Err(LiveFailure::new("reopen_health"));
|
||||
}
|
||||
let reference_result = raw_reference(10);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/unit_tests/migration.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
fn applied(version: i64, name: &str, checksum: &str) -> super::AppliedMigration {
|
||||
return super::AppliedMigration { checksum: checksum.to_owned(), name: name.to_owned(), version };
|
||||
@@ -17,7 +17,7 @@ fn embedded(version: i64, name: &'static str, resources: &'static [crate::Schema
|
||||
|
||||
#[test]
|
||||
fn pre_003_fix_001_embedded_registry_keeps_v000_checksum_and_uses_resource_owned_v001() {
|
||||
assert_eq!(super::EMBEDDED_MIGRATIONS.len(), 2);
|
||||
assert!(super::EMBEDDED_MIGRATIONS.len() >= 2);
|
||||
let v000 = &super::EMBEDDED_MIGRATIONS[0];
|
||||
assert_eq!(v000.version, 0);
|
||||
assert_eq!(v000.name, "bootstrap");
|
||||
@@ -32,7 +32,29 @@ fn pre_003_fix_001_embedded_registry_keeps_v000_checksum_and_uses_resource_owned
|
||||
assert_eq!(v001.resources.len(), 40);
|
||||
assert_eq!(super::migration_checksum(v001), "31488cda2f08f3f46c4cdbdbb6c18c243662fada02eac4487040c8735d72cc51");
|
||||
assert!(super::validate_embedded_registry(super::EMBEDDED_MIGRATIONS).is_ok());
|
||||
assert_eq!(crate::current_migration_version(), 1);
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_002_v002_registry_is_additive_minimal_and_keeps_v000_v001_checksums_stable() {
|
||||
assert_eq!(super::EMBEDDED_MIGRATIONS.len(), 3);
|
||||
let v000 = &super::EMBEDDED_MIGRATIONS[0];
|
||||
let v001 = &super::EMBEDDED_MIGRATIONS[1];
|
||||
let v002 = &super::EMBEDDED_MIGRATIONS[2];
|
||||
assert_eq!(super::migration_checksum(v000), "d29068b8c13b9dc0cc9ef6aaadd0fa12d41e0fe4c56541a1118c4bfc846a1450");
|
||||
assert_eq!(super::migration_checksum(v001), "31488cda2f08f3f46c4cdbdbb6c18c243662fada02eac4487040c8735d72cc51");
|
||||
assert_eq!(v002.version, 2);
|
||||
assert_eq!(v002.name, "raw_account_state");
|
||||
assert_eq!(v002.hook, super::MigrationHook::None);
|
||||
assert_eq!(v002.resources.len(), 5);
|
||||
assert!(super::validate_embedded_registry(super::EMBEDDED_MIGRATIONS).is_ok());
|
||||
assert_eq!(crate::current_migration_version(), 2);
|
||||
let full = [
|
||||
applied(0, v000.name, super::migration_checksum(v000).as_str()),
|
||||
applied(1, v001.name, super::migration_checksum(v001).as_str()),
|
||||
applied(2, v002.name, super::migration_checksum(v002).as_str()),
|
||||
];
|
||||
assert_eq!(super::validate_history(&full, super::EMBEDDED_MIGRATIONS).ok(), std::option::Option::Some(3));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/unit_tests/schema.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
fn actual_column(name: &str, udt_name: &str, nullable: bool) -> super::ActualColumn {
|
||||
return super::ActualColumn {
|
||||
@@ -48,6 +48,37 @@ fn pre_003_fix_001_v001_resources_are_split_and_idempotent_by_object_family() {
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_002_v002_resources_are_exactly_two_tables_plus_base_pk_fk_without_indexes_or_domain_checks() {
|
||||
assert_eq!(crate::V002_RESOURCES.len(), 5);
|
||||
let ids = crate::V002_RESOURCES.iter().map(|resource| return resource.id).collect::<std::vec::Vec<_>>();
|
||||
assert_eq!(ids[..2], ["tables/001_ksp_raw_account_states.sql", "tables/002_ksp_raw_account_observations.sql"]);
|
||||
assert_eq!(
|
||||
ids[2..],
|
||||
[
|
||||
"constraints/001_pk_ksp_raw_account_states.sql",
|
||||
"constraints/002_pk_ksp_raw_account_observations.sql",
|
||||
"constraints/003_fk_ksp_raw_account_observations_state.sql",
|
||||
]
|
||||
);
|
||||
let sql = crate::V002_RESOURCES.iter().map(|resource| return resource.sql).collect::<std::vec::Vec<_>>().concat();
|
||||
for required in [
|
||||
"CREATE TABLE IF NOT EXISTS ksp_raw_account_states",
|
||||
"CREATE TABLE IF NOT EXISTS ksp_raw_account_observations",
|
||||
"slot NUMERIC(20, 0) NOT NULL",
|
||||
"write_version NUMERIC(20, 0) NULL",
|
||||
"PRIMARY KEY (pubkey, slot, state_hash)",
|
||||
"PRIMARY KEY (observation_key)",
|
||||
"FOREIGN KEY (account_pubkey, account_slot, account_state_hash) REFERENCES ksp_raw_account_states(pubkey, slot, state_hash) ON DELETE RESTRICT",
|
||||
] {
|
||||
assert!(sql.contains(required), "V002 pre.002 physical foundation is missing: {required}");
|
||||
}
|
||||
for forbidden in ["CREATE INDEX", " CHECK ", "ON DELETE CASCADE", "BIGSERIAL", "slot BIGINT", "data TEXT"] {
|
||||
assert!(!sql.contains(forbidden), "pre.002 advanced V002 beyond the minimal table/PK/FK scope: {forbidden}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_003_fix_001_external_extra_columns_are_accepted_only_when_they_cannot_block_ksp_inserts() {
|
||||
let nullable = actual_column("external_nullable", "text", true);
|
||||
|
||||
232
deltas/0.3.4/pre.002.md
Normal file
232
deltas/0.3.4/pre.002.md
Normal file
@@ -0,0 +1,232 @@
|
||||
<!-- file: deltas/0.3.4/pre.002.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta `0.3.4-pre.002` — registry V002 et tables RAW account minimales
|
||||
|
||||
## 1. Base requise
|
||||
|
||||
Base directe attendue :
|
||||
|
||||
```text
|
||||
0.3.4-pre.001-fix.001
|
||||
workspace.package.version = 0.3.4-pre.1
|
||||
```
|
||||
|
||||
Le gate opérateur fourni pour `pre.001` est propre : audits Rust/Markdown, `cargo check --workspace`, Clippy, tests ciblés Store/Config et `cargo check -p ksp-store-lib --no-default-features` passent. `pre.001-fix.001` est ensuite un correctif strictement documentaire ; ses audits statiques sont propres et il ne modifie pas Cargo/runtime.
|
||||
|
||||
## 2. Objectif
|
||||
|
||||
Matérialiser uniquement la première fondation physique V002 décidée en `pre.001` :
|
||||
|
||||
```text
|
||||
migration logique V002 = raw_account_state
|
||||
2 tables
|
||||
2 primary keys
|
||||
1 foreign key observation -> state
|
||||
```
|
||||
|
||||
Cette tranche n'ouvre aucun repository account, aucun dispatch Store, aucun index métier et aucune contrainte de domaine/fixed-width complète.
|
||||
|
||||
## 3. Version Cargo
|
||||
|
||||
Cette prerelease modifie code et migration SQL. Conformément à `VER-ID-009` :
|
||||
|
||||
```text
|
||||
workspace.package.version : 0.3.4-pre.1 -> 0.3.4-pre.2
|
||||
Cargo.toml header : 364 -> 365
|
||||
```
|
||||
|
||||
## 4. Registry V002
|
||||
|
||||
`EMBEDDED_MIGRATIONS` contient désormais exactement trois migrations logiques ordonnées :
|
||||
|
||||
```text
|
||||
V000 bootstrap
|
||||
V001 raw_transaction
|
||||
V002 raw_account_state
|
||||
```
|
||||
|
||||
V002 utilise `MigrationChecksum::Resources`, `MigrationHook::None` et `V002_RESOURCES`. `current_migration_version()` passe de `1` à `2`.
|
||||
|
||||
Les checksums acquis restent inchangés :
|
||||
|
||||
```text
|
||||
V000 d29068b8c13b9dc0cc9ef6aaadd0fa12d41e0fe4c56541a1118c4bfc846a1450
|
||||
V001 31488cda2f08f3f46c4cdbdbb6c18c243662fada02eac4487040c8735d72cc51
|
||||
```
|
||||
|
||||
Le checksum calculé sur les cinq resources V002 de cette tranche est :
|
||||
|
||||
```text
|
||||
30ac87496f1bb3805d816660891d7eab2127c599a636eb40c17ade5926311f55
|
||||
```
|
||||
|
||||
Il est volontairement **provisoire de prerelease** : `pre.003` doit encore ajouter les contraintes de domaine et l'index prévus, traiter explicitement la transition depuis cet état intermédiaire puis figer le checksum V002 final avant toute preuve live account persistante.
|
||||
|
||||
## 5. Ressources physiques ajoutées
|
||||
|
||||
```text
|
||||
migrations/v002_raw_account_state/
|
||||
tables/
|
||||
001_ksp_raw_account_states.sql
|
||||
002_ksp_raw_account_observations.sql
|
||||
constraints/
|
||||
001_pk_ksp_raw_account_states.sql
|
||||
002_pk_ksp_raw_account_observations.sql
|
||||
003_fk_ksp_raw_account_observations_state.sql
|
||||
```
|
||||
|
||||
### 5.1 State
|
||||
|
||||
Colonnes matérialisées exactement selon le design `pre.001` :
|
||||
|
||||
```text
|
||||
pubkey BYTEA NOT NULL
|
||||
slot NUMERIC(20,0) NOT NULL
|
||||
state_hash BYTEA NOT NULL
|
||||
lamports NUMERIC(20,0) NOT NULL
|
||||
owner BYTEA NOT NULL
|
||||
executable BOOLEAN NOT NULL
|
||||
rent_epoch NUMERIC(20,0) NOT NULL
|
||||
data BYTEA NOT NULL
|
||||
```
|
||||
|
||||
PK :
|
||||
|
||||
```text
|
||||
(pubkey, slot, state_hash)
|
||||
```
|
||||
|
||||
### 5.2 Observation
|
||||
|
||||
Les champs de provenance existants sont conservés avec les optionalités account décidées, dont :
|
||||
|
||||
```text
|
||||
is_startup BOOLEAN NULL
|
||||
transaction_signature BYTEA NULL
|
||||
write_version NUMERIC(20,0) NULL
|
||||
```
|
||||
|
||||
PK : `(observation_key)`.
|
||||
|
||||
FK :
|
||||
|
||||
```text
|
||||
(account_pubkey, account_slot, account_state_hash)
|
||||
-> ksp_raw_account_states(pubkey, slot, state_hash)
|
||||
ON DELETE RESTRICT
|
||||
```
|
||||
|
||||
Aucune FK vers `ksp_raw_transactions` n'est ajoutée.
|
||||
|
||||
## 6. Scope explicitement non avancé
|
||||
|
||||
```text
|
||||
aucun CHECK fixed-width/u64/data/provenance account
|
||||
aucun index (slot,pubkey,state_hash)
|
||||
aucun index owner/provider/time/status
|
||||
aucun src/raw_account.rs
|
||||
aucun repository/read/write account
|
||||
aucune impl RawAccount* sur PostgresBackend
|
||||
aucune impl RawAccount* sur Store
|
||||
aucune modification ksp-store-api
|
||||
aucune retention/archive/purge account
|
||||
```
|
||||
|
||||
Les contraintes et l'index sont réservés à `pre.003` ; le mapping/read commence seulement à `pre.004`.
|
||||
|
||||
## 7. Tests/canaris ajustés
|
||||
|
||||
Les tests historiques qui interdisaient l'existence même de V002 sont recalibrés sans ouvrir les capabilities account :
|
||||
|
||||
- registry V000/V001/V002 exact et `current_migration_version = 2` ;
|
||||
- inventaire V002 exact `2 tables + 3 contraintes PK/FK` ;
|
||||
- absence de CHECK/index dans V002 `pre.002` ;
|
||||
- absence de module repository account et d'impl `RawAccount*` runtime ;
|
||||
- live tests transaction/foundation existants attendent désormais migration version `2` s'ils sont exécutés.
|
||||
|
||||
Les canaris qui interdisent les quatre implémentations `RawAccount*` restent actifs.
|
||||
|
||||
## 8. Fichiers ajoutés
|
||||
|
||||
```text
|
||||
crates/ksp-store-postgres-lib/migrations/v002_raw_account_state/tables/001_ksp_raw_account_states.sql
|
||||
crates/ksp-store-postgres-lib/migrations/v002_raw_account_state/tables/002_ksp_raw_account_observations.sql
|
||||
crates/ksp-store-postgres-lib/migrations/v002_raw_account_state/constraints/001_pk_ksp_raw_account_states.sql
|
||||
crates/ksp-store-postgres-lib/migrations/v002_raw_account_state/constraints/002_pk_ksp_raw_account_observations.sql
|
||||
crates/ksp-store-postgres-lib/migrations/v002_raw_account_state/constraints/003_fk_ksp_raw_account_observations_state.sql
|
||||
deltas/0.3.4/pre.002.md
|
||||
```
|
||||
|
||||
## 9. Fichiers modifiés
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
crates/ksp-store-postgres-lib/src/lib.rs
|
||||
crates/ksp-store-postgres-lib/src/migration.rs
|
||||
crates/ksp-store-postgres-lib/src/schema.rs
|
||||
crates/ksp-store-postgres-lib/unit_tests/migration.rs
|
||||
crates/ksp-store-postgres-lib/unit_tests/schema.rs
|
||||
crates/ksp-store-postgres-lib/tests/dependency_boundary.rs
|
||||
crates/ksp-store-postgres-lib/tests/hardening_completeness.rs
|
||||
crates/ksp-store-postgres-lib/tests/postgres_foundation_live.rs
|
||||
crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs
|
||||
docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md
|
||||
docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md
|
||||
```
|
||||
|
||||
## 10. Fichiers supprimés
|
||||
|
||||
Aucun.
|
||||
|
||||
## 11. Validations exécutées dans l'environnement d'assemblage
|
||||
|
||||
```text
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
General Rust rule audit: clean
|
||||
Rust export completeness audit: 0 candidate(s)
|
||||
KSP workspace Rust rule audit: clean
|
||||
|
||||
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.3.4
|
||||
Markdown table audit: clean (239 table(s), 136 file(s))
|
||||
|
||||
assertions structurelles locales
|
||||
DIFF_SCOPE=PASS
|
||||
HEADER_VERSIONS=PASS
|
||||
V000_V001_IMMUTABLE=PASS
|
||||
V002_MINIMAL_SCOPE=PASS
|
||||
V002_CHECKSUM=30ac87496f1bb3805d816660891d7eab2127c599a636eb40c17ade5926311f55
|
||||
```
|
||||
|
||||
Le checksum V002 intermédiaire a été recalculé indépendamment à partir du domaine `ksp-migration-resources-v1\0`, des IDs ordonnés et des bytes exacts des cinq resources.
|
||||
|
||||
## 12. Validations non exécutées dans l'environnement d'assemblage
|
||||
|
||||
L'exécutable `cargo` n'est pas disponible dans cet environnement. Après application du delta, rejouer côté opérateur :
|
||||
|
||||
```text
|
||||
cargo fmt --all
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.3.4
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
cargo test -p ksp-store-api
|
||||
cargo test -p ksp-store-lib
|
||||
cargo test -p ksp-store-postgres-lib
|
||||
cargo test -p ksp-config-lib
|
||||
cargo check -p ksp-store-lib --no-default-features
|
||||
```
|
||||
|
||||
Aucun live PostgreSQL account n'est revendiqué dans `pre.002`.
|
||||
|
||||
## 13. Décisions prises
|
||||
|
||||
- V002 reste additive et ne modifie aucun byte V000/V001.
|
||||
- Les PK/FK sont des resources séparées et inspectables par le moteur existant.
|
||||
- La table state porte directement les bytes D1 RAW ; aucune représentation base64 physique n'est introduite.
|
||||
- `transaction_signature` reste metadata d'observation sans FK transaction.
|
||||
- La tranche ne crée pas de deuxième vérité `space`, de surrogate ID, d'archive account ni de processing ledger.
|
||||
|
||||
## 14. Questions ouvertes
|
||||
|
||||
Aucune question de contrat nouvelle. `pre.003` doit finaliser la surface physique V002 déjà décidée : contraintes de domaine/fixed-width, index de navigation, compatibilité schema et checksum final, y compris la transition depuis l'état intermédiaire de cette prerelease.
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- file: docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Plan `0.3.4` — Store/PostgreSQL `RawAccountState` + complétude RAW
|
||||
|
||||
## 1. Statut du gate `pre.001`
|
||||
## 1. Statut de la release
|
||||
|
||||
`0.3.4-pre.001` est un gate de conception. Il ne crée **aucun** SQL V002, aucune table account et aucun repository account. Il fixe la forme physique et le séquencement nécessaires avant implémentation.
|
||||
`0.3.4-pre.001` a figé le design. `0.3.4-pre.002` matérialise uniquement la fondation physique V002 : registry logique, deux tables, deux clés primaires et la FK observation -> state. Aucun repository account, aucun dispatch façade, aucun index métier et aucune contrainte de domaine complète ne sont ouverts dans cette tranche.
|
||||
|
||||
Base canonique auditée :
|
||||
|
||||
@@ -569,15 +569,17 @@ Remplacement du sizing tabulaire par des sous-sections éditables avec statut ex
|
||||
|
||||
### `pre.002` — Registry V002 et tables minimales
|
||||
|
||||
**Statut : planifié.**
|
||||
**Statut : réalisé ; gate Cargo opérateur post-delta à rejouer.**
|
||||
|
||||
Budget cible : **15-20 min**. Ajouter le registry V002 et les deux tables `RawAccountState`/observation avec PK/FK de base, sans repository account ni dispatch façade.
|
||||
Budget cible : **15-20 min**. V002 `raw_account_state` est enregistrée avec exactement cinq resources : deux tables, les PK `(pubkey, slot, state_hash)` / `(observation_key)` et la FK composite observation -> state. Aucun repository account ni dispatch façade n'est ajouté.
|
||||
|
||||
Le checksum resources calculable sur cet état intermédiaire est `30ac87496f1bb3805d816660891d7eab2127c599a636eb40c17ade5926311f55`. Il est **provisoire de prerelease** : `pre.003` ajoute encore les contraintes de domaine et l'index prévus, puis fige le checksum V002 final avant toute preuve live account. V000/V001 restent strictement inchangées.
|
||||
|
||||
### `pre.003` — Contraintes, index et schema compatibility V002
|
||||
|
||||
**Statut : planifié.**
|
||||
|
||||
Budget cible : **15-20 min**. Compléter les contraintes physiques, l'index de navigation, la schema compatibility et le checksum V002, sans avancer les repositories.
|
||||
Budget cible : **15-20 min**. Compléter les contraintes physiques, l'index de navigation, la schema compatibility et figer le checksum V002 final, sans avancer les repositories. Cette tranche doit traiter explicitement la transition depuis l'état V002 intermédiaire de `pre.002` avant toute utilisation live persistante.
|
||||
|
||||
### `pre.004` — Mapping privé et lectures `get`
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- file: docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Validation `0.3.4` — Store/PostgreSQL `RawAccountState` + complétude RAW
|
||||
|
||||
## 1. Portée
|
||||
|
||||
Cette matrice est ouverte par `0.3.4-pre.001`. La tranche courante valide **le design et le sizing uniquement** ; elle n'affirme aucune présence de V002 ou d'implémentation account.
|
||||
Cette matrice est ouverte par `0.3.4-pre.001`. La tranche courante `0.3.4-pre.002` matérialise uniquement la fondation V002 : registry, deux tables et PK/FK de base. Les contraintes de domaine, l'index, la compatibilité externe complète, les repositories et les quatre capabilities account restent volontairement pending.
|
||||
|
||||
Base :
|
||||
|
||||
@@ -133,18 +133,22 @@ observation_key family-local unique
|
||||
|
||||
## 7. Migration/schema V002
|
||||
|
||||
| Objet | Décision pre.001 | État |
|
||||
|----------------------------------|---------------------------------------|-------------------------|
|
||||
| V000 | immuable | PASS design |
|
||||
| V001 | immuable | PASS design |
|
||||
| V002 logical name | raw_account_state | PASS design |
|
||||
| table state | ksp_raw_account_states | PASS design |
|
||||
| table observation | ksp_raw_account_observations | PASS design |
|
||||
| Objet | Décision / état physique | État |
|
||||
|----------------------------------|--------------------------------------------------------------------------|---------------------|
|
||||
| V000 | bytes/checksum inchangés | PASS |
|
||||
| V001 | 40 resources + checksum inchangés | PASS |
|
||||
| V002 logical name | `raw_account_state` | PASS pre.002 |
|
||||
| table state | `ksp_raw_account_states` | PASS pre.002 |
|
||||
| table observation | `ksp_raw_account_observations` | PASS pre.002 |
|
||||
| PK state | `(pubkey,slot,state_hash)` | PASS pre.002 |
|
||||
| PK observation | `(observation_key)` | PASS pre.002 |
|
||||
| FK observation -> state | `(account_pubkey,account_slot,account_state_hash)` -> state composite PK | PASS pre.002 |
|
||||
| contraintes domaine/fixed-width | non encore ajoutées | PENDING pre.003 |
|
||||
| index métier | `(slot,pubkey,state_hash)` non encore ajouté | PENDING pre.003 |
|
||||
| index owner/provider/time/status | aucun prévu | PASS negative scope |
|
||||
| archive/tombstone account | aucune | PASS negative scope |
|
||||
| index métier | (slot,pubkey,state_hash) | PASS design |
|
||||
| index owner/provider/time/status | aucun | PASS negative scope |
|
||||
| SQL/resource files | pas encore créés | PENDING pre.002/pre.003 |
|
||||
| V002 checksum | inconnu tant que resources non créées | PENDING pre.003 |
|
||||
| V002 checksum intermédiaire | `30ac8749…26311f55` sur les 5 resources pre.002 | PROVISIONAL |
|
||||
| V002 checksum final | après contraintes/index de pre.003 | PENDING pre.003 |
|
||||
|
||||
## 8. Idempotence et concurrence
|
||||
|
||||
@@ -267,8 +271,8 @@ Le test live account devra être opt-in/ignored, URI stdin, sans environnement n
|
||||
|
||||
| Tranche | Objet | État |
|
||||
|---------|-------------------------------------------------------------------|---------|
|
||||
| pre.001 | audit, kbot3, threat model, V002 design, sizing, plan/validation | CURRENT |
|
||||
| pre.002 | V002 registry + deux tables + PK/FK de base, sans repository | PLANNED |
|
||||
| pre.001 | audit, kbot3, threat model, V002 design, sizing, plan/validation | DONE |
|
||||
| pre.002 | V002 registry + deux tables + PK/FK de base, sans repository | CURRENT |
|
||||
| pre.003 | contraintes complètes, index, schema compatibility, checksum V002 | PLANNED |
|
||||
| pre.004 | mapping privé state/observation + get reads + hostile rows | PLANNED |
|
||||
| pre.005 | acquisition atomique state+observation + idempotence/conflict | PLANNED |
|
||||
@@ -318,10 +322,10 @@ cargo tree --duplicates
|
||||
|
||||
Les preuves live restent séparées et explicitement `--ignored --nocapture`.
|
||||
|
||||
## 17. Verdict `pre.001`
|
||||
## 17. Verdict `pre.002`
|
||||
|
||||
Design : **PASS**. Les audits Rust/Markdown de l'overlay sont propres.
|
||||
Fondation V002 minimale : **PASS statique**. Le registry logique V002 expose exactement cinq resources et aucune surface repository/runtime account. Les audits Rust/Markdown applicables sont rejoués dans l'environnement d'assemblage.
|
||||
|
||||
Compilation/Clippy/tests post-overlay : **NON EXÉCUTÉS dans le conteneur d'assemblage**, faute d'exécutable `cargo`; ils restent à rejouer par l'opérateur.
|
||||
Compilation/Clippy/tests Cargo post-delta : **NON EXÉCUTÉS dans le conteneur d'assemblage**, faute d'exécutable `cargo`; ils restent à rejouer par l'opérateur.
|
||||
|
||||
Implémentation V002/account : **PENDING**, volontairement non ouverte dans cette tranche.
|
||||
Contraintes complètes/index/schema compatibility/checksum final : **PENDING `pre.003`**. Repository et capabilities account : **PENDING `pre.004+`**.
|
||||
|
||||
Reference in New Issue
Block a user