state_catalog.rs (145232B)
1 //! Immutable Myc schema and migration catalog identity. 2 3 use core::fmt; 4 use std::error::Error; 5 6 use radroots_service_sqlite::{ 7 MigrationCatalog, MigrationChecksum, MigrationDescriptor, SchemaCatalog, SchemaDigest, 8 SchemaObject, SchemaObjectKind, SchemaVersionCatalog, 9 }; 10 11 /// The shared create-new baseline written before service migrations run. 12 pub const MYC_STATE_BASE_SCHEMA_VERSION: u32 = 1; 13 14 /// The newest governed Myc state schema understood by this binary. 15 pub const MYC_STATE_SCHEMA_VERSION: u32 = 12; 16 17 /// The shared metadata and migration-ledger objects present at schema v1. 18 pub const MYC_STATE_SCHEMA_VERSION_1_OBJECT_COUNT: u32 = 6; 19 20 /// The shared objects plus the three immutable Myc metadata objects at schema v2. 21 pub const MYC_STATE_SCHEMA_VERSION_2_OBJECT_COUNT: u32 = 9; 22 23 /// The shared objects plus Myc metadata and request-admission objects at schema v3. 24 pub const MYC_STATE_SCHEMA_VERSION_3_OBJECT_COUNT: u32 = 13; 25 26 /// The shared objects plus Myc metadata, request, and connection objects at schema v4. 27 pub const MYC_STATE_SCHEMA_VERSION_4_OBJECT_COUNT: u32 = 25; 28 29 /// The shared objects plus all Myc metadata, request, connection, and governance objects at v5. 30 pub const MYC_STATE_SCHEMA_VERSION_5_OBJECT_COUNT: u32 = 34; 31 32 /// The shared objects plus Myc metadata, request, connection, governance, and delivery objects. 33 pub const MYC_STATE_SCHEMA_VERSION_6_OBJECT_COUNT: u32 = 43; 34 35 /// The shared objects plus Myc discovery desired/current state and exact documents. 36 pub const MYC_STATE_SCHEMA_VERSION_7_OBJECT_COUNT: u32 = 53; 37 38 /// The shared objects plus immutable NIP-46 operation completion evidence. 39 pub const MYC_STATE_SCHEMA_VERSION_8_OBJECT_COUNT: u32 = 56; 40 41 /// The shared objects plus immutable exact NIP-46 response authority. 42 pub const MYC_STATE_SCHEMA_VERSION_9_OBJECT_COUNT: u32 = 59; 43 44 /// The shared objects plus the append-only configuration-binding history. 45 pub const MYC_STATE_SCHEMA_VERSION_10_OBJECT_COUNT: u32 = 63; 46 47 /// The shared objects plus the bounded admin-operation journal. 48 pub const MYC_STATE_SCHEMA_VERSION_11_OBJECT_COUNT: u32 = 65; 49 50 /// The shared objects plus immutable pending-approval response authority. 51 pub const MYC_STATE_SCHEMA_VERSION_12_OBJECT_COUNT: u32 = 70; 52 53 /// SHA-256 identity of the exact schema-v1 object snapshot. 54 pub const MYC_STATE_SCHEMA_VERSION_1_SHA256: [u8; 32] = [ 55 0x94, 0xdc, 0x66, 0xfb, 0xca, 0x60, 0x16, 0x79, 0x61, 0x5c, 0x05, 0x52, 0x29, 0xdc, 0x0d, 0xb6, 56 0x11, 0x9f, 0x5b, 0xd9, 0x2b, 0x04, 0x39, 0x0c, 0x67, 0xf6, 0x98, 0xa0, 0x36, 0xfa, 0x78, 0xae, 57 ]; 58 59 /// SHA-256 identity of the schema-v2 object snapshot. 60 pub const MYC_STATE_SCHEMA_VERSION_2_SHA256: [u8; 32] = [ 61 0x94, 0x73, 0x9b, 0x5a, 0x34, 0xca, 0x8e, 0xd1, 0x30, 0xb9, 0x46, 0xd0, 0x92, 0x73, 0x1b, 0x59, 62 0xbf, 0x15, 0x48, 0xfe, 0x54, 0x1d, 0x9a, 0x92, 0x69, 0xa3, 0x3d, 0x0a, 0xed, 0x1e, 0xa0, 0x9e, 63 ]; 64 65 /// SHA-256 identity of the ordered Myc migration catalog. 66 pub const MYC_MIGRATION_CATALOG_SHA256: [u8; 32] = [ 67 0xb1, 0xd6, 0x45, 0x82, 0x45, 0xe6, 0xdf, 0xc4, 0x66, 0x1a, 0xa6, 0x14, 0x6b, 0x8c, 0xe8, 0xab, 68 0x55, 0xf7, 0xc2, 0x9b, 0xf3, 0x60, 0x99, 0xd2, 0x61, 0xc0, 0x7f, 0x5f, 0x51, 0x67, 0x56, 0x1d, 69 ]; 70 71 /// SHA-256 identity of the schema catalog bound to the migration catalog. 72 pub const MYC_STATE_SCHEMA_CATALOG_SHA256: [u8; 32] = [ 73 0xb5, 0x27, 0x21, 0xd8, 0x5c, 0x1e, 0xb8, 0xcd, 0xdc, 0x28, 0x25, 0x6c, 0x21, 0x17, 0x9a, 0x10, 74 0xd5, 0xf3, 0x2b, 0xcb, 0x33, 0xe9, 0xd2, 0xa6, 0xbb, 0x8f, 0xe4, 0x9e, 0xcb, 0xc4, 0x9a, 0x68, 75 ]; 76 77 /// SHA-256 identity of the schema-v2 migration content. 78 pub const MYC_STATE_SCHEMA_VERSION_2_MIGRATION_SHA256: [u8; 32] = [ 79 0xc5, 0xeb, 0x97, 0x8b, 0xda, 0x1b, 0xc7, 0x0c, 0x70, 0xbd, 0x9b, 0xd4, 0x4d, 0x8c, 0xba, 0x70, 80 0xcb, 0x28, 0x57, 0xd2, 0x6a, 0x9d, 0xce, 0x74, 0x96, 0x1f, 0x4b, 0x78, 0x1e, 0x71, 0x00, 0x37, 81 ]; 82 83 /// SHA-256 identity of the schema-v3 migration content. 84 pub const MYC_STATE_SCHEMA_VERSION_3_MIGRATION_SHA256: [u8; 32] = [ 85 0x75, 0x31, 0x65, 0x13, 0x6b, 0x3d, 0xac, 0xe0, 0x09, 0x1d, 0x78, 0x2f, 0x33, 0xf6, 0xb1, 0x0c, 86 0xa1, 0xa2, 0x82, 0x33, 0x14, 0x15, 0x8d, 0x80, 0xa4, 0x77, 0x5e, 0x0a, 0xf6, 0x28, 0xed, 0xf9, 87 ]; 88 89 /// SHA-256 identity of the schema-v3 object snapshot. 90 pub const MYC_STATE_SCHEMA_VERSION_3_SHA256: [u8; 32] = [ 91 0x57, 0x2f, 0xe6, 0xa4, 0xd3, 0x6c, 0x04, 0x76, 0xec, 0x40, 0x53, 0x6f, 0x48, 0x02, 0x8e, 0x15, 92 0x58, 0x48, 0x8f, 0xb8, 0xab, 0xeb, 0xa0, 0xa3, 0x4b, 0xa6, 0x9b, 0x4b, 0x70, 0x80, 0xba, 0x08, 93 ]; 94 95 /// SHA-256 identity of the schema-v4 migration content. 96 pub const MYC_STATE_SCHEMA_VERSION_4_MIGRATION_SHA256: [u8; 32] = [ 97 0x93, 0x9c, 0x0e, 0xd0, 0x7c, 0xd1, 0x5c, 0xc0, 0xc7, 0x94, 0xbf, 0x6c, 0x2a, 0xf7, 0x19, 0x22, 98 0x61, 0x40, 0x93, 0x05, 0xc2, 0x87, 0x6f, 0x3b, 0xe3, 0x63, 0xe8, 0xe4, 0xfe, 0x4a, 0x1a, 0xbb, 99 ]; 100 101 /// SHA-256 identity of the schema-v4 object snapshot. 102 pub const MYC_STATE_SCHEMA_VERSION_4_SHA256: [u8; 32] = [ 103 0x47, 0x98, 0x63, 0xd3, 0x7d, 0x91, 0xe6, 0xc2, 0x69, 0xfa, 0x35, 0x73, 0xdb, 0x6c, 0x2e, 0x76, 104 0x7c, 0xdd, 0x3b, 0x24, 0xa9, 0x3a, 0xb4, 0x82, 0xd7, 0x74, 0xbc, 0xec, 0x02, 0x18, 0xc1, 0x74, 105 ]; 106 107 /// SHA-256 identity of the schema-v5 migration content. 108 pub const MYC_STATE_SCHEMA_VERSION_5_MIGRATION_SHA256: [u8; 32] = [ 109 0x0e, 0x00, 0x4f, 0xcb, 0x5d, 0x0b, 0xc7, 0xc9, 0x51, 0xb1, 0x6f, 0x43, 0x34, 0x53, 0x3d, 0x10, 110 0xef, 0xcb, 0x18, 0xa8, 0x26, 0xf6, 0x24, 0xde, 0x09, 0x22, 0xd8, 0x6d, 0xc8, 0x50, 0x4b, 0x33, 111 ]; 112 113 /// SHA-256 identity of the schema-v5 object snapshot. 114 pub const MYC_STATE_SCHEMA_VERSION_5_SHA256: [u8; 32] = [ 115 0xfe, 0x89, 0xd4, 0xaf, 0x7d, 0xe4, 0xed, 0xed, 0x78, 0xa3, 0xf0, 0x62, 0xdc, 0x9d, 0x30, 0x0f, 116 0x06, 0xcf, 0x0f, 0x4c, 0xfc, 0xa5, 0xfa, 0x5c, 0xff, 0xc9, 0x3a, 0xf1, 0x14, 0x6f, 0x21, 0xc5, 117 ]; 118 119 /// SHA-256 identity of the schema-v6 delivery-state migration. 120 pub const MYC_STATE_SCHEMA_VERSION_6_MIGRATION_SHA256: [u8; 32] = [ 121 0x46, 0x49, 0xb9, 0xaf, 0xd0, 0x3f, 0xc0, 0x7f, 0x89, 0xfe, 0x18, 0x4f, 0x02, 0x79, 0x25, 0x67, 122 0x5a, 0x02, 0x65, 0x95, 0x1e, 0xa7, 0xcf, 0x75, 0xe0, 0x6a, 0x43, 0x12, 0xc5, 0x5a, 0x82, 0xbd, 123 ]; 124 125 /// SHA-256 identity of the schema-v6 object snapshot. 126 pub const MYC_STATE_SCHEMA_VERSION_6_SHA256: [u8; 32] = [ 127 0x55, 0x72, 0x73, 0x30, 0x6e, 0x68, 0xe9, 0x30, 0x6d, 0xc1, 0xd7, 0xc7, 0x00, 0x9e, 0x1c, 0xb7, 128 0xc9, 0xd1, 0x5b, 0x8d, 0x52, 0xe0, 0x7d, 0xb7, 0xd0, 0xbd, 0x51, 0xe8, 0x3f, 0x05, 0x44, 0x92, 129 ]; 130 131 /// SHA-256 identity of the schema-v7 discovery-state migration. 132 pub const MYC_STATE_SCHEMA_VERSION_7_MIGRATION_SHA256: [u8; 32] = [ 133 0x60, 0x97, 0xc4, 0x07, 0x76, 0xa5, 0x7d, 0xd4, 0xbd, 0xdc, 0x04, 0xe6, 0x52, 0x98, 0x72, 0x17, 134 0xd6, 0xf5, 0x99, 0x1f, 0x2d, 0x5e, 0x94, 0xd3, 0x22, 0xd1, 0x20, 0x86, 0x19, 0x25, 0x4e, 0x6c, 135 ]; 136 137 /// SHA-256 identity of the schema-v7 object snapshot. 138 pub const MYC_STATE_SCHEMA_VERSION_7_SHA256: [u8; 32] = [ 139 0x3b, 0x35, 0x28, 0x91, 0x1a, 0x29, 0x34, 0x99, 0xd9, 0x72, 0x1d, 0xa7, 0x1b, 0x6a, 0xd0, 0x7a, 140 0x5e, 0x72, 0x3e, 0x97, 0xb6, 0xeb, 0xf5, 0xb4, 0x0a, 0x19, 0xb9, 0x05, 0x89, 0x58, 0xbf, 0x79, 141 ]; 142 143 /// SHA-256 identity of the schema-v8 operation-completion migration. 144 pub const MYC_STATE_SCHEMA_VERSION_8_MIGRATION_SHA256: [u8; 32] = [ 145 0xb8, 0x1f, 0x98, 0x0c, 0x91, 0xac, 0xd9, 0x8b, 0x91, 0xec, 0xd5, 0xcb, 0x24, 0x8e, 0x40, 0x27, 146 0xc9, 0xf4, 0x7c, 0x1d, 0xc8, 0xd0, 0x13, 0x4a, 0x61, 0xaf, 0x5c, 0x38, 0x23, 0x83, 0x15, 0xbc, 147 ]; 148 149 /// SHA-256 identity of the schema-v8 object snapshot. 150 pub const MYC_STATE_SCHEMA_VERSION_8_SHA256: [u8; 32] = [ 151 0x50, 0x15, 0x8c, 0xb0, 0x93, 0xed, 0x70, 0xb3, 0xd5, 0x78, 0x37, 0x62, 0xb1, 0x8d, 0x21, 0xb7, 152 0x80, 0x96, 0x65, 0xc8, 0x9f, 0xde, 0x92, 0x5d, 0x87, 0x23, 0x65, 0x90, 0x9d, 0x28, 0xf0, 0x6e, 153 ]; 154 155 /// SHA-256 identity of the schema-v9 atomic response migration. 156 pub const MYC_STATE_SCHEMA_VERSION_9_MIGRATION_SHA256: [u8; 32] = [ 157 0xfd, 0xb0, 0x39, 0xd4, 0x72, 0xcd, 0x62, 0xe7, 0xda, 0x46, 0xc4, 0x0a, 0x97, 0x86, 0xc3, 0xa9, 158 0xa7, 0xec, 0x55, 0xf2, 0xae, 0x7d, 0xb6, 0x89, 0xd0, 0xf8, 0x55, 0xfb, 0xbf, 0x8a, 0x95, 0x66, 159 ]; 160 161 /// SHA-256 identity of the schema-v9 object snapshot. 162 pub const MYC_STATE_SCHEMA_VERSION_9_SHA256: [u8; 32] = [ 163 0xee, 0xe7, 0x6f, 0x4f, 0xf0, 0xbd, 0x2d, 0xc2, 0xc0, 0x61, 0xae, 0x38, 0x4e, 0x00, 0xde, 0x16, 164 0xc5, 0xf5, 0xef, 0xc4, 0xb6, 0xed, 0xd0, 0xac, 0x7f, 0x73, 0xca, 0xd8, 0x3a, 0x99, 0x1f, 0xf7, 165 ]; 166 167 /// SHA-256 identity of the schema-v10 configuration-binding migration. 168 pub const MYC_STATE_SCHEMA_VERSION_10_MIGRATION_SHA256: [u8; 32] = [ 169 0x28, 0x42, 0x3e, 0xbb, 0x59, 0xf4, 0xb2, 0x62, 0x23, 0x30, 0x7b, 0x74, 0xa7, 0xe1, 0x29, 0x05, 170 0xca, 0x48, 0x18, 0xc0, 0x1a, 0x65, 0x52, 0x03, 0xee, 0x8d, 0x63, 0xc9, 0x11, 0xf4, 0x44, 0x89, 171 ]; 172 173 /// SHA-256 identity of the schema-v10 object snapshot. 174 pub const MYC_STATE_SCHEMA_VERSION_10_SHA256: [u8; 32] = [ 175 0xb7, 0x7e, 0xd2, 0x3a, 0xfa, 0x39, 0xff, 0x45, 0xdd, 0xa2, 0x50, 0xfa, 0xa1, 0xeb, 0xfc, 0x05, 176 0x87, 0xc3, 0x44, 0x62, 0x65, 0x8f, 0xc4, 0x9f, 0xb7, 0xb2, 0xfb, 0xc8, 0x90, 0x9b, 0xa3, 0x03, 177 ]; 178 179 /// SHA-256 identity of the schema-v11 admin-operation journal migration. 180 pub const MYC_STATE_SCHEMA_VERSION_11_MIGRATION_SHA256: [u8; 32] = [ 181 0x16, 0x38, 0x53, 0x68, 0xaa, 0x4e, 0xe4, 0x0e, 0xa7, 0x00, 0x2a, 0x0a, 0xb4, 0x26, 0x45, 0xbc, 182 0x68, 0xb5, 0x46, 0xa4, 0xba, 0x6a, 0xfd, 0xfe, 0xde, 0x56, 0x5f, 0xe0, 0x26, 0x57, 0x6c, 0x96, 183 ]; 184 185 /// SHA-256 identity of the schema-v12 pending-approval response migration. 186 pub const MYC_STATE_SCHEMA_VERSION_12_MIGRATION_SHA256: [u8; 32] = [ 187 0x38, 0x8e, 0xe5, 0x1d, 0xe5, 0x99, 0xf3, 0x7b, 0x7b, 0xb1, 0x95, 0x6c, 0xeb, 0xd5, 0x18, 0x46, 188 0x1f, 0x3e, 0xb1, 0x93, 0x53, 0x5f, 0xfe, 0x6b, 0xb9, 0xea, 0xc2, 0xd8, 0x2b, 0xbe, 0x3e, 0x37, 189 ]; 190 191 /// SHA-256 identity of the schema-v12 object snapshot. 192 pub const MYC_STATE_SCHEMA_VERSION_12_SHA256: [u8; 32] = [ 193 0xd8, 0x93, 0xa2, 0x3b, 0xa6, 0x8e, 0x46, 0x34, 0x89, 0xad, 0x7e, 0xf1, 0xe6, 0xa8, 0x0e, 0xa4, 194 0xe8, 0x80, 0x89, 0x38, 0x1c, 0x73, 0xde, 0xcc, 0x32, 0x43, 0xa4, 0xce, 0x6f, 0x64, 0xda, 0x8f, 195 ]; 196 197 /// SHA-256 identity of the schema-v11 object snapshot. 198 pub const MYC_STATE_SCHEMA_VERSION_11_SHA256: [u8; 32] = [ 199 0x0d, 0xe7, 0xfe, 0x17, 0x6e, 0xa7, 0xda, 0x60, 0x30, 0x42, 0x4a, 0xdd, 0xc2, 0x9b, 0x9a, 0x91, 200 0x36, 0x3e, 0x88, 0xb0, 0x4d, 0xc7, 0x8d, 0xda, 0xb4, 0x80, 0xfd, 0x0f, 0x0a, 0xf9, 0x4e, 0x5a, 201 ]; 202 203 /// SHA-256 identity of the Myc metadata table definition. 204 const MYC_STATE_METADATA_TABLE_SHA256: [u8; 32] = [ 205 0x16, 0x17, 0x46, 0xa2, 0x26, 0x42, 0x46, 0x2f, 0x2b, 0xdb, 0x08, 0x5b, 0xae, 0xde, 0xb2, 0x3b, 206 0xb2, 0x83, 0xee, 0xbe, 0x8b, 0xcc, 0x95, 0x72, 0x38, 0xad, 0xaa, 0x30, 0x78, 0xc0, 0x29, 0x1a, 207 ]; 208 209 /// SHA-256 identity of the Myc metadata update guard. 210 const MYC_STATE_METADATA_NO_UPDATE_SHA256: [u8; 32] = [ 211 0xf0, 0xe3, 0x30, 0xf2, 0x19, 0x63, 0xd4, 0x94, 0xf8, 0x02, 0xf3, 0x55, 0x78, 0x4b, 0x45, 0x1c, 212 0xde, 0x2b, 0xd2, 0xc8, 0x0d, 0x90, 0x22, 0x33, 0x0e, 0x61, 0x03, 0x97, 0xd4, 0x3c, 0xbe, 0x08, 213 ]; 214 215 /// SHA-256 identity of the Myc metadata delete guard. 216 const MYC_STATE_METADATA_NO_DELETE_SHA256: [u8; 32] = [ 217 0x05, 0x32, 0x87, 0x93, 0x6d, 0xbb, 0xae, 0x52, 0x0b, 0xff, 0x25, 0xfe, 0x87, 0xd5, 0xd2, 0xd1, 218 0xa3, 0xcc, 0xf2, 0x81, 0xc3, 0x5b, 0x14, 0xa0, 0x24, 0xa7, 0x74, 0xa5, 0x67, 0x50, 0x3d, 0x4c, 219 ]; 220 221 const NIP46_REQUESTS_TABLE_SHA256: [u8; 32] = [ 222 0x7a, 0x62, 0x77, 0xaa, 0xa9, 0x71, 0x62, 0x2c, 0x1c, 0x7e, 0x0c, 0x0f, 0xab, 0x62, 0xe7, 0xfc, 223 0xfa, 0xea, 0x1b, 0x1d, 0x6f, 0x20, 0xda, 0x14, 0x7a, 0x93, 0xc7, 0x80, 0x6d, 0xd4, 0xaa, 0x54, 224 ]; 225 const NIP46_REQUEST_DEDUP_TABLE_SHA256: [u8; 32] = [ 226 0x1d, 0xe1, 0x60, 0xcb, 0x35, 0xd1, 0x84, 0x66, 0x60, 0xda, 0xfc, 0xa4, 0xae, 0x26, 0x51, 0x12, 227 0xd1, 0x4a, 0xa9, 0x19, 0x7e, 0xf3, 0x7f, 0x2a, 0x5a, 0xd7, 0xdf, 0x3d, 0xfe, 0x36, 0xd7, 0x65, 228 ]; 229 const NIP46_REQUESTS_NO_UPDATE_SHA256: [u8; 32] = [ 230 0x26, 0xfb, 0x6f, 0x52, 0x78, 0x7e, 0x07, 0x8a, 0x4a, 0xb9, 0x2f, 0xa1, 0x19, 0xf4, 0x65, 0x42, 231 0x18, 0xea, 0x3d, 0x61, 0xad, 0x58, 0xb2, 0x01, 0x3a, 0x99, 0x0e, 0xbc, 0xc9, 0xd7, 0x6b, 0x35, 232 ]; 233 const NIP46_REQUEST_DEDUP_GUARD_UPDATE_SHA256: [u8; 32] = [ 234 0x47, 0x57, 0x86, 0x7c, 0x88, 0xe8, 0xec, 0x05, 0x0c, 0xa5, 0x3d, 0x64, 0x79, 0xae, 0x22, 0xb4, 235 0x9a, 0x11, 0xa4, 0xff, 0x39, 0x32, 0xd9, 0xa3, 0x88, 0x80, 0xd3, 0x1d, 0x7e, 0x7a, 0x94, 0x6c, 236 ]; 237 238 macro_rules! myc_state_metadata_table_sql { 239 () => { 240 r#"CREATE TABLE myc_state_metadata ( 241 singleton INTEGER NOT NULL PRIMARY KEY CHECK (singleton = 1), 242 normalized_config_sha256 BLOB NOT NULL CHECK (length(normalized_config_sha256) = 32), 243 transport_public_key TEXT NOT NULL 244 CHECK (length(CAST(transport_public_key AS BLOB)) = 64) 245 CHECK (transport_public_key NOT GLOB '*[^0-9a-f]*'), 246 user_public_key TEXT NOT NULL 247 CHECK (length(CAST(user_public_key AS BLOB)) = 64) 248 CHECK (user_public_key NOT GLOB '*[^0-9a-f]*'), 249 discovery_public_key TEXT 250 CHECK (discovery_public_key IS NULL OR ( 251 length(CAST(discovery_public_key AS BLOB)) = 64 252 AND discovery_public_key NOT GLOB '*[^0-9a-f]*' 253 )), 254 config_contract_version INTEGER NOT NULL 255 CHECK (config_contract_version BETWEEN 1 AND 4294967295), 256 state_contract_version INTEGER NOT NULL 257 CHECK (state_contract_version BETWEEN 1 AND 4294967295), 258 operator_contract_version INTEGER NOT NULL 259 CHECK (operator_contract_version BETWEEN 1 AND 4294967295), 260 status_contract_version INTEGER NOT NULL 261 CHECK (status_contract_version BETWEEN 1 AND 4294967295) 262 ) STRICT"# 263 }; 264 } 265 266 macro_rules! myc_state_metadata_no_update_sql { 267 () => { 268 r#"CREATE TRIGGER myc_state_metadata_no_update 269 BEFORE UPDATE ON myc_state_metadata 270 BEGIN 271 SELECT RAISE(ABORT, 'Myc state metadata is immutable'); 272 END"# 273 }; 274 } 275 276 macro_rules! myc_state_metadata_no_delete_sql { 277 () => { 278 r#"CREATE TRIGGER myc_state_metadata_no_delete 279 BEFORE DELETE ON myc_state_metadata 280 BEGIN 281 SELECT RAISE(ABORT, 'Myc state metadata is immutable'); 282 END"# 283 }; 284 } 285 286 const CREATE_MYC_STATE_METADATA_TABLE_SQL: &str = myc_state_metadata_table_sql!(); 287 const CREATE_MYC_STATE_METADATA_NO_UPDATE_SQL: &str = myc_state_metadata_no_update_sql!(); 288 const CREATE_MYC_STATE_METADATA_NO_DELETE_SQL: &str = myc_state_metadata_no_delete_sql!(); 289 290 const CREATE_MYC_STATE_METADATA_MIGRATION_SQL: &str = concat!( 291 myc_state_metadata_table_sql!(), 292 ";\n", 293 myc_state_metadata_no_update_sql!(), 294 ";\n", 295 myc_state_metadata_no_delete_sql!(), 296 ); 297 298 macro_rules! nip46_requests_table_sql { 299 () => { 300 r#"CREATE TABLE nip46_requests ( 301 operation_id BLOB NOT NULL PRIMARY KEY CHECK (length(operation_id) = 32), 302 correlation_id BLOB NOT NULL UNIQUE CHECK (length(correlation_id) = 32), 303 operation_nonce BLOB NOT NULL CHECK (length(operation_nonce) = 32), 304 request_identity_sha256 BLOB NOT NULL UNIQUE CHECK (length(request_identity_sha256) = 32), 305 client_public_key TEXT NOT NULL 306 CHECK (length(CAST(client_public_key AS BLOB)) = 64) 307 CHECK (client_public_key NOT GLOB '*[^0-9a-f]*'), 308 request_id TEXT NOT NULL 309 CHECK (length(CAST(request_id AS BLOB)) BETWEEN 1 AND 128), 310 first_event_id BLOB NOT NULL CHECK (length(first_event_id) = 32), 311 method TEXT NOT NULL CHECK (method IN ( 312 'connect', 313 'get_public_key', 314 'get_session_capability', 315 'sign_event', 316 'nip04_encrypt', 317 'nip04_decrypt', 318 'nip44_encrypt', 319 'nip44_decrypt', 320 'ping', 321 'switch_relays', 322 'logout' 323 )), 324 request_sha256 BLOB NOT NULL CHECK (length(request_sha256) = 32), 325 received_at_unix_ms INTEGER NOT NULL 326 CHECK (received_at_unix_ms BETWEEN 1 AND 9223372036854775807) 327 ) STRICT"# 328 }; 329 } 330 331 macro_rules! nip46_request_dedup_table_sql { 332 () => { 333 r#"CREATE TABLE nip46_request_dedup ( 334 dedup_kind TEXT NOT NULL CHECK (dedup_kind IN ('request', 'event')), 335 identity_sha256 BLOB NOT NULL CHECK (length(identity_sha256) = 32), 336 request_sha256 BLOB NOT NULL CHECK (length(request_sha256) = 32), 337 operation_id BLOB NOT NULL CHECK (length(operation_id) = 32) 338 REFERENCES nip46_requests(operation_id), 339 replay_count INTEGER NOT NULL CHECK (replay_count BETWEEN 0 AND 9223372036854775807), 340 conflict_count INTEGER NOT NULL CHECK (conflict_count BETWEEN 0 AND 9223372036854775807), 341 first_seen_at_unix_ms INTEGER NOT NULL 342 CHECK (first_seen_at_unix_ms BETWEEN 1 AND 9223372036854775807), 343 last_seen_at_unix_ms INTEGER NOT NULL 344 CHECK (last_seen_at_unix_ms BETWEEN first_seen_at_unix_ms AND 9223372036854775807), 345 PRIMARY KEY (dedup_kind, identity_sha256) 346 ) STRICT"# 347 }; 348 } 349 350 macro_rules! nip46_requests_no_update_sql { 351 () => { 352 r#"CREATE TRIGGER nip46_requests_no_update 353 BEFORE UPDATE ON nip46_requests 354 BEGIN 355 SELECT RAISE(ABORT, 'NIP-46 request identity is immutable'); 356 END"# 357 }; 358 } 359 360 macro_rules! nip46_request_dedup_guard_update_sql { 361 () => { 362 r#"CREATE TRIGGER nip46_request_dedup_guard_update 363 BEFORE UPDATE ON nip46_request_dedup 364 WHEN NEW.dedup_kind != OLD.dedup_kind 365 OR NEW.identity_sha256 != OLD.identity_sha256 366 OR NEW.request_sha256 != OLD.request_sha256 367 OR NEW.operation_id != OLD.operation_id 368 OR NEW.first_seen_at_unix_ms != OLD.first_seen_at_unix_ms 369 OR NEW.last_seen_at_unix_ms < OLD.last_seen_at_unix_ms 370 OR NOT ( 371 ( 372 OLD.replay_count < 9223372036854775807 373 AND NEW.replay_count = OLD.replay_count + 1 374 AND NEW.conflict_count = OLD.conflict_count 375 ) OR ( 376 OLD.conflict_count < 9223372036854775807 377 AND NEW.conflict_count = OLD.conflict_count + 1 378 AND NEW.replay_count = OLD.replay_count 379 ) 380 ) 381 BEGIN 382 SELECT RAISE(ABORT, 'NIP-46 request evidence is append-only'); 383 END"# 384 }; 385 } 386 387 const CREATE_NIP46_REQUESTS_TABLE_SQL: &str = nip46_requests_table_sql!(); 388 const CREATE_NIP46_REQUEST_DEDUP_TABLE_SQL: &str = nip46_request_dedup_table_sql!(); 389 const CREATE_NIP46_REQUESTS_NO_UPDATE_SQL: &str = nip46_requests_no_update_sql!(); 390 const CREATE_NIP46_REQUEST_DEDUP_GUARD_UPDATE_SQL: &str = nip46_request_dedup_guard_update_sql!(); 391 392 const CREATE_NIP46_REQUEST_ADMISSION_MIGRATION_SQL: &str = concat!( 393 "DROP TRIGGER myc_state_metadata_no_update;\n", 394 "UPDATE myc_state_metadata SET state_contract_version = CASE ", 395 "WHEN state_contract_version = 2 THEN 3 ELSE 0 END WHERE singleton = 1;\n", 396 myc_state_metadata_no_update_sql!(), 397 ";\n", 398 nip46_requests_table_sql!(), 399 ";\n", 400 nip46_request_dedup_table_sql!(), 401 ";\n", 402 nip46_requests_no_update_sql!(), 403 ";\n", 404 nip46_request_dedup_guard_update_sql!(), 405 ); 406 407 macro_rules! connections_table_sql { 408 () => { 409 r#"CREATE TABLE connections ( 410 connection_id BLOB NOT NULL PRIMARY KEY CHECK (length(connection_id) = 32), 411 connection_nonce BLOB NOT NULL CHECK (length(connection_nonce) = 32), 412 client_public_key TEXT NOT NULL 413 CHECK (length(CAST(client_public_key AS BLOB)) = 64) 414 CHECK (client_public_key NOT GLOB '*[^0-9a-f]*'), 415 requested_permissions_sha256 BLOB NOT NULL 416 CHECK (length(requested_permissions_sha256) = 32), 417 policy_generation INTEGER NOT NULL 418 CHECK (policy_generation BETWEEN 1 AND 9223372036854775807), 419 status TEXT NOT NULL CHECK (status IN ('pending', 'active', 'denied', 'expired')), 420 created_at_unix_ms INTEGER NOT NULL 421 CHECK (created_at_unix_ms BETWEEN 1 AND 9223372036854775807), 422 updated_at_unix_ms INTEGER NOT NULL 423 CHECK (updated_at_unix_ms BETWEEN created_at_unix_ms AND 9223372036854775807), 424 authorized_until_unix_ms INTEGER 425 CHECK (authorized_until_unix_ms IS NULL OR 426 authorized_until_unix_ms BETWEEN created_at_unix_ms + 1 AND 9223372036854775807), 427 CHECK ((status = 'active') OR authorized_until_unix_ms IS NULL) 428 ) STRICT"# 429 }; 430 } 431 432 macro_rules! connection_permissions_table_sql { 433 () => { 434 r#"CREATE TABLE connection_permissions ( 435 connection_id BLOB NOT NULL CHECK (length(connection_id) = 32) 436 REFERENCES connections(connection_id), 437 permission_scope TEXT NOT NULL CHECK (permission_scope IN ('requested', 'granted')), 438 permission_code TEXT NOT NULL 439 CHECK (length(CAST(permission_code AS BLOB)) BETWEEN 1 AND 64), 440 PRIMARY KEY (connection_id, permission_scope, permission_code) 441 ) STRICT"# 442 }; 443 } 444 445 macro_rules! nip46_request_decisions_table_sql { 446 () => { 447 r#"CREATE TABLE nip46_request_decisions ( 448 operation_id BLOB NOT NULL PRIMARY KEY CHECK (length(operation_id) = 32) 449 REFERENCES nip46_requests(operation_id), 450 connection_id BLOB CHECK (connection_id IS NULL OR length(connection_id) = 32) 451 REFERENCES connections(connection_id), 452 decision TEXT NOT NULL 453 CHECK (decision IN ('pending_approval', 'challenged', 'allowed', 'denied')), 454 reason_code TEXT NOT NULL CHECK (reason_code IN ( 455 'explicit_approval_required', 456 'trusted_client', 457 'policy_denied', 458 'operator_approved', 459 'operator_denied', 460 'authorization_challenge_required', 461 'authorization_challenge_authorized', 462 'authorization_challenge_expired' 463 )), 464 policy_generation INTEGER NOT NULL 465 CHECK (policy_generation BETWEEN 1 AND 9223372036854775807), 466 requested_permissions_sha256 BLOB NOT NULL 467 CHECK (length(requested_permissions_sha256) = 32), 468 challenge_id BLOB UNIQUE CHECK (challenge_id IS NULL OR length(challenge_id) = 32) 469 REFERENCES connection_auth_challenges(challenge_id), 470 decided_at_unix_ms INTEGER NOT NULL 471 CHECK (decided_at_unix_ms BETWEEN 1 AND 9223372036854775807), 472 CHECK ( 473 (decision = 'denied' AND reason_code = 'policy_denied' 474 AND connection_id IS NULL AND challenge_id IS NULL) 475 OR (decision = 'pending_approval' AND reason_code = 'explicit_approval_required' 476 AND connection_id IS NOT NULL AND challenge_id IS NULL) 477 OR (decision = 'allowed' AND reason_code IN ('trusted_client', 'operator_approved') 478 AND connection_id IS NOT NULL AND challenge_id IS NULL) 479 OR (decision = 'denied' AND reason_code = 'operator_denied' 480 AND connection_id IS NOT NULL AND challenge_id IS NULL) 481 OR (decision = 'challenged' AND reason_code = 'authorization_challenge_required' 482 AND connection_id IS NOT NULL AND challenge_id IS NOT NULL) 483 OR (decision = 'allowed' AND reason_code = 'authorization_challenge_authorized' 484 AND connection_id IS NOT NULL AND challenge_id IS NOT NULL) 485 OR (decision = 'denied' AND reason_code = 'authorization_challenge_expired' 486 AND connection_id IS NOT NULL AND challenge_id IS NOT NULL) 487 ) 488 ) STRICT"# 489 }; 490 } 491 492 macro_rules! connection_auth_challenges_table_sql { 493 () => { 494 r#"CREATE TABLE connection_auth_challenges ( 495 challenge_id BLOB NOT NULL PRIMARY KEY CHECK (length(challenge_id) = 32), 496 challenge_nonce BLOB NOT NULL CHECK (length(challenge_nonce) = 32), 497 connection_id BLOB NOT NULL CHECK (length(connection_id) = 32) 498 REFERENCES connections(connection_id), 499 operation_id BLOB NOT NULL UNIQUE CHECK (length(operation_id) = 32) 500 REFERENCES nip46_requests(operation_id), 501 policy_generation INTEGER NOT NULL 502 CHECK (policy_generation BETWEEN 1 AND 9223372036854775807), 503 challenge_url TEXT NOT NULL 504 CHECK (length(CAST(challenge_url AS BLOB)) BETWEEN 1 AND 2048), 505 state TEXT NOT NULL CHECK (state IN ('pending', 'authorized', 'expired')), 506 issued_at_unix_ms INTEGER NOT NULL 507 CHECK (issued_at_unix_ms BETWEEN 1 AND 9223372036854775807), 508 expires_at_unix_ms INTEGER NOT NULL 509 CHECK (expires_at_unix_ms BETWEEN issued_at_unix_ms + 1 AND 9223372036854775807), 510 resolved_at_unix_ms INTEGER 511 CHECK (resolved_at_unix_ms IS NULL OR 512 resolved_at_unix_ms BETWEEN issued_at_unix_ms AND 9223372036854775807), 513 CHECK ((state = 'pending' AND resolved_at_unix_ms IS NULL) 514 OR (state IN ('authorized', 'expired') AND resolved_at_unix_ms IS NOT NULL)) 515 ) STRICT"# 516 }; 517 } 518 519 macro_rules! connections_guard_update_sql { 520 () => { 521 r#"CREATE TRIGGER connections_guard_update 522 BEFORE UPDATE ON connections 523 WHEN NEW.connection_id != OLD.connection_id 524 OR NEW.connection_nonce != OLD.connection_nonce 525 OR NEW.client_public_key != OLD.client_public_key 526 OR NEW.requested_permissions_sha256 != OLD.requested_permissions_sha256 527 OR NEW.policy_generation != OLD.policy_generation 528 OR NEW.created_at_unix_ms != OLD.created_at_unix_ms 529 OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms 530 OR NOT ( 531 (OLD.status = 'pending' AND NEW.status = 'active' 532 AND (NEW.authorized_until_unix_ms IS NULL 533 OR NEW.authorized_until_unix_ms > NEW.updated_at_unix_ms)) 534 OR (OLD.status = 'pending' AND NEW.status = 'denied' 535 AND NEW.authorized_until_unix_ms IS NULL) 536 OR (OLD.status = 'active' AND NEW.status = 'expired' 537 AND NEW.authorized_until_unix_ms IS NULL) 538 ) 539 BEGIN 540 SELECT RAISE(ABORT, 'connection transition is invalid'); 541 END"# 542 }; 543 } 544 545 macro_rules! connections_no_delete_sql { 546 () => { 547 r#"CREATE TRIGGER connections_no_delete 548 BEFORE DELETE ON connections 549 BEGIN 550 SELECT RAISE(ABORT, 'connection evidence is retained'); 551 END"# 552 }; 553 } 554 555 macro_rules! connection_permissions_no_update_sql { 556 () => { 557 r#"CREATE TRIGGER connection_permissions_no_update 558 BEFORE UPDATE ON connection_permissions 559 BEGIN 560 SELECT RAISE(ABORT, 'connection permission evidence is immutable'); 561 END"# 562 }; 563 } 564 565 macro_rules! connection_permissions_no_delete_sql { 566 () => { 567 r#"CREATE TRIGGER connection_permissions_no_delete 568 BEFORE DELETE ON connection_permissions 569 BEGIN 570 SELECT RAISE(ABORT, 'connection permission evidence is retained'); 571 END"# 572 }; 573 } 574 575 macro_rules! nip46_request_decisions_guard_update_sql { 576 () => { 577 r#"CREATE TRIGGER nip46_request_decisions_guard_update 578 BEFORE UPDATE ON nip46_request_decisions 579 WHEN NEW.operation_id != OLD.operation_id 580 OR NEW.connection_id IS NOT OLD.connection_id 581 OR NEW.policy_generation != OLD.policy_generation 582 OR NEW.requested_permissions_sha256 != OLD.requested_permissions_sha256 583 OR NEW.challenge_id IS NOT OLD.challenge_id 584 OR NEW.decided_at_unix_ms < OLD.decided_at_unix_ms 585 OR NOT ( 586 (OLD.decision = 'pending_approval' AND NEW.decision = 'allowed' 587 AND NEW.reason_code = 'operator_approved') 588 OR (OLD.decision = 'pending_approval' AND NEW.decision = 'denied' 589 AND NEW.reason_code = 'operator_denied') 590 OR (OLD.decision = 'challenged' AND NEW.decision = 'allowed' 591 AND NEW.reason_code = 'authorization_challenge_authorized') 592 OR (OLD.decision = 'challenged' AND NEW.decision = 'denied' 593 AND NEW.reason_code = 'authorization_challenge_expired') 594 ) 595 BEGIN 596 SELECT RAISE(ABORT, 'request decision transition is invalid'); 597 END"# 598 }; 599 } 600 601 macro_rules! nip46_request_decisions_no_delete_sql { 602 () => { 603 r#"CREATE TRIGGER nip46_request_decisions_no_delete 604 BEFORE DELETE ON nip46_request_decisions 605 BEGIN 606 SELECT RAISE(ABORT, 'request decision evidence is retained'); 607 END"# 608 }; 609 } 610 611 macro_rules! connection_auth_challenges_guard_update_sql { 612 () => { 613 r#"CREATE TRIGGER connection_auth_challenges_guard_update 614 BEFORE UPDATE ON connection_auth_challenges 615 WHEN NEW.challenge_id != OLD.challenge_id 616 OR NEW.challenge_nonce != OLD.challenge_nonce 617 OR NEW.connection_id != OLD.connection_id 618 OR NEW.operation_id != OLD.operation_id 619 OR NEW.policy_generation != OLD.policy_generation 620 OR NEW.challenge_url != OLD.challenge_url 621 OR NEW.issued_at_unix_ms != OLD.issued_at_unix_ms 622 OR NEW.expires_at_unix_ms != OLD.expires_at_unix_ms 623 OR NOT (OLD.state = 'pending' 624 AND NEW.state IN ('authorized', 'expired') 625 AND NEW.resolved_at_unix_ms IS NOT NULL 626 AND NEW.resolved_at_unix_ms >= OLD.issued_at_unix_ms) 627 BEGIN 628 SELECT RAISE(ABORT, 'authorization challenge transition is invalid'); 629 END"# 630 }; 631 } 632 633 macro_rules! connection_auth_challenges_no_delete_sql { 634 () => { 635 r#"CREATE TRIGGER connection_auth_challenges_no_delete 636 BEFORE DELETE ON connection_auth_challenges 637 BEGIN 638 SELECT RAISE(ABORT, 'authorization challenge evidence is retained'); 639 END"# 640 }; 641 } 642 643 const CREATE_CONNECTIONS_TABLE_SQL: &str = connections_table_sql!(); 644 const CREATE_CONNECTION_PERMISSIONS_TABLE_SQL: &str = connection_permissions_table_sql!(); 645 const CREATE_NIP46_REQUEST_DECISIONS_TABLE_SQL: &str = nip46_request_decisions_table_sql!(); 646 const CREATE_CONNECTION_AUTH_CHALLENGES_TABLE_SQL: &str = connection_auth_challenges_table_sql!(); 647 const CREATE_CONNECTIONS_GUARD_UPDATE_SQL: &str = connections_guard_update_sql!(); 648 const CREATE_CONNECTIONS_NO_DELETE_SQL: &str = connections_no_delete_sql!(); 649 const CREATE_CONNECTION_PERMISSIONS_NO_UPDATE_SQL: &str = connection_permissions_no_update_sql!(); 650 const CREATE_CONNECTION_PERMISSIONS_NO_DELETE_SQL: &str = connection_permissions_no_delete_sql!(); 651 const CREATE_NIP46_REQUEST_DECISIONS_GUARD_UPDATE_SQL: &str = 652 nip46_request_decisions_guard_update_sql!(); 653 const CREATE_NIP46_REQUEST_DECISIONS_NO_DELETE_SQL: &str = nip46_request_decisions_no_delete_sql!(); 654 const CREATE_CONNECTION_AUTH_CHALLENGES_GUARD_UPDATE_SQL: &str = 655 connection_auth_challenges_guard_update_sql!(); 656 const CREATE_CONNECTION_AUTH_CHALLENGES_NO_DELETE_SQL: &str = 657 connection_auth_challenges_no_delete_sql!(); 658 659 const CREATE_CONNECTION_STATE_MIGRATION_SQL: &str = concat!( 660 "DROP TRIGGER myc_state_metadata_no_update;\n", 661 "UPDATE myc_state_metadata SET state_contract_version = CASE ", 662 "WHEN state_contract_version = 3 THEN 4 ELSE 0 END WHERE singleton = 1;\n", 663 myc_state_metadata_no_update_sql!(), 664 ";\n", 665 connections_table_sql!(), 666 ";\n", 667 connection_permissions_table_sql!(), 668 ";\n", 669 nip46_request_decisions_table_sql!(), 670 ";\n", 671 connection_auth_challenges_table_sql!(), 672 ";\n", 673 connections_guard_update_sql!(), 674 ";\n", 675 connections_no_delete_sql!(), 676 ";\n", 677 connection_permissions_no_update_sql!(), 678 ";\n", 679 connection_permissions_no_delete_sql!(), 680 ";\n", 681 nip46_request_decisions_guard_update_sql!(), 682 ";\n", 683 nip46_request_decisions_no_delete_sql!(), 684 ";\n", 685 connection_auth_challenges_guard_update_sql!(), 686 ";\n", 687 connection_auth_challenges_no_delete_sql!(), 688 ); 689 690 macro_rules! myc_audit_state_table_sql { 691 () => { 692 r#"CREATE TABLE myc_audit_state ( 693 singleton INTEGER NOT NULL PRIMARY KEY CHECK (singleton = 1), 694 next_sequence INTEGER NOT NULL CHECK (next_sequence BETWEEN 0 AND 9223372036854775807) 695 ) STRICT"# 696 }; 697 } 698 699 macro_rules! operation_audit_table_sql { 700 () => { 701 r#"CREATE TABLE operation_audit ( 702 audit_sequence INTEGER NOT NULL PRIMARY KEY 703 CHECK (audit_sequence BETWEEN 1 AND 9223372036854775807), 704 audit_id BLOB NOT NULL UNIQUE CHECK (length(audit_id) = 32), 705 correlation_id BLOB NOT NULL CHECK (length(correlation_id) = 32), 706 audit_kind TEXT NOT NULL CHECK (audit_kind IN ( 707 'connection_admission', 708 'connection_operator_decision', 709 'connection_expiry', 710 'challenge_creation', 711 'challenge_authorization', 712 'governance_compaction' 713 )), 714 outcome TEXT NOT NULL CHECK (outcome IN ('succeeded', 'rejected', 'failed')), 715 reason_code TEXT NOT NULL CHECK (reason_code IN ( 716 'trusted', 717 'approval_required', 718 'policy_denied', 719 'operator_approved', 720 'operator_denied', 721 'connection_expired', 722 'challenge_required', 723 'challenge_authorized', 724 'challenge_expired', 725 'rate_limited', 726 'compacted' 727 )), 728 occurred_at_unix_ms INTEGER NOT NULL 729 CHECK (occurred_at_unix_ms BETWEEN 1 AND 9223372036854775807), 730 UNIQUE (correlation_id, audit_kind) 731 ) STRICT"# 732 }; 733 } 734 735 macro_rules! nip46_request_audit_table_sql { 736 () => { 737 r#"CREATE TABLE nip46_request_audit ( 738 operation_id BLOB NOT NULL CHECK (length(operation_id) = 32) 739 REFERENCES nip46_requests(operation_id), 740 audit_kind TEXT NOT NULL CHECK (audit_kind IN ( 741 'connection_admission', 'challenge_creation', 'challenge_authorization' 742 )), 743 audit_sequence INTEGER NOT NULL UNIQUE 744 CHECK (audit_sequence BETWEEN 1 AND 9223372036854775807) 745 REFERENCES operation_audit(audit_sequence), 746 PRIMARY KEY (operation_id, audit_kind) 747 ) STRICT"# 748 }; 749 } 750 751 macro_rules! connection_rate_windows_table_sql { 752 () => { 753 r#"CREATE TABLE connection_rate_windows ( 754 rate_kind TEXT NOT NULL CHECK (rate_kind IN ( 755 'connection_admission', 'challenge_creation', 'challenge_authorization' 756 )), 757 subject_scope TEXT NOT NULL CHECK (subject_scope IN ('global', 'relay', 'connection')), 758 subject_sha256 BLOB NOT NULL CHECK (length(subject_sha256) = 32), 759 window_started_at_unix_ms INTEGER NOT NULL 760 CHECK (window_started_at_unix_ms BETWEEN 1 AND 9223372036854775807), 761 window_ends_at_unix_ms INTEGER NOT NULL 762 CHECK (window_ends_at_unix_ms BETWEEN window_started_at_unix_ms AND 9223372036854775807), 763 accepted_count INTEGER NOT NULL CHECK (accepted_count BETWEEN 0 AND 10000), 764 rejected_count INTEGER NOT NULL CHECK (rejected_count BETWEEN 0 AND 9223372036854775807), 765 lifetime_accepted_count INTEGER NOT NULL 766 CHECK (lifetime_accepted_count BETWEEN accepted_count AND 9223372036854775807), 767 lifetime_rejected_count INTEGER NOT NULL 768 CHECK (lifetime_rejected_count BETWEEN rejected_count AND 9223372036854775807), 769 last_observed_at_unix_ms INTEGER NOT NULL 770 CHECK (last_observed_at_unix_ms BETWEEN window_started_at_unix_ms AND 9223372036854775807), 771 retention_expires_at_unix_ms INTEGER NOT NULL 772 CHECK (retention_expires_at_unix_ms BETWEEN last_observed_at_unix_ms AND 9223372036854775807), 773 CHECK ( 774 (rate_kind = 'connection_admission' AND subject_scope IN ('global', 'relay')) 775 OR (rate_kind IN ('challenge_creation', 'challenge_authorization') 776 AND subject_scope = 'connection') 777 ), 778 PRIMARY KEY (rate_kind, subject_scope, subject_sha256) 779 ) STRICT"# 780 }; 781 } 782 783 macro_rules! myc_audit_state_guard_update_sql { 784 () => { 785 r#"CREATE TRIGGER myc_audit_state_guard_update 786 BEFORE UPDATE ON myc_audit_state 787 WHEN NEW.singleton != OLD.singleton 788 OR OLD.next_sequence = 9223372036854775807 789 OR NEW.next_sequence != OLD.next_sequence + 1 790 BEGIN 791 SELECT RAISE(ABORT, 'audit sequence transition is invalid'); 792 END"# 793 }; 794 } 795 796 macro_rules! myc_audit_state_no_delete_sql { 797 () => { 798 r#"CREATE TRIGGER myc_audit_state_no_delete 799 BEFORE DELETE ON myc_audit_state 800 BEGIN 801 SELECT RAISE(ABORT, 'audit sequence authority is retained'); 802 END"# 803 }; 804 } 805 806 macro_rules! operation_audit_no_update_sql { 807 () => { 808 r#"CREATE TRIGGER operation_audit_no_update 809 BEFORE UPDATE ON operation_audit 810 BEGIN 811 SELECT RAISE(ABORT, 'operation audit is immutable'); 812 END"# 813 }; 814 } 815 816 macro_rules! nip46_request_audit_no_update_sql { 817 () => { 818 r#"CREATE TRIGGER nip46_request_audit_no_update 819 BEFORE UPDATE ON nip46_request_audit 820 BEGIN 821 SELECT RAISE(ABORT, 'request audit binding is immutable'); 822 END"# 823 }; 824 } 825 826 macro_rules! connection_rate_windows_guard_update_sql { 827 () => { 828 r#"CREATE TRIGGER connection_rate_windows_guard_update 829 BEFORE UPDATE ON connection_rate_windows 830 WHEN NEW.rate_kind != OLD.rate_kind 831 OR NEW.subject_scope != OLD.subject_scope 832 OR NEW.subject_sha256 != OLD.subject_sha256 833 OR NEW.window_started_at_unix_ms < OLD.window_started_at_unix_ms 834 OR NEW.window_ends_at_unix_ms < NEW.window_started_at_unix_ms 835 OR NEW.lifetime_accepted_count < OLD.lifetime_accepted_count 836 OR NEW.lifetime_rejected_count < OLD.lifetime_rejected_count 837 OR NEW.last_observed_at_unix_ms < OLD.last_observed_at_unix_ms 838 OR NEW.retention_expires_at_unix_ms < NEW.last_observed_at_unix_ms 839 OR NOT ( 840 (NEW.window_started_at_unix_ms = OLD.window_started_at_unix_ms 841 AND NEW.window_ends_at_unix_ms = OLD.window_ends_at_unix_ms 842 AND ( 843 (NEW.accepted_count = OLD.accepted_count + 1 844 AND NEW.rejected_count = OLD.rejected_count 845 AND NEW.lifetime_accepted_count = OLD.lifetime_accepted_count + 1 846 AND NEW.lifetime_rejected_count = OLD.lifetime_rejected_count) 847 OR (NEW.accepted_count = OLD.accepted_count 848 AND NEW.rejected_count = OLD.rejected_count + 1 849 AND NEW.lifetime_accepted_count = OLD.lifetime_accepted_count 850 AND NEW.lifetime_rejected_count = OLD.lifetime_rejected_count + 1) 851 )) 852 OR (NEW.window_started_at_unix_ms > OLD.window_ends_at_unix_ms 853 AND NEW.window_ends_at_unix_ms > NEW.window_started_at_unix_ms 854 AND ((NEW.accepted_count = 1 AND NEW.rejected_count = 0) 855 OR (NEW.accepted_count = 0 AND NEW.rejected_count = 1)) 856 AND NEW.lifetime_accepted_count = OLD.lifetime_accepted_count + NEW.accepted_count 857 AND NEW.lifetime_rejected_count = OLD.lifetime_rejected_count + NEW.rejected_count) 858 ) 859 BEGIN 860 SELECT RAISE(ABORT, 'rate-window transition is invalid'); 861 END"# 862 }; 863 } 864 865 const CREATE_MYC_AUDIT_STATE_TABLE_SQL: &str = myc_audit_state_table_sql!(); 866 const CREATE_OPERATION_AUDIT_TABLE_SQL: &str = operation_audit_table_sql!(); 867 const CREATE_NIP46_REQUEST_AUDIT_TABLE_SQL: &str = nip46_request_audit_table_sql!(); 868 const CREATE_CONNECTION_RATE_WINDOWS_TABLE_SQL: &str = connection_rate_windows_table_sql!(); 869 const CREATE_MYC_AUDIT_STATE_GUARD_UPDATE_SQL: &str = myc_audit_state_guard_update_sql!(); 870 const CREATE_MYC_AUDIT_STATE_NO_DELETE_SQL: &str = myc_audit_state_no_delete_sql!(); 871 const CREATE_OPERATION_AUDIT_NO_UPDATE_SQL: &str = operation_audit_no_update_sql!(); 872 const CREATE_NIP46_REQUEST_AUDIT_NO_UPDATE_SQL: &str = nip46_request_audit_no_update_sql!(); 873 const CREATE_CONNECTION_RATE_WINDOWS_GUARD_UPDATE_SQL: &str = 874 connection_rate_windows_guard_update_sql!(); 875 876 const CREATE_GOVERNANCE_STATE_MIGRATION_SQL: &str = concat!( 877 "DROP TRIGGER myc_state_metadata_no_update;\n", 878 "UPDATE myc_state_metadata SET state_contract_version = CASE ", 879 "WHEN state_contract_version = 4 THEN 5 ELSE 0 END WHERE singleton = 1;\n", 880 myc_state_metadata_no_update_sql!(), 881 ";\n", 882 myc_audit_state_table_sql!(), 883 ";\n", 884 "INSERT INTO myc_audit_state (singleton, next_sequence) VALUES (1, 0);\n", 885 operation_audit_table_sql!(), 886 ";\n", 887 nip46_request_audit_table_sql!(), 888 ";\n", 889 connection_rate_windows_table_sql!(), 890 ";\n", 891 myc_audit_state_guard_update_sql!(), 892 ";\n", 893 myc_audit_state_no_delete_sql!(), 894 ";\n", 895 operation_audit_no_update_sql!(), 896 ";\n", 897 nip46_request_audit_no_update_sql!(), 898 ";\n", 899 connection_rate_windows_guard_update_sql!(), 900 ); 901 902 macro_rules! publication_outbox_table_sql { 903 () => { 904 r#"CREATE TABLE publication_outbox ( 905 job_id BLOB NOT NULL PRIMARY KEY CHECK (length(job_id) = 32), 906 signer_operation_id BLOB NOT NULL UNIQUE CHECK (length(signer_operation_id) = 32) 907 REFERENCES nip46_requests(operation_id), 908 artifact_sha256 BLOB NOT NULL CHECK (length(artifact_sha256) = 32), 909 policy_mode TEXT NOT NULL CHECK (policy_mode IN ( 910 'at_least_one_required', 'all_required', 'required_quorum' 911 )), 912 required_acknowledgements INTEGER NOT NULL 913 CHECK (required_acknowledgements BETWEEN 1 AND 32), 914 max_attempts INTEGER NOT NULL CHECK (max_attempts BETWEEN 1 AND 32), 915 initial_backoff_ms INTEGER NOT NULL CHECK (initial_backoff_ms BETWEEN 1 AND 30000), 916 maximum_backoff_ms INTEGER NOT NULL CHECK (maximum_backoff_ms BETWEEN initial_backoff_ms AND 300000), 917 attempt_deadline_ms INTEGER NOT NULL CHECK (attempt_deadline_ms BETWEEN 1 AND 30000), 918 status TEXT NOT NULL CHECK (status IN ('pending', 'active', 'delivered', 'failed', 'unknown')), 919 created_at_unix_ms INTEGER NOT NULL 920 CHECK (created_at_unix_ms BETWEEN 1 AND 9223372036854775807), 921 updated_at_unix_ms INTEGER NOT NULL 922 CHECK (updated_at_unix_ms BETWEEN created_at_unix_ms AND 9223372036854775807), 923 finalized_at_unix_ms INTEGER 924 CHECK (finalized_at_unix_ms IS NULL OR 925 finalized_at_unix_ms BETWEEN created_at_unix_ms AND 9223372036854775807), 926 CHECK ((status IN ('pending', 'active') AND finalized_at_unix_ms IS NULL) 927 OR (status IN ('delivered', 'failed', 'unknown') AND finalized_at_unix_ms IS NOT NULL)) 928 ) STRICT"# 929 }; 930 } 931 932 macro_rules! publication_targets_table_sql { 933 () => { 934 r#"CREATE TABLE publication_targets ( 935 job_id BLOB NOT NULL CHECK (length(job_id) = 32) 936 REFERENCES publication_outbox(job_id), 937 target_index INTEGER NOT NULL CHECK (target_index BETWEEN 0 AND 31), 938 relay_id TEXT NOT NULL CHECK (length(CAST(relay_id AS BLOB)) BETWEEN 1 AND 64), 939 required INTEGER NOT NULL CHECK (required IN (0, 1)), 940 attempt_count INTEGER NOT NULL CHECK (attempt_count BETWEEN 0 AND 32), 941 status TEXT NOT NULL CHECK (status IN ( 942 'pending', 'leased', 'submitted', 'delivered', 'retryable', 'unknown', 'exhausted' 943 )), 944 active_attempt_id BLOB CHECK (active_attempt_id IS NULL OR length(active_attempt_id) = 32), 945 next_attempt_at_unix_ms INTEGER 946 CHECK (next_attempt_at_unix_ms IS NULL OR 947 next_attempt_at_unix_ms BETWEEN 1 AND 9223372036854775807), 948 updated_at_unix_ms INTEGER NOT NULL 949 CHECK (updated_at_unix_ms BETWEEN 1 AND 9223372036854775807), 950 CHECK ((status IN ('leased', 'submitted') AND active_attempt_id IS NOT NULL 951 AND next_attempt_at_unix_ms IS NULL) 952 OR (status = 'retryable' AND active_attempt_id IS NULL 953 AND next_attempt_at_unix_ms IS NOT NULL) 954 OR (status = 'unknown' AND active_attempt_id IS NULL) 955 OR (status IN ('pending', 'delivered', 'exhausted') AND active_attempt_id IS NULL 956 AND next_attempt_at_unix_ms IS NULL)), 957 PRIMARY KEY (job_id, target_index), 958 UNIQUE (job_id, relay_id) 959 ) STRICT"# 960 }; 961 } 962 963 macro_rules! publication_attempts_table_sql { 964 () => { 965 r#"CREATE TABLE publication_attempts ( 966 attempt_id BLOB NOT NULL PRIMARY KEY CHECK (length(attempt_id) = 32), 967 job_id BLOB NOT NULL CHECK (length(job_id) = 32), 968 target_index INTEGER NOT NULL CHECK (target_index BETWEEN 0 AND 31), 969 attempt_number INTEGER NOT NULL CHECK (attempt_number BETWEEN 1 AND 32), 970 attempt_nonce BLOB NOT NULL CHECK (length(attempt_nonce) = 32), 971 status TEXT NOT NULL CHECK (status IN ('leased', 'submitted', 'delivered', 'failed', 'unknown')), 972 leased_at_unix_ms INTEGER NOT NULL 973 CHECK (leased_at_unix_ms BETWEEN 1 AND 9223372036854775807), 974 lease_expires_at_unix_ms INTEGER NOT NULL 975 CHECK (lease_expires_at_unix_ms BETWEEN leased_at_unix_ms + 1 AND 9223372036854775807), 976 submitted_at_unix_ms INTEGER 977 CHECK (submitted_at_unix_ms IS NULL OR 978 submitted_at_unix_ms BETWEEN leased_at_unix_ms AND lease_expires_at_unix_ms), 979 resolved_at_unix_ms INTEGER 980 CHECK (resolved_at_unix_ms IS NULL OR 981 resolved_at_unix_ms BETWEEN leased_at_unix_ms AND 9223372036854775807), 982 reason_code TEXT CHECK (reason_code IS NULL OR reason_code IN ( 983 'accepted', 'relay_rejected', 'transport_failed', 984 'lease_expired_before_submit', 'acknowledgement_lost' 985 )), 986 CHECK ((status = 'leased' AND submitted_at_unix_ms IS NULL 987 AND resolved_at_unix_ms IS NULL AND reason_code IS NULL) 988 OR (status = 'submitted' AND submitted_at_unix_ms IS NOT NULL 989 AND resolved_at_unix_ms IS NULL AND reason_code IS NULL) 990 OR (status = 'delivered' AND submitted_at_unix_ms IS NOT NULL 991 AND resolved_at_unix_ms IS NOT NULL AND reason_code = 'accepted') 992 OR (status = 'failed' AND resolved_at_unix_ms IS NOT NULL 993 AND reason_code IN ('relay_rejected', 'transport_failed', 'lease_expired_before_submit')) 994 OR (status = 'unknown' AND submitted_at_unix_ms IS NOT NULL 995 AND resolved_at_unix_ms IS NOT NULL AND reason_code = 'acknowledgement_lost')), 996 FOREIGN KEY (job_id, target_index) 997 REFERENCES publication_targets(job_id, target_index), 998 UNIQUE (job_id, target_index, attempt_number), 999 UNIQUE (job_id, target_index, attempt_nonce) 1000 ) STRICT"# 1001 }; 1002 } 1003 1004 macro_rules! publication_outbox_guard_update_sql { 1005 () => { 1006 r#"CREATE TRIGGER publication_outbox_guard_update 1007 BEFORE UPDATE ON publication_outbox 1008 WHEN NEW.job_id != OLD.job_id 1009 OR NEW.signer_operation_id != OLD.signer_operation_id 1010 OR NEW.artifact_sha256 != OLD.artifact_sha256 1011 OR NEW.policy_mode != OLD.policy_mode 1012 OR NEW.required_acknowledgements != OLD.required_acknowledgements 1013 OR NEW.max_attempts != OLD.max_attempts 1014 OR NEW.initial_backoff_ms != OLD.initial_backoff_ms 1015 OR NEW.maximum_backoff_ms != OLD.maximum_backoff_ms 1016 OR NEW.attempt_deadline_ms != OLD.attempt_deadline_ms 1017 OR NEW.created_at_unix_ms != OLD.created_at_unix_ms 1018 OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms 1019 OR NOT ((OLD.status = 'pending' AND NEW.status = 'active' 1020 AND NEW.finalized_at_unix_ms IS NULL) 1021 OR (OLD.status IN ('pending', 'active') AND NEW.status IN ('delivered', 'failed', 'unknown') 1022 AND NEW.finalized_at_unix_ms IS NOT NULL)) 1023 BEGIN 1024 SELECT RAISE(ABORT, 'publication job transition is invalid'); 1025 END"# 1026 }; 1027 } 1028 1029 macro_rules! publication_targets_guard_update_sql { 1030 () => { 1031 r#"CREATE TRIGGER publication_targets_guard_update 1032 BEFORE UPDATE ON publication_targets 1033 WHEN NEW.job_id != OLD.job_id 1034 OR NEW.target_index != OLD.target_index 1035 OR NEW.relay_id != OLD.relay_id 1036 OR NEW.required != OLD.required 1037 OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms 1038 OR NOT ((OLD.status IN ('pending', 'retryable', 'unknown') AND NEW.status = 'leased' 1039 AND NEW.attempt_count = OLD.attempt_count + 1 1040 AND NEW.active_attempt_id IS NOT NULL AND NEW.next_attempt_at_unix_ms IS NULL) 1041 OR (OLD.status = 'leased' AND NEW.status = 'submitted' 1042 AND NEW.attempt_count = OLD.attempt_count 1043 AND NEW.active_attempt_id = OLD.active_attempt_id 1044 AND NEW.next_attempt_at_unix_ms IS NULL) 1045 OR (OLD.status IN ('leased', 'submitted') 1046 AND NEW.status IN ('delivered', 'retryable', 'unknown', 'exhausted') 1047 AND NEW.attempt_count = OLD.attempt_count 1048 AND NEW.active_attempt_id IS NULL 1049 AND ((NEW.status = 'retryable' 1050 AND NEW.next_attempt_at_unix_ms IS NOT NULL) 1051 OR NEW.status = 'unknown' 1052 OR (NEW.status IN ('delivered', 'exhausted') 1053 AND NEW.next_attempt_at_unix_ms IS NULL)))) 1054 BEGIN 1055 SELECT RAISE(ABORT, 'publication target transition is invalid'); 1056 END"# 1057 }; 1058 } 1059 1060 macro_rules! publication_attempts_guard_update_sql { 1061 () => { 1062 r#"CREATE TRIGGER publication_attempts_guard_update 1063 BEFORE UPDATE ON publication_attempts 1064 WHEN NEW.attempt_id != OLD.attempt_id 1065 OR NEW.job_id != OLD.job_id 1066 OR NEW.target_index != OLD.target_index 1067 OR NEW.attempt_number != OLD.attempt_number 1068 OR NEW.attempt_nonce != OLD.attempt_nonce 1069 OR NEW.leased_at_unix_ms != OLD.leased_at_unix_ms 1070 OR NEW.lease_expires_at_unix_ms != OLD.lease_expires_at_unix_ms 1071 OR NOT ((OLD.status = 'leased' AND NEW.status = 'submitted' 1072 AND NEW.submitted_at_unix_ms IS NOT NULL 1073 AND NEW.resolved_at_unix_ms IS NULL AND NEW.reason_code IS NULL) 1074 OR (OLD.status = 'leased' AND NEW.status = 'failed' 1075 AND NEW.submitted_at_unix_ms IS NULL 1076 AND NEW.resolved_at_unix_ms IS NOT NULL 1077 AND NEW.reason_code IN ('transport_failed', 'lease_expired_before_submit')) 1078 OR (OLD.status = 'submitted' AND NEW.status IN ('delivered', 'failed', 'unknown') 1079 AND NEW.submitted_at_unix_ms = OLD.submitted_at_unix_ms 1080 AND NEW.resolved_at_unix_ms IS NOT NULL 1081 AND ((NEW.status = 'delivered' AND NEW.reason_code = 'accepted') 1082 OR (NEW.status = 'failed' 1083 AND NEW.reason_code IN ('relay_rejected', 'transport_failed')) 1084 OR (NEW.status = 'unknown' 1085 AND NEW.reason_code = 'acknowledgement_lost')))) 1086 BEGIN 1087 SELECT RAISE(ABORT, 'publication attempt transition is invalid'); 1088 END"# 1089 }; 1090 } 1091 1092 macro_rules! publication_outbox_no_delete_sql { 1093 () => { 1094 r#"CREATE TRIGGER publication_outbox_no_delete 1095 BEFORE DELETE ON publication_outbox 1096 BEGIN 1097 SELECT RAISE(ABORT, 'publication jobs are immutable'); 1098 END"# 1099 }; 1100 } 1101 1102 macro_rules! publication_targets_no_delete_sql { 1103 () => { 1104 r#"CREATE TRIGGER publication_targets_no_delete 1105 BEFORE DELETE ON publication_targets 1106 BEGIN 1107 SELECT RAISE(ABORT, 'publication targets are immutable'); 1108 END"# 1109 }; 1110 } 1111 1112 macro_rules! publication_attempts_no_delete_sql { 1113 () => { 1114 r#"CREATE TRIGGER publication_attempts_no_delete 1115 BEFORE DELETE ON publication_attempts 1116 BEGIN 1117 SELECT RAISE(ABORT, 'publication attempts are immutable'); 1118 END"# 1119 }; 1120 } 1121 1122 const CREATE_PUBLICATION_OUTBOX_TABLE_SQL: &str = publication_outbox_table_sql!(); 1123 const CREATE_PUBLICATION_TARGETS_TABLE_SQL: &str = publication_targets_table_sql!(); 1124 const CREATE_PUBLICATION_ATTEMPTS_TABLE_SQL: &str = publication_attempts_table_sql!(); 1125 const CREATE_PUBLICATION_OUTBOX_GUARD_UPDATE_SQL: &str = publication_outbox_guard_update_sql!(); 1126 const CREATE_PUBLICATION_TARGETS_GUARD_UPDATE_SQL: &str = publication_targets_guard_update_sql!(); 1127 const CREATE_PUBLICATION_ATTEMPTS_GUARD_UPDATE_SQL: &str = publication_attempts_guard_update_sql!(); 1128 const CREATE_PUBLICATION_OUTBOX_NO_DELETE_SQL: &str = publication_outbox_no_delete_sql!(); 1129 const CREATE_PUBLICATION_TARGETS_NO_DELETE_SQL: &str = publication_targets_no_delete_sql!(); 1130 const CREATE_PUBLICATION_ATTEMPTS_NO_DELETE_SQL: &str = publication_attempts_no_delete_sql!(); 1131 1132 const CREATE_DELIVERY_STATE_MIGRATION_SQL: &str = concat!( 1133 "DROP TRIGGER myc_state_metadata_no_update;\n", 1134 "UPDATE myc_state_metadata SET state_contract_version = CASE ", 1135 "WHEN state_contract_version = 5 THEN 6 ELSE 0 END WHERE singleton = 1;\n", 1136 myc_state_metadata_no_update_sql!(), 1137 ";\n", 1138 publication_outbox_table_sql!(), 1139 ";\n", 1140 publication_targets_table_sql!(), 1141 ";\n", 1142 publication_attempts_table_sql!(), 1143 ";\n", 1144 publication_outbox_guard_update_sql!(), 1145 ";\n", 1146 publication_targets_guard_update_sql!(), 1147 ";\n", 1148 publication_attempts_guard_update_sql!(), 1149 ";\n", 1150 publication_outbox_no_delete_sql!(), 1151 ";\n", 1152 publication_targets_no_delete_sql!(), 1153 ";\n", 1154 publication_attempts_no_delete_sql!(), 1155 ); 1156 1157 macro_rules! delivery_jobs_table_sql { 1158 () => { 1159 r#"CREATE TABLE delivery_jobs ( 1160 job_id BLOB NOT NULL PRIMARY KEY CHECK (length(job_id) = 32), 1161 source_kind TEXT NOT NULL CHECK (source_kind IN ('signer_response', 'discovery_handler')), 1162 source_id BLOB NOT NULL CHECK (length(source_id) = 32), 1163 artifact_sha256 BLOB NOT NULL CHECK (length(artifact_sha256) = 32), 1164 policy_mode TEXT NOT NULL CHECK (policy_mode IN ( 1165 'at_least_one_required', 'all_required', 'required_quorum' 1166 )), 1167 required_acknowledgements INTEGER NOT NULL 1168 CHECK (required_acknowledgements BETWEEN 1 AND 32), 1169 max_attempts INTEGER NOT NULL CHECK (max_attempts BETWEEN 1 AND 32), 1170 initial_backoff_ms INTEGER NOT NULL CHECK (initial_backoff_ms BETWEEN 1 AND 30000), 1171 maximum_backoff_ms INTEGER NOT NULL CHECK (maximum_backoff_ms BETWEEN initial_backoff_ms AND 300000), 1172 attempt_deadline_ms INTEGER NOT NULL CHECK (attempt_deadline_ms BETWEEN 1 AND 30000), 1173 status TEXT NOT NULL CHECK (status IN ('pending', 'active', 'delivered', 'failed', 'unknown')), 1174 created_at_unix_ms INTEGER NOT NULL 1175 CHECK (created_at_unix_ms BETWEEN 1 AND 9223372036854775807), 1176 updated_at_unix_ms INTEGER NOT NULL 1177 CHECK (updated_at_unix_ms BETWEEN created_at_unix_ms AND 9223372036854775807), 1178 finalized_at_unix_ms INTEGER 1179 CHECK (finalized_at_unix_ms IS NULL OR 1180 finalized_at_unix_ms BETWEEN created_at_unix_ms AND 9223372036854775807), 1181 UNIQUE (source_kind, source_id), 1182 CHECK ((status IN ('pending', 'active') AND finalized_at_unix_ms IS NULL) 1183 OR (status IN ('delivered', 'failed', 'unknown') AND finalized_at_unix_ms IS NOT NULL)) 1184 ) STRICT"# 1185 }; 1186 } 1187 1188 macro_rules! delivery_targets_table_sql { 1189 () => { 1190 r#"CREATE TABLE delivery_targets ( 1191 job_id BLOB NOT NULL CHECK (length(job_id) = 32) 1192 REFERENCES delivery_jobs(job_id), 1193 target_index INTEGER NOT NULL CHECK (target_index BETWEEN 0 AND 31), 1194 relay_id TEXT NOT NULL CHECK (length(CAST(relay_id AS BLOB)) BETWEEN 1 AND 64), 1195 required INTEGER NOT NULL CHECK (required IN (0, 1)), 1196 attempt_count INTEGER NOT NULL CHECK (attempt_count BETWEEN 0 AND 32), 1197 status TEXT NOT NULL CHECK (status IN ( 1198 'pending', 'leased', 'submitted', 'delivered', 'retryable', 'unknown', 'exhausted' 1199 )), 1200 active_attempt_id BLOB CHECK (active_attempt_id IS NULL OR length(active_attempt_id) = 32), 1201 next_attempt_at_unix_ms INTEGER 1202 CHECK (next_attempt_at_unix_ms IS NULL OR 1203 next_attempt_at_unix_ms BETWEEN 1 AND 9223372036854775807), 1204 updated_at_unix_ms INTEGER NOT NULL 1205 CHECK (updated_at_unix_ms BETWEEN 1 AND 9223372036854775807), 1206 CHECK ((status IN ('leased', 'submitted') AND active_attempt_id IS NOT NULL 1207 AND next_attempt_at_unix_ms IS NULL) 1208 OR (status = 'retryable' AND active_attempt_id IS NULL 1209 AND next_attempt_at_unix_ms IS NOT NULL) 1210 OR (status = 'unknown' AND active_attempt_id IS NULL) 1211 OR (status IN ('pending', 'delivered', 'exhausted') AND active_attempt_id IS NULL 1212 AND next_attempt_at_unix_ms IS NULL)), 1213 PRIMARY KEY (job_id, target_index), 1214 UNIQUE (job_id, relay_id) 1215 ) STRICT"# 1216 }; 1217 } 1218 1219 macro_rules! delivery_attempts_table_sql { 1220 () => { 1221 r#"CREATE TABLE delivery_attempts ( 1222 attempt_id BLOB NOT NULL PRIMARY KEY CHECK (length(attempt_id) = 32), 1223 job_id BLOB NOT NULL CHECK (length(job_id) = 32), 1224 target_index INTEGER NOT NULL CHECK (target_index BETWEEN 0 AND 31), 1225 attempt_number INTEGER NOT NULL CHECK (attempt_number BETWEEN 1 AND 32), 1226 attempt_nonce BLOB NOT NULL CHECK (length(attempt_nonce) = 32), 1227 status TEXT NOT NULL CHECK (status IN ('leased', 'submitted', 'delivered', 'failed', 'unknown')), 1228 leased_at_unix_ms INTEGER NOT NULL 1229 CHECK (leased_at_unix_ms BETWEEN 1 AND 9223372036854775807), 1230 lease_expires_at_unix_ms INTEGER NOT NULL 1231 CHECK (lease_expires_at_unix_ms BETWEEN leased_at_unix_ms + 1 AND 9223372036854775807), 1232 submitted_at_unix_ms INTEGER 1233 CHECK (submitted_at_unix_ms IS NULL OR 1234 submitted_at_unix_ms BETWEEN leased_at_unix_ms AND lease_expires_at_unix_ms), 1235 resolved_at_unix_ms INTEGER 1236 CHECK (resolved_at_unix_ms IS NULL OR 1237 resolved_at_unix_ms BETWEEN leased_at_unix_ms AND 9223372036854775807), 1238 reason_code TEXT CHECK (reason_code IS NULL OR reason_code IN ( 1239 'accepted', 'relay_rejected', 'transport_failed', 1240 'lease_expired_before_submit', 'acknowledgement_lost' 1241 )), 1242 CHECK ((status = 'leased' AND submitted_at_unix_ms IS NULL 1243 AND resolved_at_unix_ms IS NULL AND reason_code IS NULL) 1244 OR (status = 'submitted' AND submitted_at_unix_ms IS NOT NULL 1245 AND resolved_at_unix_ms IS NULL AND reason_code IS NULL) 1246 OR (status = 'delivered' AND submitted_at_unix_ms IS NOT NULL 1247 AND resolved_at_unix_ms IS NOT NULL AND reason_code = 'accepted') 1248 OR (status = 'failed' AND resolved_at_unix_ms IS NOT NULL 1249 AND reason_code IN ('relay_rejected', 'transport_failed', 'lease_expired_before_submit')) 1250 OR (status = 'unknown' AND submitted_at_unix_ms IS NOT NULL 1251 AND resolved_at_unix_ms IS NOT NULL AND reason_code = 'acknowledgement_lost')), 1252 FOREIGN KEY (job_id, target_index) 1253 REFERENCES delivery_targets(job_id, target_index), 1254 UNIQUE (job_id, target_index, attempt_number), 1255 UNIQUE (job_id, target_index, attempt_nonce) 1256 ) STRICT"# 1257 }; 1258 } 1259 1260 macro_rules! delivery_jobs_guard_update_sql { 1261 () => { 1262 r#"CREATE TRIGGER delivery_jobs_guard_update 1263 BEFORE UPDATE ON delivery_jobs 1264 WHEN NEW.job_id != OLD.job_id 1265 OR NEW.source_kind != OLD.source_kind 1266 OR NEW.source_id != OLD.source_id 1267 OR NEW.artifact_sha256 != OLD.artifact_sha256 1268 OR NEW.policy_mode != OLD.policy_mode 1269 OR NEW.required_acknowledgements != OLD.required_acknowledgements 1270 OR NEW.max_attempts != OLD.max_attempts 1271 OR NEW.initial_backoff_ms != OLD.initial_backoff_ms 1272 OR NEW.maximum_backoff_ms != OLD.maximum_backoff_ms 1273 OR NEW.attempt_deadline_ms != OLD.attempt_deadline_ms 1274 OR NEW.created_at_unix_ms != OLD.created_at_unix_ms 1275 OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms 1276 OR NOT ((OLD.status = 'pending' AND NEW.status = 'active' 1277 AND NEW.finalized_at_unix_ms IS NULL) 1278 OR (OLD.status IN ('pending', 'active') AND NEW.status IN ('delivered', 'failed', 'unknown') 1279 AND NEW.finalized_at_unix_ms IS NOT NULL)) 1280 BEGIN 1281 SELECT RAISE(ABORT, 'publication job transition is invalid'); 1282 END"# 1283 }; 1284 } 1285 1286 macro_rules! delivery_jobs_guard_insert_sql { 1287 () => { 1288 r#"CREATE TRIGGER delivery_jobs_guard_insert 1289 BEFORE INSERT ON delivery_jobs 1290 WHEN (NEW.source_kind = 'signer_response' 1291 AND NOT EXISTS ( 1292 SELECT 1 FROM nip46_requests WHERE operation_id = NEW.source_id 1293 )) 1294 OR (NEW.source_kind = 'discovery_handler' 1295 AND NOT EXISTS ( 1296 SELECT 1 FROM discovery_desired_state WHERE generation_id = NEW.source_id 1297 )) 1298 BEGIN 1299 SELECT RAISE(ABORT, 'delivery job source is unknown'); 1300 END"# 1301 }; 1302 } 1303 1304 macro_rules! delivery_targets_guard_update_sql { 1305 () => { 1306 r#"CREATE TRIGGER delivery_targets_guard_update 1307 BEFORE UPDATE ON delivery_targets 1308 WHEN NEW.job_id != OLD.job_id 1309 OR NEW.target_index != OLD.target_index 1310 OR NEW.relay_id != OLD.relay_id 1311 OR NEW.required != OLD.required 1312 OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms 1313 OR NOT ((OLD.status IN ('pending', 'retryable', 'unknown') AND NEW.status = 'leased' 1314 AND NEW.attempt_count = OLD.attempt_count + 1 1315 AND NEW.active_attempt_id IS NOT NULL AND NEW.next_attempt_at_unix_ms IS NULL) 1316 OR (OLD.status = 'leased' AND NEW.status = 'submitted' 1317 AND NEW.attempt_count = OLD.attempt_count 1318 AND NEW.active_attempt_id = OLD.active_attempt_id 1319 AND NEW.next_attempt_at_unix_ms IS NULL) 1320 OR (OLD.status IN ('leased', 'submitted') 1321 AND NEW.status IN ('delivered', 'retryable', 'unknown', 'exhausted') 1322 AND NEW.attempt_count = OLD.attempt_count 1323 AND NEW.active_attempt_id IS NULL 1324 AND ((NEW.status = 'retryable' 1325 AND NEW.next_attempt_at_unix_ms IS NOT NULL) 1326 OR NEW.status = 'unknown' 1327 OR (NEW.status IN ('delivered', 'exhausted') 1328 AND NEW.next_attempt_at_unix_ms IS NULL)))) 1329 BEGIN 1330 SELECT RAISE(ABORT, 'publication target transition is invalid'); 1331 END"# 1332 }; 1333 } 1334 1335 macro_rules! delivery_attempts_guard_update_sql { 1336 () => { 1337 r#"CREATE TRIGGER delivery_attempts_guard_update 1338 BEFORE UPDATE ON delivery_attempts 1339 WHEN NEW.attempt_id != OLD.attempt_id 1340 OR NEW.job_id != OLD.job_id 1341 OR NEW.target_index != OLD.target_index 1342 OR NEW.attempt_number != OLD.attempt_number 1343 OR NEW.attempt_nonce != OLD.attempt_nonce 1344 OR NEW.leased_at_unix_ms != OLD.leased_at_unix_ms 1345 OR NEW.lease_expires_at_unix_ms != OLD.lease_expires_at_unix_ms 1346 OR NOT ((OLD.status = 'leased' AND NEW.status = 'submitted' 1347 AND NEW.submitted_at_unix_ms IS NOT NULL 1348 AND NEW.resolved_at_unix_ms IS NULL AND NEW.reason_code IS NULL) 1349 OR (OLD.status = 'leased' AND NEW.status = 'failed' 1350 AND NEW.submitted_at_unix_ms IS NULL 1351 AND NEW.resolved_at_unix_ms IS NOT NULL 1352 AND NEW.reason_code IN ('transport_failed', 'lease_expired_before_submit')) 1353 OR (OLD.status = 'submitted' AND NEW.status IN ('delivered', 'failed', 'unknown') 1354 AND NEW.submitted_at_unix_ms = OLD.submitted_at_unix_ms 1355 AND NEW.resolved_at_unix_ms IS NOT NULL 1356 AND ((NEW.status = 'delivered' AND NEW.reason_code = 'accepted') 1357 OR (NEW.status = 'failed' 1358 AND NEW.reason_code IN ('relay_rejected', 'transport_failed')) 1359 OR (NEW.status = 'unknown' 1360 AND NEW.reason_code = 'acknowledgement_lost')))) 1361 BEGIN 1362 SELECT RAISE(ABORT, 'publication attempt transition is invalid'); 1363 END"# 1364 }; 1365 } 1366 1367 macro_rules! discovery_desired_state_table_sql { 1368 () => { 1369 r#"CREATE TABLE discovery_desired_state ( 1370 generation_id BLOB NOT NULL PRIMARY KEY CHECK (length(generation_id) = 32), 1371 normalized_config_sha256 BLOB NOT NULL CHECK (length(normalized_config_sha256) = 32), 1372 desired_sha256 BLOB NOT NULL UNIQUE CHECK (length(desired_sha256) = 32), 1373 created_at_unix_ms INTEGER NOT NULL 1374 CHECK (created_at_unix_ms BETWEEN 1 AND 9223372036854775807) 1375 ) STRICT"# 1376 }; 1377 } 1378 1379 macro_rules! discovery_documents_table_sql { 1380 () => { 1381 r#"CREATE TABLE discovery_documents ( 1382 generation_id BLOB NOT NULL PRIMARY KEY CHECK (length(generation_id) = 32) 1383 REFERENCES discovery_desired_state(generation_id), 1384 event_id BLOB NOT NULL UNIQUE CHECK (length(event_id) = 32), 1385 event_sha256 BLOB NOT NULL UNIQUE CHECK (length(event_sha256) = 32), 1386 event_bytes BLOB NOT NULL CHECK (length(event_bytes) BETWEEN 1 AND 524288), 1387 nip05_projection_sha256 BLOB NOT NULL CHECK (length(nip05_projection_sha256) = 32), 1388 nip05_projection_bytes BLOB NOT NULL 1389 CHECK (length(nip05_projection_bytes) BETWEEN 1 AND 524288) 1390 ) STRICT"# 1391 }; 1392 } 1393 1394 macro_rules! discovery_publication_state_table_sql { 1395 () => { 1396 r#"CREATE TABLE discovery_publication_state ( 1397 singleton INTEGER NOT NULL PRIMARY KEY CHECK (singleton = 1), 1398 desired_generation_id BLOB NOT NULL UNIQUE CHECK (length(desired_generation_id) = 32) 1399 REFERENCES discovery_desired_state(generation_id), 1400 desired_job_id BLOB NOT NULL UNIQUE CHECK (length(desired_job_id) = 32) 1401 REFERENCES delivery_jobs(job_id), 1402 current_generation_id BLOB UNIQUE 1403 CHECK (current_generation_id IS NULL OR length(current_generation_id) = 32) 1404 REFERENCES discovery_desired_state(generation_id), 1405 current_job_id BLOB UNIQUE 1406 CHECK (current_job_id IS NULL OR length(current_job_id) = 32) 1407 REFERENCES delivery_jobs(job_id), 1408 updated_at_unix_ms INTEGER NOT NULL 1409 CHECK (updated_at_unix_ms BETWEEN 1 AND 9223372036854775807), 1410 CHECK ((current_generation_id IS NULL AND current_job_id IS NULL) 1411 OR (current_generation_id IS NOT NULL AND current_job_id IS NOT NULL)) 1412 ) STRICT"# 1413 }; 1414 } 1415 1416 macro_rules! immutable_no_update_sql { 1417 ($trigger:literal, $table:literal, $message:literal) => { 1418 concat!( 1419 "CREATE TRIGGER ", 1420 $trigger, 1421 " BEFORE UPDATE ON ", 1422 $table, 1423 " BEGIN SELECT RAISE(ABORT, '", 1424 $message, 1425 "'); END" 1426 ) 1427 }; 1428 } 1429 1430 macro_rules! immutable_no_delete_sql { 1431 ($trigger:literal, $table:literal, $message:literal) => { 1432 concat!( 1433 "CREATE TRIGGER ", 1434 $trigger, 1435 " BEFORE DELETE ON ", 1436 $table, 1437 " BEGIN SELECT RAISE(ABORT, '", 1438 $message, 1439 "'); END" 1440 ) 1441 }; 1442 } 1443 1444 macro_rules! discovery_publication_state_guard_update_sql { 1445 () => { 1446 r#"CREATE TRIGGER discovery_publication_state_guard_update 1447 BEFORE UPDATE ON discovery_publication_state 1448 WHEN NEW.singleton != OLD.singleton 1449 OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms 1450 OR NOT ( 1451 (NEW.desired_generation_id != OLD.desired_generation_id 1452 AND NEW.desired_job_id != OLD.desired_job_id 1453 AND NEW.current_generation_id IS OLD.current_generation_id 1454 AND NEW.current_job_id IS OLD.current_job_id) 1455 OR (NEW.desired_generation_id = OLD.desired_generation_id 1456 AND NEW.desired_job_id = OLD.desired_job_id 1457 AND NEW.current_generation_id = OLD.desired_generation_id 1458 AND NEW.current_job_id = OLD.desired_job_id) 1459 ) 1460 BEGIN 1461 SELECT RAISE(ABORT, 'discovery publication transition is invalid'); 1462 END"# 1463 }; 1464 } 1465 1466 const CREATE_DELIVERY_JOBS_TABLE_SQL: &str = delivery_jobs_table_sql!(); 1467 const CREATE_DELIVERY_TARGETS_TABLE_SQL: &str = delivery_targets_table_sql!(); 1468 const CREATE_DELIVERY_ATTEMPTS_TABLE_SQL: &str = delivery_attempts_table_sql!(); 1469 const CREATE_DELIVERY_JOBS_GUARD_INSERT_SQL: &str = delivery_jobs_guard_insert_sql!(); 1470 const CREATE_DELIVERY_JOBS_GUARD_UPDATE_SQL: &str = delivery_jobs_guard_update_sql!(); 1471 const CREATE_DELIVERY_TARGETS_GUARD_UPDATE_SQL: &str = delivery_targets_guard_update_sql!(); 1472 const CREATE_DELIVERY_ATTEMPTS_GUARD_UPDATE_SQL: &str = delivery_attempts_guard_update_sql!(); 1473 const CREATE_DELIVERY_JOBS_NO_DELETE_SQL: &str = immutable_no_delete_sql!( 1474 "delivery_jobs_no_delete", 1475 "delivery_jobs", 1476 "publication jobs are immutable" 1477 ); 1478 const CREATE_DELIVERY_TARGETS_NO_DELETE_SQL: &str = immutable_no_delete_sql!( 1479 "delivery_targets_no_delete", 1480 "delivery_targets", 1481 "publication targets are immutable" 1482 ); 1483 const CREATE_DELIVERY_ATTEMPTS_NO_DELETE_SQL: &str = immutable_no_delete_sql!( 1484 "delivery_attempts_no_delete", 1485 "delivery_attempts", 1486 "publication attempts are immutable" 1487 ); 1488 const CREATE_DISCOVERY_DESIRED_STATE_TABLE_SQL: &str = discovery_desired_state_table_sql!(); 1489 const CREATE_DISCOVERY_DOCUMENTS_TABLE_SQL: &str = discovery_documents_table_sql!(); 1490 const CREATE_DISCOVERY_PUBLICATION_STATE_TABLE_SQL: &str = discovery_publication_state_table_sql!(); 1491 const CREATE_DISCOVERY_DESIRED_STATE_NO_UPDATE_SQL: &str = immutable_no_update_sql!( 1492 "discovery_desired_state_no_update", 1493 "discovery_desired_state", 1494 "discovery desired state is immutable" 1495 ); 1496 const CREATE_DISCOVERY_DESIRED_STATE_NO_DELETE_SQL: &str = immutable_no_delete_sql!( 1497 "discovery_desired_state_no_delete", 1498 "discovery_desired_state", 1499 "discovery desired state is immutable" 1500 ); 1501 const CREATE_DISCOVERY_DOCUMENTS_NO_UPDATE_SQL: &str = immutable_no_update_sql!( 1502 "discovery_documents_no_update", 1503 "discovery_documents", 1504 "discovery documents are immutable" 1505 ); 1506 const CREATE_DISCOVERY_DOCUMENTS_NO_DELETE_SQL: &str = immutable_no_delete_sql!( 1507 "discovery_documents_no_delete", 1508 "discovery_documents", 1509 "discovery documents are immutable" 1510 ); 1511 const CREATE_DISCOVERY_PUBLICATION_STATE_GUARD_UPDATE_SQL: &str = 1512 discovery_publication_state_guard_update_sql!(); 1513 const CREATE_DISCOVERY_PUBLICATION_STATE_NO_DELETE_SQL: &str = immutable_no_delete_sql!( 1514 "discovery_publication_state_no_delete", 1515 "discovery_publication_state", 1516 "discovery publication state is retained" 1517 ); 1518 1519 const CREATE_DISCOVERY_STATE_MIGRATION_SQL: &str = concat!( 1520 "DROP TRIGGER myc_state_metadata_no_update;\n", 1521 "UPDATE myc_state_metadata SET state_contract_version = CASE ", 1522 "WHEN state_contract_version = 6 THEN 7 ELSE 0 END WHERE singleton = 1;\n", 1523 myc_state_metadata_no_update_sql!(), 1524 ";\n", 1525 "DROP TRIGGER publication_attempts_no_delete;\n", 1526 "DROP TRIGGER publication_targets_no_delete;\n", 1527 "DROP TRIGGER publication_outbox_no_delete;\n", 1528 "DROP TRIGGER publication_attempts_guard_update;\n", 1529 "DROP TRIGGER publication_targets_guard_update;\n", 1530 "DROP TRIGGER publication_outbox_guard_update;\n", 1531 delivery_jobs_table_sql!(), 1532 ";\n", 1533 delivery_targets_table_sql!(), 1534 ";\n", 1535 delivery_attempts_table_sql!(), 1536 ";\n", 1537 "INSERT INTO delivery_jobs (job_id, source_kind, source_id, artifact_sha256, ", 1538 "policy_mode, required_acknowledgements, max_attempts, initial_backoff_ms, ", 1539 "maximum_backoff_ms, attempt_deadline_ms, status, created_at_unix_ms, ", 1540 "updated_at_unix_ms, finalized_at_unix_ms) SELECT job_id, 'signer_response', ", 1541 "signer_operation_id, artifact_sha256, policy_mode, required_acknowledgements, ", 1542 "max_attempts, initial_backoff_ms, maximum_backoff_ms, attempt_deadline_ms, status, ", 1543 "created_at_unix_ms, updated_at_unix_ms, finalized_at_unix_ms FROM publication_outbox;\n", 1544 "INSERT INTO delivery_targets SELECT * FROM publication_targets;\n", 1545 "INSERT INTO delivery_attempts SELECT * FROM publication_attempts;\n", 1546 "DROP TABLE publication_attempts;\n", 1547 "DROP TABLE publication_targets;\n", 1548 "DROP TABLE publication_outbox;\n", 1549 delivery_jobs_guard_update_sql!(), 1550 ";\n", 1551 delivery_targets_guard_update_sql!(), 1552 ";\n", 1553 delivery_attempts_guard_update_sql!(), 1554 ";\n", 1555 immutable_no_delete_sql!( 1556 "delivery_jobs_no_delete", 1557 "delivery_jobs", 1558 "publication jobs are immutable" 1559 ), 1560 ";\n", 1561 immutable_no_delete_sql!( 1562 "delivery_targets_no_delete", 1563 "delivery_targets", 1564 "publication targets are immutable" 1565 ), 1566 ";\n", 1567 immutable_no_delete_sql!( 1568 "delivery_attempts_no_delete", 1569 "delivery_attempts", 1570 "publication attempts are immutable" 1571 ), 1572 ";\n", 1573 discovery_desired_state_table_sql!(), 1574 ";\n", 1575 discovery_documents_table_sql!(), 1576 ";\n", 1577 discovery_publication_state_table_sql!(), 1578 ";\n", 1579 delivery_jobs_guard_insert_sql!(), 1580 ";\n", 1581 immutable_no_update_sql!( 1582 "discovery_desired_state_no_update", 1583 "discovery_desired_state", 1584 "discovery desired state is immutable" 1585 ), 1586 ";\n", 1587 immutable_no_delete_sql!( 1588 "discovery_desired_state_no_delete", 1589 "discovery_desired_state", 1590 "discovery desired state is immutable" 1591 ), 1592 ";\n", 1593 immutable_no_update_sql!( 1594 "discovery_documents_no_update", 1595 "discovery_documents", 1596 "discovery documents are immutable" 1597 ), 1598 ";\n", 1599 immutable_no_delete_sql!( 1600 "discovery_documents_no_delete", 1601 "discovery_documents", 1602 "discovery documents are immutable" 1603 ), 1604 ";\n", 1605 discovery_publication_state_guard_update_sql!(), 1606 ";\n", 1607 immutable_no_delete_sql!( 1608 "discovery_publication_state_no_delete", 1609 "discovery_publication_state", 1610 "discovery publication state is retained" 1611 ), 1612 ); 1613 1614 macro_rules! nip46_operation_commits_table_sql { 1615 () => { 1616 r#"CREATE TABLE nip46_operation_commits ( 1617 operation_id BLOB NOT NULL PRIMARY KEY CHECK (length(operation_id) = 32) 1618 REFERENCES nip46_requests(operation_id), 1619 correlation_id BLOB NOT NULL UNIQUE CHECK (length(correlation_id) = 32), 1620 method TEXT NOT NULL CHECK (method IN ( 1621 'connect', 'get_public_key', 'get_session_capability', 'sign_event', 1622 'nip04_encrypt', 'nip04_decrypt', 'nip44_encrypt', 'nip44_decrypt', 1623 'ping', 'switch_relays', 'logout' 1624 )), 1625 connection_id BLOB CHECK (connection_id IS NULL OR length(connection_id) = 32) 1626 REFERENCES connections(connection_id), 1627 session_effect TEXT NOT NULL CHECK (session_effect IN ( 1628 'none', 'connection_admitted', 'connection_revoked' 1629 )), 1630 provider_operation_id BLOB UNIQUE 1631 CHECK (provider_operation_id IS NULL OR length(provider_operation_id) = 32), 1632 provider_artifact_kind TEXT NOT NULL CHECK (provider_artifact_kind IN ( 1633 'none', 'signed_event' 1634 )), 1635 provider_artifact_sha256 BLOB 1636 CHECK (provider_artifact_sha256 IS NULL OR length(provider_artifact_sha256) = 32), 1637 provider_artifact BLOB 1638 CHECK (provider_artifact IS NULL OR length(provider_artifact) BETWEEN 1 AND 1048576), 1639 outcome TEXT NOT NULL CHECK (outcome = 'succeeded'), 1640 reason_code TEXT NOT NULL CHECK (reason_code IN ( 1641 'completed', 'connection_admitted', 'connection_denied', 'session_revoked' 1642 )), 1643 completed_at_unix_ms INTEGER NOT NULL 1644 CHECK (completed_at_unix_ms BETWEEN 1 AND 9223372036854775807), 1645 CHECK ( 1646 (method = 'connect' AND session_effect = 'connection_admitted' 1647 AND connection_id IS NOT NULL AND reason_code = 'connection_admitted') 1648 OR (method = 'connect' AND session_effect = 'none' 1649 AND connection_id IS NULL AND reason_code = 'connection_denied') 1650 OR (method = 'logout' AND session_effect = 'connection_revoked' 1651 AND connection_id IS NOT NULL AND reason_code = 'session_revoked') 1652 OR (method NOT IN ('connect', 'logout') AND session_effect = 'none' 1653 AND connection_id IS NOT NULL AND reason_code = 'completed') 1654 ), 1655 CHECK ( 1656 (method IN ('sign_event', 'nip04_encrypt', 'nip04_decrypt', 1657 'nip44_encrypt', 'nip44_decrypt') AND provider_operation_id IS NOT NULL) 1658 OR (method NOT IN ('sign_event', 'nip04_encrypt', 'nip04_decrypt', 1659 'nip44_encrypt', 'nip44_decrypt') AND provider_operation_id IS NULL) 1660 ), 1661 CHECK ( 1662 (method = 'sign_event' AND provider_artifact_kind = 'signed_event' 1663 AND provider_artifact_sha256 IS NOT NULL AND provider_artifact IS NOT NULL) 1664 OR (method != 'sign_event' AND provider_artifact_kind = 'none' 1665 AND provider_artifact_sha256 IS NULL AND provider_artifact IS NULL) 1666 ) 1667 ) STRICT"# 1668 }; 1669 } 1670 1671 macro_rules! nip46_operation_commits_no_update_sql { 1672 () => { 1673 r#"CREATE TRIGGER nip46_operation_commits_no_update 1674 BEFORE UPDATE ON nip46_operation_commits 1675 BEGIN 1676 SELECT RAISE(ABORT, 'NIP-46 operation completion is immutable'); 1677 END"# 1678 }; 1679 } 1680 1681 macro_rules! nip46_operation_commits_no_delete_sql { 1682 () => { 1683 r#"CREATE TRIGGER nip46_operation_commits_no_delete 1684 BEFORE DELETE ON nip46_operation_commits 1685 BEGIN 1686 SELECT RAISE(ABORT, 'NIP-46 operation completion is retained'); 1687 END"# 1688 }; 1689 } 1690 1691 const CREATE_NIP46_OPERATION_COMMITS_TABLE_SQL: &str = nip46_operation_commits_table_sql!(); 1692 const CREATE_NIP46_OPERATION_COMMITS_NO_UPDATE_SQL: &str = nip46_operation_commits_no_update_sql!(); 1693 const CREATE_NIP46_OPERATION_COMMITS_NO_DELETE_SQL: &str = nip46_operation_commits_no_delete_sql!(); 1694 1695 const CREATE_NIP46_OPERATION_COMPLETION_MIGRATION_SQL: &str = concat!( 1696 "DROP TRIGGER myc_state_metadata_no_update;\n", 1697 "UPDATE myc_state_metadata SET state_contract_version = CASE ", 1698 "WHEN state_contract_version = 7 THEN 8 ELSE 0 END WHERE singleton = 1;\n", 1699 myc_state_metadata_no_update_sql!(), 1700 ";\n", 1701 nip46_operation_commits_table_sql!(), 1702 ";\n", 1703 nip46_operation_commits_no_update_sql!(), 1704 ";\n", 1705 nip46_operation_commits_no_delete_sql!(), 1706 ); 1707 1708 macro_rules! nip46_signed_responses_table_sql { 1709 () => { 1710 r#"CREATE TABLE nip46_signed_responses ( 1711 operation_id BLOB NOT NULL PRIMARY KEY CHECK (length(operation_id) = 32) 1712 REFERENCES nip46_operation_commits(operation_id), 1713 response_provider_operation_id BLOB NOT NULL UNIQUE 1714 CHECK (length(response_provider_operation_id) = 32), 1715 response_event_id BLOB NOT NULL UNIQUE CHECK (length(response_event_id) = 32), 1716 response_sha256 BLOB NOT NULL CHECK (length(response_sha256) = 32), 1717 response_bytes BLOB NOT NULL 1718 CHECK (length(response_bytes) BETWEEN 1 AND 1048576), 1719 authored_at_unix_s INTEGER NOT NULL 1720 CHECK (authored_at_unix_s BETWEEN 1 AND 9223372036854775807), 1721 committed_at_unix_ms INTEGER NOT NULL 1722 CHECK (committed_at_unix_ms BETWEEN 1 AND 9223372036854775807) 1723 ) STRICT"# 1724 }; 1725 } 1726 1727 macro_rules! nip46_signed_responses_no_update_sql { 1728 () => { 1729 r#"CREATE TRIGGER nip46_signed_responses_no_update 1730 BEFORE UPDATE ON nip46_signed_responses 1731 BEGIN 1732 SELECT RAISE(ABORT, 'NIP-46 signed response is immutable'); 1733 END"# 1734 }; 1735 } 1736 1737 macro_rules! nip46_signed_responses_no_delete_sql { 1738 () => { 1739 r#"CREATE TRIGGER nip46_signed_responses_no_delete 1740 BEFORE DELETE ON nip46_signed_responses 1741 BEGIN 1742 SELECT RAISE(ABORT, 'NIP-46 signed response is retained'); 1743 END"# 1744 }; 1745 } 1746 1747 const CREATE_NIP46_SIGNED_RESPONSES_TABLE_SQL: &str = nip46_signed_responses_table_sql!(); 1748 const CREATE_NIP46_SIGNED_RESPONSES_NO_UPDATE_SQL: &str = nip46_signed_responses_no_update_sql!(); 1749 const CREATE_NIP46_SIGNED_RESPONSES_NO_DELETE_SQL: &str = nip46_signed_responses_no_delete_sql!(); 1750 1751 const CREATE_NIP46_ATOMIC_RESPONSE_MIGRATION_SQL: &str = concat!( 1752 "DROP TRIGGER myc_state_metadata_no_update;\n", 1753 "UPDATE myc_state_metadata SET state_contract_version = CASE ", 1754 "WHEN state_contract_version = 8 THEN 9 ELSE 0 END WHERE singleton = 1;\n", 1755 myc_state_metadata_no_update_sql!(), 1756 ";\n", 1757 nip46_signed_responses_table_sql!(), 1758 ";\n", 1759 nip46_signed_responses_no_update_sql!(), 1760 ";\n", 1761 nip46_signed_responses_no_delete_sql!(), 1762 ); 1763 1764 macro_rules! nip46_pending_responses_table_sql { 1765 () => { 1766 r#"CREATE TABLE nip46_pending_responses ( 1767 operation_id BLOB NOT NULL PRIMARY KEY CHECK (length(operation_id) = 32) 1768 REFERENCES nip46_requests(operation_id), 1769 connection_id BLOB NOT NULL CHECK (length(connection_id) = 32) 1770 REFERENCES connections(connection_id), 1771 response_kind TEXT NOT NULL CHECK (response_kind = 'pending_approval'), 1772 response_provider_operation_id BLOB NOT NULL UNIQUE 1773 CHECK (length(response_provider_operation_id) = 32), 1774 response_event_id BLOB NOT NULL UNIQUE CHECK (length(response_event_id) = 32), 1775 response_sha256 BLOB NOT NULL CHECK (length(response_sha256) = 32), 1776 response_bytes BLOB NOT NULL 1777 CHECK (length(response_bytes) BETWEEN 1 AND 1048576), 1778 authored_at_unix_s INTEGER NOT NULL 1779 CHECK (authored_at_unix_s BETWEEN 1 AND 9223372036854775807), 1780 committed_at_unix_ms INTEGER NOT NULL 1781 CHECK (committed_at_unix_ms BETWEEN 1 AND 9223372036854775807) 1782 ) STRICT"# 1783 }; 1784 } 1785 1786 macro_rules! nip46_pending_responses_guard_insert_sql { 1787 () => { 1788 r#"CREATE TRIGGER nip46_pending_responses_guard_insert 1789 BEFORE INSERT ON nip46_pending_responses 1790 WHEN NOT EXISTS ( 1791 SELECT 1 1792 FROM nip46_request_decisions AS decision 1793 JOIN connections AS connection 1794 ON connection.connection_id = decision.connection_id 1795 JOIN nip46_requests AS request 1796 ON request.operation_id = decision.operation_id 1797 WHERE decision.operation_id = NEW.operation_id 1798 AND decision.connection_id = NEW.connection_id 1799 AND decision.decision = 'pending_approval' 1800 AND decision.reason_code = 'explicit_approval_required' 1801 AND connection.status = 'pending' 1802 AND connection.client_public_key = request.client_public_key 1803 AND connection.policy_generation = decision.policy_generation 1804 AND connection.requested_permissions_sha256 = decision.requested_permissions_sha256 1805 AND request.method = 'connect' 1806 ) 1807 OR EXISTS ( 1808 SELECT 1 FROM nip46_signed_responses 1809 WHERE operation_id = NEW.operation_id 1810 OR response_provider_operation_id = NEW.response_provider_operation_id 1811 OR response_event_id = NEW.response_event_id 1812 ) 1813 BEGIN 1814 SELECT RAISE(ABORT, 'pending NIP-46 response binding is invalid'); 1815 END"# 1816 }; 1817 } 1818 1819 macro_rules! nip46_signed_responses_guard_pending_insert_sql { 1820 () => { 1821 r#"CREATE TRIGGER nip46_signed_responses_guard_pending_insert 1822 BEFORE INSERT ON nip46_signed_responses 1823 WHEN EXISTS ( 1824 SELECT 1 FROM nip46_pending_responses 1825 WHERE operation_id = NEW.operation_id 1826 OR response_provider_operation_id = NEW.response_provider_operation_id 1827 OR response_event_id = NEW.response_event_id 1828 ) 1829 BEGIN 1830 SELECT RAISE(ABORT, 'terminal NIP-46 response conflicts with pending authority'); 1831 END"# 1832 }; 1833 } 1834 1835 macro_rules! nip46_pending_responses_no_update_sql { 1836 () => { 1837 r#"CREATE TRIGGER nip46_pending_responses_no_update 1838 BEFORE UPDATE ON nip46_pending_responses 1839 BEGIN 1840 SELECT RAISE(ABORT, 'pending NIP-46 response is immutable'); 1841 END"# 1842 }; 1843 } 1844 1845 macro_rules! nip46_pending_responses_no_delete_sql { 1846 () => { 1847 r#"CREATE TRIGGER nip46_pending_responses_no_delete 1848 BEFORE DELETE ON nip46_pending_responses 1849 BEGIN 1850 SELECT RAISE(ABORT, 'pending NIP-46 response is retained'); 1851 END"# 1852 }; 1853 } 1854 1855 const CREATE_NIP46_PENDING_RESPONSES_TABLE_SQL: &str = nip46_pending_responses_table_sql!(); 1856 const CREATE_NIP46_PENDING_RESPONSES_GUARD_INSERT_SQL: &str = 1857 nip46_pending_responses_guard_insert_sql!(); 1858 const CREATE_NIP46_SIGNED_RESPONSES_GUARD_PENDING_INSERT_SQL: &str = 1859 nip46_signed_responses_guard_pending_insert_sql!(); 1860 const CREATE_NIP46_PENDING_RESPONSES_NO_UPDATE_SQL: &str = nip46_pending_responses_no_update_sql!(); 1861 const CREATE_NIP46_PENDING_RESPONSES_NO_DELETE_SQL: &str = nip46_pending_responses_no_delete_sql!(); 1862 1863 const CREATE_NIP46_PENDING_RESPONSE_MIGRATION_SQL: &str = concat!( 1864 nip46_pending_responses_table_sql!(), 1865 ";\n", 1866 nip46_pending_responses_guard_insert_sql!(), 1867 ";\n", 1868 nip46_signed_responses_guard_pending_insert_sql!(), 1869 ";\n", 1870 nip46_pending_responses_no_update_sql!(), 1871 ";\n", 1872 nip46_pending_responses_no_delete_sql!(), 1873 ";", 1874 ); 1875 1876 macro_rules! myc_config_bindings_table_sql { 1877 () => { 1878 r#"CREATE TABLE myc_config_bindings ( 1879 generation INTEGER NOT NULL PRIMARY KEY CHECK (generation BETWEEN 1 AND 1024), 1880 normalized_config_sha256 BLOB NOT NULL CHECK (length(normalized_config_sha256) = 32), 1881 transport_public_key TEXT NOT NULL 1882 CHECK (length(CAST(transport_public_key AS BLOB)) = 64) 1883 CHECK (transport_public_key NOT GLOB '*[^0-9a-f]*'), 1884 user_public_key TEXT NOT NULL 1885 CHECK (length(CAST(user_public_key AS BLOB)) = 64) 1886 CHECK (user_public_key NOT GLOB '*[^0-9a-f]*'), 1887 discovery_public_key TEXT 1888 CHECK (discovery_public_key IS NULL OR 1889 (length(CAST(discovery_public_key AS BLOB)) = 64 1890 AND discovery_public_key NOT GLOB '*[^0-9a-f]*')), 1891 config_contract_version INTEGER NOT NULL 1892 CHECK (config_contract_version BETWEEN 1 AND 4294967295), 1893 state_contract_version INTEGER NOT NULL 1894 CHECK (state_contract_version BETWEEN 1 AND 4294967295), 1895 operator_contract_version INTEGER NOT NULL 1896 CHECK (operator_contract_version BETWEEN 1 AND 4294967295), 1897 status_contract_version INTEGER NOT NULL 1898 CHECK (status_contract_version BETWEEN 1 AND 4294967295), 1899 applied_at_unix_s INTEGER NOT NULL 1900 CHECK (applied_at_unix_s BETWEEN 0 AND 9223372036854775807), 1901 service_version TEXT NOT NULL 1902 CHECK (length(CAST(service_version AS BLOB)) BETWEEN 1 AND 128), 1903 service_commit TEXT NOT NULL 1904 CHECK (length(CAST(service_commit AS BLOB)) = 40), 1905 lib_revision TEXT NOT NULL 1906 CHECK (length(CAST(lib_revision AS BLOB)) = 40), 1907 rust_version TEXT NOT NULL 1908 CHECK (length(CAST(rust_version AS BLOB)) BETWEEN 1 AND 128), 1909 target TEXT NOT NULL CHECK (length(CAST(target AS BLOB)) BETWEEN 1 AND 128), 1910 feature_profile TEXT NOT NULL 1911 CHECK (length(CAST(feature_profile AS BLOB)) BETWEEN 1 AND 128), 1912 provider_contract_version INTEGER NOT NULL 1913 CHECK (provider_contract_version BETWEEN 1 AND 4294967295) 1914 ) STRICT"# 1915 }; 1916 } 1917 1918 macro_rules! myc_config_bindings_guard_insert_sql { 1919 () => { 1920 r#"CREATE TRIGGER myc_config_bindings_guard_insert 1921 BEFORE INSERT ON myc_config_bindings 1922 WHEN NEW.generation != COALESCE( 1923 (SELECT MAX(generation) + 1 FROM myc_config_bindings), 1 1924 ) 1925 OR (SELECT COUNT(*) FROM myc_config_bindings) >= 1024 1926 OR NEW.applied_at_unix_s < COALESCE( 1927 (SELECT MAX(applied_at_unix_s) FROM myc_config_bindings), 0 1928 ) 1929 BEGIN 1930 SELECT RAISE(ABORT, 'configuration binding sequence is invalid'); 1931 END"# 1932 }; 1933 } 1934 1935 macro_rules! myc_config_bindings_no_update_sql { 1936 () => { 1937 r#"CREATE TRIGGER myc_config_bindings_no_update 1938 BEFORE UPDATE ON myc_config_bindings 1939 BEGIN 1940 SELECT RAISE(ABORT, 'configuration binding history is immutable'); 1941 END"# 1942 }; 1943 } 1944 1945 macro_rules! myc_config_bindings_no_delete_sql { 1946 () => { 1947 r#"CREATE TRIGGER myc_config_bindings_no_delete 1948 BEFORE DELETE ON myc_config_bindings 1949 BEGIN 1950 SELECT RAISE(ABORT, 'configuration binding history is retained'); 1951 END"# 1952 }; 1953 } 1954 1955 const CREATE_MYC_CONFIG_BINDINGS_TABLE_SQL: &str = myc_config_bindings_table_sql!(); 1956 const CREATE_MYC_CONFIG_BINDINGS_GUARD_INSERT_SQL: &str = myc_config_bindings_guard_insert_sql!(); 1957 const CREATE_MYC_CONFIG_BINDINGS_NO_UPDATE_SQL: &str = myc_config_bindings_no_update_sql!(); 1958 const CREATE_MYC_CONFIG_BINDINGS_NO_DELETE_SQL: &str = myc_config_bindings_no_delete_sql!(); 1959 1960 const CREATE_MYC_CONFIG_BINDINGS_MIGRATION_SQL: &str = concat!( 1961 myc_config_bindings_table_sql!(), 1962 ";\n", 1963 myc_config_bindings_guard_insert_sql!(), 1964 ";\n", 1965 myc_config_bindings_no_update_sql!(), 1966 ";\n", 1967 myc_config_bindings_no_delete_sql!(), 1968 ";", 1969 ); 1970 1971 macro_rules! myc_admin_operations_table_sql { 1972 () => { 1973 r#"CREATE TABLE myc_admin_operations ( 1974 operation_id TEXT NOT NULL PRIMARY KEY 1975 CHECK (length(CAST(operation_id AS BLOB)) BETWEEN 1 AND 128) 1976 CHECK (substr(operation_id, 1, 1) GLOB '[A-Za-z0-9]') 1977 CHECK (operation_id NOT GLOB '*[^A-Za-z0-9._:-]*'), 1978 route TEXT NOT NULL CHECK (length(CAST(route AS BLOB)) BETWEEN 1 AND 128), 1979 request_sha256 BLOB NOT NULL CHECK (length(request_sha256) = 32), 1980 state TEXT NOT NULL CHECK (state IN ('prepared', 'completed')), 1981 response_model BLOB CHECK (response_model IS NULL OR 1982 length(response_model) BETWEEN 1 AND 8192), 1983 response_sha256 BLOB CHECK (response_sha256 IS NULL OR 1984 length(response_sha256) = 32), 1985 prepared_at_unix_ms INTEGER NOT NULL 1986 CHECK (prepared_at_unix_ms BETWEEN 0 AND 9223372036854775807), 1987 completed_at_unix_ms INTEGER 1988 CHECK (completed_at_unix_ms IS NULL OR 1989 completed_at_unix_ms BETWEEN prepared_at_unix_ms AND 9223372036854775807), 1990 expires_at_unix_ms INTEGER 1991 CHECK (expires_at_unix_ms IS NULL OR 1992 expires_at_unix_ms BETWEEN completed_at_unix_ms AND 9223372036854775807), 1993 CHECK ((state = 'prepared' AND response_model IS NULL 1994 AND response_sha256 IS NULL AND completed_at_unix_ms IS NULL 1995 AND expires_at_unix_ms IS NULL) 1996 OR (state = 'completed' AND response_model IS NOT NULL 1997 AND response_sha256 IS NOT NULL AND completed_at_unix_ms IS NOT NULL 1998 AND expires_at_unix_ms IS NOT NULL)) 1999 ) STRICT"# 2000 }; 2001 } 2002 2003 macro_rules! myc_admin_operations_guard_update_sql { 2004 () => { 2005 r#"CREATE TRIGGER myc_admin_operations_guard_update 2006 BEFORE UPDATE ON myc_admin_operations 2007 WHEN OLD.state != 'prepared' OR NEW.state != 'completed' 2008 OR NEW.operation_id != OLD.operation_id OR NEW.route != OLD.route 2009 OR NEW.request_sha256 != OLD.request_sha256 2010 OR NEW.prepared_at_unix_ms != OLD.prepared_at_unix_ms 2011 OR NEW.response_model IS NULL OR NEW.response_sha256 IS NULL 2012 OR NEW.completed_at_unix_ms IS NULL OR NEW.expires_at_unix_ms IS NULL 2013 BEGIN 2014 SELECT RAISE(ABORT, 'admin operation transition is invalid'); 2015 END"# 2016 }; 2017 } 2018 2019 const CREATE_MYC_ADMIN_OPERATIONS_TABLE_SQL: &str = myc_admin_operations_table_sql!(); 2020 const CREATE_MYC_ADMIN_OPERATIONS_GUARD_UPDATE_SQL: &str = myc_admin_operations_guard_update_sql!(); 2021 const CREATE_MYC_ADMIN_OPERATIONS_MIGRATION_SQL: &str = concat!( 2022 myc_admin_operations_table_sql!(), 2023 ";\n", 2024 myc_admin_operations_guard_update_sql!(), 2025 ";", 2026 ); 2027 2028 const MYC_ADMIN_OPERATIONS_TABLE_SHA256: [u8; 32] = [ 2029 0x22, 0xd6, 0xbc, 0xb4, 0x15, 0xac, 0x9a, 0xf2, 0x4e, 0x41, 0x61, 0xac, 0x2a, 0x8c, 0xae, 0xfb, 2030 0xfb, 0x7a, 0xf0, 0xa4, 0xfe, 0xae, 0xe9, 0xe6, 0xdf, 0x36, 0x67, 0x14, 0x24, 0x5b, 0xf3, 0xf1, 2031 ]; 2032 const MYC_ADMIN_OPERATIONS_GUARD_UPDATE_SHA256: [u8; 32] = [ 2033 0xb9, 0x68, 0x2d, 0x07, 0xca, 0x59, 0x91, 0x3b, 0x66, 0x09, 0xdc, 0x73, 0x61, 0xc5, 0xe0, 0xee, 2034 0x22, 0x52, 0x4f, 0x51, 0x2c, 0xbc, 0xe2, 0x8a, 0x7a, 0x8f, 0xe0, 0xd5, 0x2c, 0xfd, 0x45, 0xf6, 2035 ]; 2036 2037 const NIP46_PENDING_RESPONSES_TABLE_SHA256: [u8; 32] = [ 2038 0x27, 0x99, 0x17, 0x8b, 0x41, 0xb4, 0x4b, 0xb2, 0x22, 0x2c, 0x54, 0x99, 0xbc, 0xc2, 0x67, 0x37, 2039 0x47, 0x84, 0xe8, 0xe1, 0xd5, 0xde, 0xa2, 0xe6, 0x93, 0x6e, 0xfa, 0x9f, 0xb0, 0xc8, 0x80, 0x10, 2040 ]; 2041 const NIP46_PENDING_RESPONSES_GUARD_INSERT_SHA256: [u8; 32] = [ 2042 0x7a, 0x8a, 0x70, 0x91, 0x63, 0x33, 0xf4, 0xb8, 0x39, 0x5e, 0xa9, 0x39, 0x6b, 0xc1, 0xd6, 0x3e, 2043 0x4b, 0x11, 0xe9, 0x96, 0x70, 0x4d, 0x6f, 0x3b, 0xa0, 0x30, 0xac, 0xbb, 0x19, 0x5a, 0xd6, 0x8c, 2044 ]; 2045 const NIP46_SIGNED_RESPONSES_GUARD_PENDING_INSERT_SHA256: [u8; 32] = [ 2046 0xd7, 0x30, 0xca, 0xbe, 0xe4, 0x05, 0x1b, 0xfb, 0x5a, 0x7b, 0x34, 0xe5, 0x9c, 0x1f, 0x35, 0x7b, 2047 0x25, 0x4f, 0xea, 0x50, 0x53, 0x6d, 0xed, 0x67, 0x7e, 0x9e, 0x52, 0x67, 0x4a, 0x6b, 0x15, 0xbe, 2048 ]; 2049 const NIP46_PENDING_RESPONSES_NO_UPDATE_SHA256: [u8; 32] = [ 2050 0x7a, 0xfa, 0xc0, 0xb6, 0x19, 0x61, 0x2d, 0xf8, 0xfe, 0xab, 0xe0, 0x27, 0xa8, 0x18, 0x82, 0x7b, 2051 0xa6, 0x5c, 0x84, 0xed, 0x11, 0x1f, 0x2d, 0x7e, 0xf3, 0xee, 0xdd, 0x3b, 0xaa, 0x3c, 0x7d, 0x4e, 2052 ]; 2053 const NIP46_PENDING_RESPONSES_NO_DELETE_SHA256: [u8; 32] = [ 2054 0xa2, 0x95, 0x91, 0x8a, 0x52, 0x2e, 0xfb, 0xf3, 0xbf, 0x94, 0x73, 0xeb, 0x58, 0x60, 0x67, 0xad, 2055 0x4d, 0x28, 0x64, 0x2f, 0xbb, 0x02, 0xca, 0xf3, 0xdf, 0x2f, 0x2a, 0x02, 0xfd, 0xe1, 0x5d, 0x1b, 2056 ]; 2057 2058 const MYC_CONFIG_BINDINGS_TABLE_SHA256: [u8; 32] = [ 2059 0xf7, 0x7a, 0x0b, 0xc4, 0x4a, 0xb0, 0xf9, 0x18, 0x09, 0xed, 0x6a, 0xb1, 0xaa, 0x0c, 0x9e, 0xd8, 2060 0x80, 0x4c, 0xac, 0x8f, 0x12, 0x15, 0xf1, 0x15, 0xd5, 0x7e, 0x1b, 0x42, 0xe4, 0x20, 0xf2, 0x60, 2061 ]; 2062 const MYC_CONFIG_BINDINGS_GUARD_INSERT_SHA256: [u8; 32] = [ 2063 0x28, 0x4c, 0xc3, 0xa6, 0xe6, 0xb2, 0x42, 0x2c, 0x71, 0x42, 0xb9, 0x43, 0x2f, 0x67, 0x29, 0x20, 2064 0x4d, 0xa7, 0x03, 0xde, 0x21, 0xec, 0x8e, 0xbc, 0xe1, 0xc4, 0xda, 0x24, 0x60, 0x43, 0x5d, 0xce, 2065 ]; 2066 const MYC_CONFIG_BINDINGS_NO_UPDATE_SHA256: [u8; 32] = [ 2067 0xba, 0xcc, 0x52, 0x41, 0x3e, 0x4b, 0xc2, 0x68, 0x01, 0xbc, 0xfd, 0xa0, 0x8b, 0xda, 0xdb, 0x1f, 2068 0x24, 0xd0, 0x6d, 0x86, 0xa1, 0x79, 0x72, 0xd2, 0x93, 0x6b, 0xcf, 0xfb, 0xdd, 0xc7, 0xa0, 0xe5, 2069 ]; 2070 const MYC_CONFIG_BINDINGS_NO_DELETE_SHA256: [u8; 32] = [ 2071 0xb5, 0x2b, 0x12, 0xde, 0xec, 0xc3, 0x2b, 0xe8, 0x5e, 0x48, 0xa9, 0x91, 0xc1, 0x4b, 0xff, 0xc0, 2072 0x0d, 0xe9, 0xfc, 0x24, 0x44, 0x62, 0x83, 0xf3, 0x7c, 0x05, 0xa3, 0x52, 0xdf, 0xfa, 0xcf, 0x5c, 2073 ]; 2074 2075 const CONNECTIONS_TABLE_SHA256: [u8; 32] = [ 2076 0x72, 0xd5, 0xd8, 0xba, 0x24, 0x68, 0x9c, 0x93, 0x34, 0xb3, 0x8f, 0xbf, 0x64, 0x21, 0xe1, 0x65, 2077 0xfd, 0xc3, 0x80, 0x46, 0xf1, 0x3f, 0x56, 0x49, 0x3a, 0xef, 0xd7, 0x42, 0xc4, 0xe6, 0x49, 0x85, 2078 ]; 2079 const CONNECTION_PERMISSIONS_TABLE_SHA256: [u8; 32] = [ 2080 0xc0, 0x84, 0xe6, 0x03, 0xa3, 0xb8, 0xa3, 0x78, 0xeb, 0x58, 0x00, 0x6f, 0x1c, 0x1c, 0xdd, 0x76, 2081 0x7f, 0x67, 0xc7, 0xf4, 0xc8, 0x9d, 0x4c, 0x58, 0x02, 0x57, 0x2d, 0xca, 0x1e, 0x7d, 0x83, 0x02, 2082 ]; 2083 const NIP46_REQUEST_DECISIONS_TABLE_SHA256: [u8; 32] = [ 2084 0xe8, 0x53, 0x1d, 0xed, 0xad, 0x22, 0xfd, 0xfe, 0x96, 0xd4, 0x17, 0x04, 0xea, 0x05, 0x6d, 0xf1, 2085 0x2f, 0xc2, 0x99, 0xac, 0x1a, 0xbf, 0x73, 0xff, 0xcc, 0x6f, 0x2c, 0x5f, 0xdc, 0x27, 0xd9, 0x80, 2086 ]; 2087 const CONNECTION_AUTH_CHALLENGES_TABLE_SHA256: [u8; 32] = [ 2088 0x65, 0x09, 0x11, 0x3c, 0x4b, 0xfa, 0x30, 0x16, 0x7e, 0x0b, 0xc8, 0xf6, 0x67, 0xf5, 0x38, 0xc5, 2089 0x5a, 0xd9, 0x4e, 0x0e, 0xb7, 0x18, 0x22, 0x94, 0x73, 0xea, 0x11, 0x74, 0x9c, 0x8e, 0xa4, 0x37, 2090 ]; 2091 const CONNECTIONS_GUARD_UPDATE_SHA256: [u8; 32] = [ 2092 0x66, 0x61, 0xb0, 0xc6, 0x78, 0x3a, 0x0d, 0x4a, 0x01, 0xb9, 0x7e, 0x7e, 0xd0, 0x8e, 0x2b, 0x6e, 2093 0xdb, 0xd5, 0x3a, 0x28, 0x56, 0x11, 0x88, 0x80, 0x16, 0xf3, 0x2e, 0x5a, 0x42, 0xf0, 0xf9, 0xfe, 2094 ]; 2095 const CONNECTIONS_NO_DELETE_SHA256: [u8; 32] = [ 2096 0xb0, 0xcf, 0x50, 0x22, 0x23, 0x2a, 0xab, 0x23, 0x62, 0x1f, 0xfc, 0x54, 0x8c, 0xc5, 0x88, 0xdb, 2097 0x8c, 0x6e, 0x4a, 0xe0, 0x91, 0x48, 0x0d, 0xda, 0xc8, 0x79, 0x4b, 0x6c, 0x0c, 0x06, 0x3f, 0xaa, 2098 ]; 2099 const CONNECTION_PERMISSIONS_NO_UPDATE_SHA256: [u8; 32] = [ 2100 0x5e, 0x11, 0x4c, 0xa4, 0x28, 0x69, 0x0e, 0xa7, 0x64, 0x3d, 0x67, 0xbc, 0x30, 0x0f, 0x3f, 0xf1, 2101 0xe9, 0x7e, 0xfe, 0x2f, 0x8d, 0xbd, 0x7b, 0x79, 0x47, 0x18, 0x56, 0x3d, 0xb6, 0x64, 0x70, 0x1f, 2102 ]; 2103 const CONNECTION_PERMISSIONS_NO_DELETE_SHA256: [u8; 32] = [ 2104 0xd0, 0x27, 0x41, 0x8e, 0x03, 0x72, 0x87, 0x09, 0x16, 0x49, 0x1d, 0x83, 0x28, 0x98, 0xb9, 0x47, 2105 0xe1, 0x1f, 0xf8, 0xe6, 0x57, 0xbd, 0x89, 0x2c, 0x90, 0xa5, 0x5c, 0x30, 0x51, 0xfe, 0x2b, 0xd7, 2106 ]; 2107 const NIP46_REQUEST_DECISIONS_GUARD_UPDATE_SHA256: [u8; 32] = [ 2108 0x1b, 0xf7, 0xe9, 0xb9, 0x52, 0x64, 0x95, 0x6b, 0x43, 0xf2, 0xc8, 0xdd, 0x73, 0x82, 0xc8, 0xbf, 2109 0x0a, 0xc3, 0xcc, 0x91, 0xa2, 0x95, 0xd7, 0xe2, 0x25, 0xc1, 0xcb, 0xc2, 0xc3, 0xa8, 0x1b, 0x26, 2110 ]; 2111 const NIP46_REQUEST_DECISIONS_NO_DELETE_SHA256: [u8; 32] = [ 2112 0xab, 0xd0, 0x76, 0xca, 0xe9, 0x17, 0x53, 0x6d, 0xdc, 0x9d, 0x03, 0x23, 0x1e, 0xc4, 0xdc, 0xc8, 2113 0xab, 0x8e, 0x7a, 0xc4, 0x23, 0x4e, 0x64, 0x39, 0xaa, 0x58, 0x8b, 0x54, 0x15, 0x7a, 0x2d, 0x34, 2114 ]; 2115 const CONNECTION_AUTH_CHALLENGES_GUARD_UPDATE_SHA256: [u8; 32] = [ 2116 0xb3, 0x24, 0x1e, 0x29, 0x5b, 0x29, 0x68, 0x9b, 0x73, 0x72, 0x5d, 0xe2, 0xce, 0x7c, 0x8c, 0x2b, 2117 0x85, 0xd0, 0xd2, 0xe1, 0xd8, 0xd0, 0x24, 0x6d, 0x35, 0x68, 0x23, 0x2b, 0x9e, 0x87, 0xe4, 0xa8, 2118 ]; 2119 const CONNECTION_AUTH_CHALLENGES_NO_DELETE_SHA256: [u8; 32] = [ 2120 0xf3, 0xf8, 0xd1, 0x48, 0xbc, 0xde, 0x89, 0xd3, 0x34, 0xcd, 0xde, 0x51, 0x4b, 0x83, 0xa2, 0x19, 2121 0x16, 0xe5, 0xd6, 0x72, 0xb7, 0xc3, 0x1e, 0x59, 0xcb, 0xdf, 0x3a, 0x3c, 0x33, 0x80, 0x21, 0x4f, 2122 ]; 2123 const MYC_AUDIT_STATE_TABLE_SHA256: [u8; 32] = [ 2124 0xc8, 0x6b, 0x49, 0xf6, 0x55, 0xac, 0x2c, 0xa4, 0xcb, 0x13, 0xed, 0x31, 0xff, 0x9e, 0xce, 0xe3, 2125 0x2f, 0xd4, 0x2a, 0x3e, 0xb0, 0xf1, 0xc8, 0x52, 0x9d, 0x92, 0xae, 0x5b, 0x48, 0x63, 0x38, 0x3b, 2126 ]; 2127 const OPERATION_AUDIT_TABLE_SHA256: [u8; 32] = [ 2128 0xc1, 0x8d, 0x0b, 0x72, 0x34, 0xff, 0x8b, 0x21, 0x9f, 0x54, 0x20, 0x7f, 0x6c, 0x0b, 0x64, 0xae, 2129 0xd6, 0x8d, 0xd6, 0x1b, 0x48, 0xb3, 0x5b, 0xbe, 0x13, 0x2c, 0x0d, 0xb0, 0x9b, 0xea, 0x16, 0x2d, 2130 ]; 2131 const NIP46_REQUEST_AUDIT_TABLE_SHA256: [u8; 32] = [ 2132 0xe2, 0x42, 0x82, 0x0b, 0xbb, 0xb2, 0x31, 0xa3, 0x8e, 0x9e, 0x7d, 0xf3, 0xf0, 0xe4, 0xd3, 0xc6, 2133 0x85, 0x93, 0x19, 0xe1, 0x2e, 0x47, 0x84, 0x48, 0x98, 0x8b, 0xc0, 0xdf, 0xdf, 0x96, 0xc6, 0xe3, 2134 ]; 2135 const CONNECTION_RATE_WINDOWS_TABLE_SHA256: [u8; 32] = [ 2136 0x57, 0x53, 0xdf, 0x7b, 0x74, 0x44, 0x96, 0x9d, 0x88, 0x56, 0xe6, 0x1f, 0x15, 0x36, 0xdc, 0xab, 2137 0xa0, 0x02, 0x0a, 0x78, 0x77, 0x8e, 0x48, 0xa2, 0x80, 0x97, 0xc6, 0x37, 0xa6, 0x31, 0x17, 0xfc, 2138 ]; 2139 const MYC_AUDIT_STATE_GUARD_UPDATE_SHA256: [u8; 32] = [ 2140 0xda, 0xba, 0xc9, 0x86, 0x0f, 0x2a, 0xd8, 0xa0, 0x60, 0x75, 0x4b, 0x87, 0x78, 0xc8, 0xd8, 0xce, 2141 0x78, 0xa3, 0x57, 0x6e, 0xea, 0x08, 0x2b, 0x0c, 0x9c, 0x56, 0x5d, 0xa2, 0xb5, 0x6c, 0x68, 0xad, 2142 ]; 2143 const MYC_AUDIT_STATE_NO_DELETE_SHA256: [u8; 32] = [ 2144 0x0a, 0x88, 0xa1, 0xbe, 0xe8, 0x23, 0x1f, 0xf0, 0xaf, 0x41, 0x91, 0xd7, 0x38, 0x64, 0x67, 0xb6, 2145 0xa8, 0xac, 0xda, 0xf0, 0x38, 0x8e, 0xd4, 0xb0, 0xac, 0x2c, 0xb6, 0xf2, 0x0a, 0xa1, 0xf5, 0x5c, 2146 ]; 2147 const OPERATION_AUDIT_NO_UPDATE_SHA256: [u8; 32] = [ 2148 0xd8, 0xe4, 0x39, 0x63, 0x67, 0x74, 0x97, 0x4c, 0xa7, 0x97, 0x54, 0x6c, 0xed, 0x39, 0x9a, 0x7b, 2149 0xbc, 0x6c, 0x36, 0xc5, 0xd7, 0x8e, 0xf4, 0x08, 0xbd, 0xfd, 0xb7, 0x9b, 0xd0, 0x36, 0x74, 0x40, 2150 ]; 2151 const NIP46_REQUEST_AUDIT_NO_UPDATE_SHA256: [u8; 32] = [ 2152 0x8a, 0x4a, 0x99, 0x4c, 0x13, 0x5f, 0x8d, 0x4d, 0x85, 0xd1, 0x25, 0x1d, 0x65, 0x47, 0x4d, 0x23, 2153 0x37, 0x62, 0xb7, 0x27, 0xb6, 0x7f, 0x31, 0xd4, 0x9c, 0x93, 0xe5, 0xce, 0x18, 0x43, 0xba, 0x81, 2154 ]; 2155 const CONNECTION_RATE_WINDOWS_GUARD_UPDATE_SHA256: [u8; 32] = [ 2156 0x59, 0x3c, 0xfb, 0xff, 0x20, 0x95, 0x32, 0x4e, 0x61, 0xdc, 0xd6, 0x09, 0xea, 0x7b, 0x1b, 0x1d, 2157 0xc4, 0xb9, 0xb7, 0x38, 0xcf, 0x80, 0x56, 0x00, 0xa5, 0x3b, 0xb4, 0xcd, 0x02, 0xcd, 0xe1, 0xef, 2158 ]; 2159 const PUBLICATION_OUTBOX_TABLE_SHA256: [u8; 32] = [ 2160 0x26, 0xbd, 0xa8, 0x77, 0x39, 0x07, 0xdb, 0x05, 0xa8, 0x7c, 0x38, 0x21, 0x9b, 0x58, 0xd7, 0xf8, 2161 0xc8, 0x01, 0x80, 0xb3, 0x50, 0xae, 0x69, 0x87, 0xd2, 0x13, 0xd1, 0x84, 0xc6, 0x1d, 0x15, 0x0c, 2162 ]; 2163 const PUBLICATION_TARGETS_TABLE_SHA256: [u8; 32] = [ 2164 0x16, 0xd5, 0xa3, 0x85, 0x71, 0x0d, 0xb1, 0x02, 0xaa, 0x25, 0x02, 0x80, 0xbb, 0xc4, 0x23, 0x44, 2165 0x20, 0xc1, 0xa2, 0x8a, 0x33, 0xaf, 0xd0, 0xe9, 0x6b, 0x65, 0x7a, 0x79, 0xd7, 0xe3, 0x1b, 0x43, 2166 ]; 2167 const PUBLICATION_ATTEMPTS_TABLE_SHA256: [u8; 32] = [ 2168 0x25, 0xed, 0xa7, 0xb2, 0xd5, 0x07, 0xc2, 0xe5, 0x29, 0xef, 0x07, 0x31, 0xe6, 0x84, 0x6a, 0x64, 2169 0xe9, 0xef, 0x11, 0x47, 0x41, 0x0d, 0xc9, 0x79, 0x43, 0x06, 0x8e, 0x78, 0x47, 0xfb, 0x3b, 0x3d, 2170 ]; 2171 const PUBLICATION_OUTBOX_GUARD_UPDATE_SHA256: [u8; 32] = [ 2172 0x6f, 0xb5, 0x23, 0x36, 0x36, 0x1d, 0xea, 0x76, 0x83, 0x4c, 0x55, 0xe3, 0xdb, 0x90, 0xf1, 0xd1, 2173 0x84, 0xcb, 0x11, 0x23, 0x17, 0x1f, 0x09, 0xd7, 0xee, 0x9c, 0xdc, 0x70, 0x28, 0xbe, 0x24, 0xc4, 2174 ]; 2175 const PUBLICATION_TARGETS_GUARD_UPDATE_SHA256: [u8; 32] = [ 2176 0x3e, 0x74, 0xf3, 0x95, 0x67, 0x81, 0x3e, 0x55, 0xfd, 0xc6, 0x73, 0x50, 0xa4, 0xa4, 0x4a, 0xb1, 2177 0x77, 0xf0, 0x12, 0x8a, 0xe7, 0xd0, 0x07, 0x3d, 0x23, 0x92, 0x89, 0x1c, 0x97, 0x9d, 0x2f, 0x34, 2178 ]; 2179 const PUBLICATION_ATTEMPTS_GUARD_UPDATE_SHA256: [u8; 32] = [ 2180 0x5f, 0xda, 0xc3, 0xa9, 0x01, 0x48, 0x93, 0xac, 0xb4, 0x33, 0x3f, 0xac, 0x16, 0xe9, 0x63, 0x22, 2181 0xcb, 0x74, 0xff, 0xe6, 0x2c, 0xbf, 0x89, 0xfc, 0x59, 0x4f, 0x75, 0xc6, 0x39, 0xa0, 0x40, 0xc9, 2182 ]; 2183 const PUBLICATION_OUTBOX_NO_DELETE_SHA256: [u8; 32] = [ 2184 0xe9, 0x0e, 0x86, 0x86, 0xe8, 0xf0, 0x51, 0xb7, 0x89, 0x97, 0x92, 0x92, 0x8c, 0x6a, 0xd6, 0x64, 2185 0xb9, 0x79, 0xaa, 0xbf, 0xbe, 0x08, 0x5d, 0xad, 0xc0, 0x69, 0x02, 0xa7, 0x5e, 0x58, 0xa5, 0x28, 2186 ]; 2187 const PUBLICATION_TARGETS_NO_DELETE_SHA256: [u8; 32] = [ 2188 0x19, 0x0b, 0x6b, 0x34, 0xd0, 0x69, 0x45, 0x24, 0xd8, 0x57, 0x17, 0xf7, 0x27, 0x9e, 0xd9, 0x0c, 2189 0x5a, 0xc0, 0xc2, 0xa6, 0x63, 0xd6, 0x95, 0x2e, 0x77, 0x55, 0x8f, 0x6f, 0x7c, 0x81, 0xb0, 0x48, 2190 ]; 2191 const PUBLICATION_ATTEMPTS_NO_DELETE_SHA256: [u8; 32] = [ 2192 0x72, 0x0a, 0x1f, 0x3a, 0x40, 0xfb, 0xf8, 0x63, 0xeb, 0x1f, 0xd4, 0x54, 0x7f, 0xa0, 0xbc, 0x43, 2193 0x50, 0x65, 0x2b, 0xb2, 0xf0, 0x98, 0x9f, 0xda, 0x1f, 0xc6, 0x49, 0xcf, 0xd8, 0xb5, 0xd4, 0xe5, 2194 ]; 2195 const DELIVERY_JOBS_TABLE_SHA256: [u8; 32] = [ 2196 0xbb, 0xb1, 0xcf, 0xa2, 0x5e, 0x1e, 0xdd, 0x70, 0x30, 0x61, 0xd8, 0x43, 0xbe, 0x8d, 0x8c, 0x2b, 2197 0x16, 0x8c, 0x35, 0x6c, 0x9a, 0x9c, 0x0b, 0xe7, 0x88, 0x64, 0x18, 0xde, 0xca, 0xdd, 0x05, 0x01, 2198 ]; 2199 const DELIVERY_TARGETS_TABLE_SHA256: [u8; 32] = [ 2200 0xce, 0xa5, 0x3a, 0xa4, 0x64, 0x18, 0xb1, 0x8e, 0xaf, 0x61, 0xe0, 0x90, 0xf9, 0x51, 0xe7, 0x76, 2201 0x79, 0xba, 0x33, 0x97, 0xc5, 0xa9, 0x5b, 0x3c, 0xa7, 0xeb, 0x83, 0x81, 0x4a, 0x8c, 0xaf, 0x69, 2202 ]; 2203 const DELIVERY_ATTEMPTS_TABLE_SHA256: [u8; 32] = [ 2204 0xae, 0x8c, 0x2a, 0xa4, 0x61, 0xeb, 0xb2, 0x04, 0x69, 0x7b, 0xdc, 0x57, 0xc9, 0x34, 0x9c, 0x1b, 2205 0x86, 0x4b, 0x0f, 0xcd, 0x7b, 0xba, 0x9a, 0x45, 0xa7, 0x72, 0x2b, 0x49, 0xa0, 0x95, 0x94, 0xb8, 2206 ]; 2207 const DELIVERY_JOBS_GUARD_INSERT_SHA256: [u8; 32] = [ 2208 0x29, 0x60, 0xe9, 0x9e, 0x32, 0xcd, 0x50, 0x0a, 0xfb, 0xa2, 0x5a, 0xc6, 0xbc, 0x2b, 0xfc, 0xa0, 2209 0x1a, 0x71, 0x95, 0x68, 0xa6, 0x2c, 0xa7, 0xac, 0x63, 0xd4, 0x79, 0x30, 0xc8, 0x5a, 0x8f, 0x7f, 2210 ]; 2211 const DELIVERY_JOBS_GUARD_UPDATE_SHA256: [u8; 32] = [ 2212 0xc9, 0x5f, 0x5c, 0xac, 0x67, 0xa5, 0xe8, 0x1e, 0x88, 0xca, 0x5d, 0xf2, 0xc4, 0x8e, 0x71, 0x39, 2213 0xb6, 0x11, 0xc4, 0x4f, 0xa9, 0x59, 0x09, 0xea, 0xf7, 0x5e, 0x34, 0x61, 0xab, 0x5a, 0x5c, 0xe8, 2214 ]; 2215 const DELIVERY_TARGETS_GUARD_UPDATE_SHA256: [u8; 32] = [ 2216 0x1b, 0xf7, 0x81, 0xe9, 0x9e, 0xe2, 0xdd, 0x1a, 0xb9, 0xc7, 0xd5, 0xd4, 0x25, 0x96, 0x65, 0x11, 2217 0x79, 0x50, 0x1f, 0x74, 0xbf, 0x1a, 0x09, 0xdb, 0x99, 0x9c, 0x19, 0x9f, 0x25, 0xff, 0x98, 0x97, 2218 ]; 2219 const DELIVERY_ATTEMPTS_GUARD_UPDATE_SHA256: [u8; 32] = [ 2220 0x24, 0x5f, 0x0a, 0x53, 0xa0, 0xd5, 0x96, 0xa9, 0x62, 0x82, 0x70, 0xca, 0x9b, 0x89, 0x9e, 0xc2, 2221 0xd8, 0xe7, 0xf1, 0x45, 0x81, 0x61, 0x6f, 0x61, 0x62, 0x66, 0x98, 0xf5, 0x48, 0x29, 0x76, 0x9c, 2222 ]; 2223 const DELIVERY_JOBS_NO_DELETE_SHA256: [u8; 32] = [ 2224 0x19, 0x9b, 0x4a, 0xc3, 0x1e, 0x53, 0x87, 0xed, 0x6a, 0xbc, 0x15, 0x69, 0x51, 0x38, 0x0d, 0xf2, 2225 0x61, 0xf7, 0x3c, 0x97, 0x0c, 0xc3, 0x7b, 0x16, 0xfc, 0x9e, 0xca, 0x47, 0x1a, 0x64, 0x3d, 0xb2, 2226 ]; 2227 const DELIVERY_TARGETS_NO_DELETE_SHA256: [u8; 32] = [ 2228 0xa6, 0xa1, 0xd0, 0xb7, 0x42, 0xfd, 0x4f, 0xd7, 0x1d, 0x14, 0x0c, 0x64, 0xfd, 0xda, 0x1b, 0x1a, 2229 0x60, 0xfb, 0xea, 0xc4, 0xea, 0x6e, 0x22, 0xd8, 0x12, 0x79, 0xc3, 0xee, 0xbb, 0xf8, 0xb1, 0x29, 2230 ]; 2231 const DELIVERY_ATTEMPTS_NO_DELETE_SHA256: [u8; 32] = [ 2232 0x8b, 0x6d, 0x86, 0x04, 0xe3, 0x6b, 0xf6, 0xb9, 0xa2, 0x21, 0x13, 0x39, 0xda, 0xd1, 0xf0, 0x9a, 2233 0x6a, 0xf3, 0x31, 0xef, 0x46, 0xbc, 0xdd, 0xd1, 0xe0, 0xe3, 0xef, 0x35, 0x07, 0x40, 0x08, 0xf1, 2234 ]; 2235 const DISCOVERY_DESIRED_STATE_TABLE_SHA256: [u8; 32] = [ 2236 0xad, 0x85, 0x4a, 0x61, 0x50, 0xa4, 0x0f, 0xf9, 0x99, 0xe7, 0x2e, 0xf8, 0xa7, 0x63, 0xa8, 0xc8, 2237 0xcc, 0x57, 0x9d, 0x37, 0x23, 0xa2, 0x20, 0x67, 0x3c, 0xb1, 0xee, 0xbe, 0x9a, 0xda, 0xec, 0xce, 2238 ]; 2239 const DISCOVERY_DOCUMENTS_TABLE_SHA256: [u8; 32] = [ 2240 0x0b, 0x44, 0x57, 0x52, 0xbd, 0xdc, 0x28, 0x9c, 0x90, 0x96, 0x42, 0x80, 0x00, 0x8e, 0x00, 0x2a, 2241 0x96, 0x81, 0x1a, 0x2a, 0x67, 0x96, 0x9c, 0x6c, 0x55, 0x44, 0x1b, 0xa2, 0xff, 0x0e, 0x01, 0x28, 2242 ]; 2243 const DISCOVERY_PUBLICATION_STATE_TABLE_SHA256: [u8; 32] = [ 2244 0xc1, 0x61, 0x4f, 0xc6, 0x3e, 0x56, 0xae, 0xcd, 0xcf, 0x81, 0xe5, 0xea, 0x45, 0x93, 0x16, 0xc1, 2245 0x44, 0x71, 0x97, 0x11, 0xda, 0x97, 0x9c, 0xd5, 0xe4, 0x2a, 0x62, 0x54, 0x01, 0x24, 0xa1, 0x62, 2246 ]; 2247 const DISCOVERY_DESIRED_STATE_NO_UPDATE_SHA256: [u8; 32] = [ 2248 0x5a, 0x4e, 0x12, 0x67, 0x2a, 0xb5, 0x75, 0xb7, 0x91, 0x35, 0xb0, 0xd2, 0x87, 0xcb, 0x33, 0x83, 2249 0x89, 0x8a, 0x51, 0x32, 0xf2, 0x34, 0xc1, 0x20, 0xd4, 0x5a, 0x56, 0x10, 0x6d, 0xe6, 0x92, 0x4c, 2250 ]; 2251 const DISCOVERY_DESIRED_STATE_NO_DELETE_SHA256: [u8; 32] = [ 2252 0x5e, 0x1e, 0xcc, 0x9f, 0x37, 0x97, 0x38, 0xdf, 0x66, 0x0f, 0x89, 0xb2, 0xb6, 0x5d, 0x85, 0xd4, 2253 0xd2, 0x2c, 0xa1, 0x47, 0x7f, 0x20, 0x2e, 0x9b, 0xcb, 0x52, 0xb8, 0x95, 0x55, 0x8f, 0xeb, 0xf0, 2254 ]; 2255 const DISCOVERY_DOCUMENTS_NO_UPDATE_SHA256: [u8; 32] = [ 2256 0x80, 0xf0, 0x11, 0x68, 0xe6, 0x3e, 0x94, 0xd1, 0xa6, 0xcd, 0x63, 0xf6, 0x16, 0xed, 0xdf, 0x05, 2257 0x7d, 0x58, 0xb4, 0x77, 0x8b, 0x83, 0xac, 0xc6, 0x07, 0xd3, 0x98, 0x11, 0xbf, 0x0d, 0x83, 0xf7, 2258 ]; 2259 const DISCOVERY_DOCUMENTS_NO_DELETE_SHA256: [u8; 32] = [ 2260 0x23, 0xd4, 0x66, 0xe2, 0x21, 0xd3, 0x7a, 0xa1, 0xe0, 0xb7, 0xa6, 0x4e, 0x01, 0x5b, 0x1c, 0xf0, 2261 0xd5, 0x8d, 0xad, 0x1c, 0x31, 0x5b, 0x1a, 0x9e, 0x88, 0x17, 0x5c, 0x6b, 0x59, 0xd4, 0x47, 0xec, 2262 ]; 2263 const DISCOVERY_PUBLICATION_STATE_GUARD_UPDATE_SHA256: [u8; 32] = [ 2264 0xfc, 0xe8, 0x4a, 0xa7, 0x55, 0x00, 0x1c, 0x00, 0x12, 0x99, 0xc7, 0x58, 0xa1, 0xc6, 0x6a, 0x70, 2265 0x99, 0xba, 0x07, 0x77, 0xc7, 0x8e, 0xce, 0x5a, 0xeb, 0xa7, 0xf8, 0x5a, 0x27, 0x52, 0xb7, 0x5f, 2266 ]; 2267 const DISCOVERY_PUBLICATION_STATE_NO_DELETE_SHA256: [u8; 32] = [ 2268 0xcd, 0x1b, 0xb2, 0x56, 0x6e, 0x3e, 0x46, 0x14, 0x4a, 0x4d, 0x38, 0xf1, 0xcb, 0xf9, 0xa0, 0xc4, 2269 0xb8, 0x94, 0xb8, 0x96, 0x71, 0x75, 0x49, 0x9c, 0x12, 0xb0, 0x15, 0x1d, 0xa0, 0x06, 0x1c, 0xa0, 2270 ]; 2271 const NIP46_OPERATION_COMMITS_TABLE_SHA256: [u8; 32] = [ 2272 0x5f, 0x56, 0x46, 0xcf, 0xef, 0xee, 0x82, 0x58, 0xe6, 0xa7, 0x27, 0x53, 0x32, 0xbd, 0xb9, 0x92, 2273 0xaf, 0xc5, 0x3c, 0x0c, 0xaf, 0x10, 0x87, 0xe5, 0x25, 0x1e, 0x89, 0x8c, 0x4c, 0xd6, 0xc5, 0x4d, 2274 ]; 2275 const NIP46_OPERATION_COMMITS_NO_UPDATE_SHA256: [u8; 32] = [ 2276 0x52, 0xa9, 0x7d, 0x6c, 0xbd, 0x06, 0x9e, 0xe1, 0x19, 0x00, 0x98, 0xdd, 0x36, 0x6b, 0x38, 0xd7, 2277 0xff, 0xa5, 0x9d, 0x04, 0x7b, 0x6b, 0xa9, 0x79, 0x54, 0xb7, 0x7f, 0x5c, 0x13, 0x97, 0x13, 0xd3, 2278 ]; 2279 const NIP46_OPERATION_COMMITS_NO_DELETE_SHA256: [u8; 32] = [ 2280 0x99, 0x67, 0xd8, 0x61, 0xd2, 0xa7, 0x1e, 0x1a, 0x74, 0x3f, 0xb5, 0xe9, 0x7b, 0x96, 0xe0, 0x00, 2281 0xa9, 0xaa, 0x38, 0xe4, 0xb6, 0x76, 0x47, 0xa0, 0x87, 0x0b, 0x48, 0x9b, 0x55, 0x20, 0xa9, 0xa3, 2282 ]; 2283 const NIP46_SIGNED_RESPONSES_TABLE_SHA256: [u8; 32] = [ 2284 0x12, 0xf2, 0x9a, 0x4b, 0x24, 0x62, 0x5a, 0xf4, 0xcb, 0x0e, 0xa1, 0x16, 0x9d, 0x64, 0x9c, 0x1f, 2285 0xe6, 0x4a, 0xe7, 0x10, 0x14, 0x52, 0xbc, 0x43, 0x9c, 0xdd, 0x86, 0x23, 0x47, 0x60, 0x96, 0x19, 2286 ]; 2287 const NIP46_SIGNED_RESPONSES_NO_UPDATE_SHA256: [u8; 32] = [ 2288 0xee, 0xd8, 0xb0, 0x82, 0xc7, 0x46, 0x37, 0x53, 0x5a, 0x77, 0x77, 0x95, 0xb5, 0x29, 0x58, 0x41, 2289 0x5a, 0x3f, 0xab, 0xc3, 0xa6, 0x7a, 0xcf, 0x44, 0xef, 0xe0, 0xc6, 0x82, 0xeb, 0xcb, 0x2d, 0x05, 2290 ]; 2291 const NIP46_SIGNED_RESPONSES_NO_DELETE_SHA256: [u8; 32] = [ 2292 0x8e, 0x6a, 0x36, 0xe5, 0x89, 0x50, 0x81, 0x90, 0x5f, 0x1c, 0x32, 0x19, 0x25, 0xec, 0x37, 0x07, 2293 0x1f, 0x42, 0xd9, 0x1a, 0x73, 0xd3, 0x89, 0x56, 0x3d, 0x2b, 0x4b, 0x3e, 0x9d, 0x3a, 0xf3, 0xa4, 2294 ]; 2295 2296 /// Stable classes for invalid embedded Myc catalog definitions. 2297 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 2298 pub enum MycStateCatalogErrorKind { 2299 MigrationCatalog, 2300 SchemaCatalog, 2301 CatalogMismatch, 2302 } 2303 2304 impl MycStateCatalogErrorKind { 2305 /// Returns the stable machine-readable classification. 2306 #[must_use] 2307 pub const fn code(self) -> &'static str { 2308 match self { 2309 Self::MigrationCatalog => "migration_catalog_invalid", 2310 Self::SchemaCatalog => "schema_catalog_invalid", 2311 Self::CatalogMismatch => "state_catalog_mismatch", 2312 } 2313 } 2314 } 2315 2316 /// Source-free failure to construct or validate the embedded Myc catalogs. 2317 #[derive(Clone, Copy, PartialEq, Eq)] 2318 pub struct MycStateCatalogError { 2319 kind: MycStateCatalogErrorKind, 2320 } 2321 2322 impl MycStateCatalogError { 2323 const fn new(kind: MycStateCatalogErrorKind) -> Self { 2324 Self { kind } 2325 } 2326 2327 /// Returns the stable failure class. 2328 #[must_use] 2329 pub const fn kind(self) -> MycStateCatalogErrorKind { 2330 self.kind 2331 } 2332 2333 /// Returns the stable machine-readable failure code. 2334 #[must_use] 2335 pub const fn code(self) -> &'static str { 2336 self.kind.code() 2337 } 2338 } 2339 2340 impl fmt::Display for MycStateCatalogError { 2341 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { 2342 formatter.write_str(match self.kind { 2343 MycStateCatalogErrorKind::MigrationCatalog => { 2344 "Myc migration catalog definition is invalid" 2345 } 2346 MycStateCatalogErrorKind::SchemaCatalog => "Myc schema catalog definition is invalid", 2347 MycStateCatalogErrorKind::CatalogMismatch => { 2348 "Myc state catalogs do not match the governed identity" 2349 } 2350 }) 2351 } 2352 } 2353 2354 impl fmt::Debug for MycStateCatalogError { 2355 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { 2356 formatter 2357 .debug_struct("MycStateCatalogError") 2358 .field("kind", &self.kind) 2359 .finish() 2360 } 2361 } 2362 2363 impl Error for MycStateCatalogError {} 2364 2365 /// Constructs the exact ordered Myc migration catalog. 2366 pub fn myc_migration_catalog() -> Result<MigrationCatalog, MycStateCatalogError> { 2367 let metadata = MigrationDescriptor::sql( 2368 2, 2369 "create_myc_state_metadata", 2370 CREATE_MYC_STATE_METADATA_MIGRATION_SQL, 2371 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_2_MIGRATION_SHA256), 2372 ) 2373 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2374 let requests = MigrationDescriptor::sql( 2375 3, 2376 "create_nip46_request_admission", 2377 CREATE_NIP46_REQUEST_ADMISSION_MIGRATION_SQL, 2378 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_3_MIGRATION_SHA256), 2379 ) 2380 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2381 let connections = MigrationDescriptor::sql( 2382 4, 2383 "create_connection_authorization_state", 2384 CREATE_CONNECTION_STATE_MIGRATION_SQL, 2385 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_4_MIGRATION_SHA256), 2386 ) 2387 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2388 let governance = MigrationDescriptor::sql( 2389 5, 2390 "create_bounded_governance_state", 2391 CREATE_GOVERNANCE_STATE_MIGRATION_SQL, 2392 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_5_MIGRATION_SHA256), 2393 ) 2394 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2395 let delivery = MigrationDescriptor::sql( 2396 6, 2397 "create_delivery_evidence_state", 2398 CREATE_DELIVERY_STATE_MIGRATION_SQL, 2399 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_6_MIGRATION_SHA256), 2400 ) 2401 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2402 let discovery = MigrationDescriptor::sql( 2403 7, 2404 "create_discovery_desired_state", 2405 CREATE_DISCOVERY_STATE_MIGRATION_SQL, 2406 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_7_MIGRATION_SHA256), 2407 ) 2408 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2409 let completion = MigrationDescriptor::sql( 2410 8, 2411 "create_nip46_operation_completion", 2412 CREATE_NIP46_OPERATION_COMPLETION_MIGRATION_SQL, 2413 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_8_MIGRATION_SHA256), 2414 ) 2415 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2416 let response = MigrationDescriptor::sql( 2417 9, 2418 "create_nip46_atomic_response", 2419 CREATE_NIP46_ATOMIC_RESPONSE_MIGRATION_SQL, 2420 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_9_MIGRATION_SHA256), 2421 ) 2422 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2423 let configuration = MigrationDescriptor::sql( 2424 10, 2425 "create_configuration_binding_history", 2426 CREATE_MYC_CONFIG_BINDINGS_MIGRATION_SQL, 2427 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_10_MIGRATION_SHA256), 2428 ) 2429 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2430 let admin_operations = MigrationDescriptor::sql( 2431 11, 2432 "create_admin_operation_journal", 2433 CREATE_MYC_ADMIN_OPERATIONS_MIGRATION_SQL, 2434 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_11_MIGRATION_SHA256), 2435 ) 2436 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2437 let pending_responses = MigrationDescriptor::sql( 2438 12, 2439 "create_nip46_pending_response_authority", 2440 CREATE_NIP46_PENDING_RESPONSE_MIGRATION_SQL, 2441 MigrationChecksum::from_bytes(MYC_STATE_SCHEMA_VERSION_12_MIGRATION_SHA256), 2442 ) 2443 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2444 let catalog = MigrationCatalog::new([ 2445 metadata, 2446 requests, 2447 connections, 2448 governance, 2449 delivery, 2450 discovery, 2451 completion, 2452 response, 2453 configuration, 2454 admin_operations, 2455 pending_responses, 2456 ]) 2457 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::MigrationCatalog))?; 2458 if catalog.current_version() != MYC_STATE_SCHEMA_VERSION 2459 || catalog.descriptors().len() != 11 2460 || catalog.digest().as_bytes() != &MYC_MIGRATION_CATALOG_SHA256 2461 { 2462 return Err(MycStateCatalogError::new( 2463 MycStateCatalogErrorKind::CatalogMismatch, 2464 )); 2465 } 2466 Ok(catalog) 2467 } 2468 2469 /// Constructs the exact Myc schema catalog bound to the migration catalog. 2470 pub fn myc_schema_catalog() -> Result<SchemaCatalog, MycStateCatalogError> { 2471 let migrations = myc_migration_catalog()?; 2472 let version_one = SchemaVersionCatalog::new( 2473 MYC_STATE_BASE_SCHEMA_VERSION, 2474 [], 2475 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_1_SHA256), 2476 ) 2477 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2478 let version_two = SchemaVersionCatalog::new( 2479 2, 2480 myc_state_metadata_objects()?, 2481 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_2_SHA256), 2482 ) 2483 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2484 let version_three = SchemaVersionCatalog::new( 2485 3, 2486 myc_state_request_objects()?, 2487 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_3_SHA256), 2488 ) 2489 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2490 let version_four = SchemaVersionCatalog::new( 2491 4, 2492 myc_state_connection_objects()?, 2493 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_4_SHA256), 2494 ) 2495 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2496 let version_five = SchemaVersionCatalog::new( 2497 5, 2498 myc_state_governance_objects()?, 2499 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_5_SHA256), 2500 ) 2501 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2502 let version_six = SchemaVersionCatalog::new( 2503 6, 2504 myc_state_delivery_objects()?, 2505 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_6_SHA256), 2506 ) 2507 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2508 let version_seven = SchemaVersionCatalog::new( 2509 7, 2510 myc_state_discovery_objects()?, 2511 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_7_SHA256), 2512 ) 2513 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2514 let version_eight = SchemaVersionCatalog::new( 2515 8, 2516 myc_state_completion_objects()?, 2517 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_8_SHA256), 2518 ) 2519 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2520 let version_nine = SchemaVersionCatalog::new( 2521 9, 2522 myc_state_response_objects()?, 2523 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_9_SHA256), 2524 ) 2525 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2526 let version_ten = SchemaVersionCatalog::new( 2527 10, 2528 myc_state_config_binding_objects()?, 2529 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_10_SHA256), 2530 ) 2531 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2532 let version_eleven = SchemaVersionCatalog::new( 2533 11, 2534 myc_state_admin_operation_objects()?, 2535 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_11_SHA256), 2536 ) 2537 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2538 let version_twelve = SchemaVersionCatalog::new( 2539 12, 2540 myc_state_pending_response_objects()?, 2541 SchemaDigest::from_bytes(MYC_STATE_SCHEMA_VERSION_12_SHA256), 2542 ) 2543 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2544 let catalog = SchemaCatalog::new( 2545 &migrations, 2546 [ 2547 version_one, 2548 version_two, 2549 version_three, 2550 version_four, 2551 version_five, 2552 version_six, 2553 version_seven, 2554 version_eight, 2555 version_nine, 2556 version_ten, 2557 version_eleven, 2558 version_twelve, 2559 ], 2560 ) 2561 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2562 validate_myc_state_catalogs(&migrations, &catalog)?; 2563 Ok(catalog) 2564 } 2565 2566 fn myc_state_metadata_objects() -> Result<[SchemaObject; 3], MycStateCatalogError> { 2567 let table = SchemaObject::new( 2568 SchemaObjectKind::Table, 2569 "myc_state_metadata", 2570 "myc_state_metadata", 2571 CREATE_MYC_STATE_METADATA_TABLE_SQL, 2572 SchemaDigest::from_bytes(MYC_STATE_METADATA_TABLE_SHA256), 2573 ) 2574 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2575 let update = SchemaObject::new( 2576 SchemaObjectKind::Trigger, 2577 "myc_state_metadata_no_update", 2578 "myc_state_metadata", 2579 CREATE_MYC_STATE_METADATA_NO_UPDATE_SQL, 2580 SchemaDigest::from_bytes(MYC_STATE_METADATA_NO_UPDATE_SHA256), 2581 ) 2582 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2583 let delete = SchemaObject::new( 2584 SchemaObjectKind::Trigger, 2585 "myc_state_metadata_no_delete", 2586 "myc_state_metadata", 2587 CREATE_MYC_STATE_METADATA_NO_DELETE_SQL, 2588 SchemaDigest::from_bytes(MYC_STATE_METADATA_NO_DELETE_SHA256), 2589 ) 2590 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?; 2591 Ok([table, update, delete]) 2592 } 2593 2594 fn myc_state_request_objects() -> Result<[SchemaObject; 7], MycStateCatalogError> { 2595 let [metadata_table, metadata_update, metadata_delete] = myc_state_metadata_objects()?; 2596 Ok([ 2597 metadata_table, 2598 metadata_update, 2599 metadata_delete, 2600 SchemaObject::new( 2601 SchemaObjectKind::Table, 2602 "nip46_requests", 2603 "nip46_requests", 2604 CREATE_NIP46_REQUESTS_TABLE_SQL, 2605 SchemaDigest::from_bytes(NIP46_REQUESTS_TABLE_SHA256), 2606 ) 2607 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?, 2608 SchemaObject::new( 2609 SchemaObjectKind::Table, 2610 "nip46_request_dedup", 2611 "nip46_request_dedup", 2612 CREATE_NIP46_REQUEST_DEDUP_TABLE_SQL, 2613 SchemaDigest::from_bytes(NIP46_REQUEST_DEDUP_TABLE_SHA256), 2614 ) 2615 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?, 2616 SchemaObject::new( 2617 SchemaObjectKind::Trigger, 2618 "nip46_requests_no_update", 2619 "nip46_requests", 2620 CREATE_NIP46_REQUESTS_NO_UPDATE_SQL, 2621 SchemaDigest::from_bytes(NIP46_REQUESTS_NO_UPDATE_SHA256), 2622 ) 2623 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?, 2624 SchemaObject::new( 2625 SchemaObjectKind::Trigger, 2626 "nip46_request_dedup_guard_update", 2627 "nip46_request_dedup", 2628 CREATE_NIP46_REQUEST_DEDUP_GUARD_UPDATE_SQL, 2629 SchemaDigest::from_bytes(NIP46_REQUEST_DEDUP_GUARD_UPDATE_SHA256), 2630 ) 2631 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog))?, 2632 ]) 2633 } 2634 2635 fn myc_state_connection_objects() -> Result<[SchemaObject; 19], MycStateCatalogError> { 2636 let [ 2637 metadata_table, 2638 metadata_update, 2639 metadata_delete, 2640 request_table, 2641 request_dedup, 2642 request_update, 2643 request_dedup_update, 2644 ] = myc_state_request_objects()?; 2645 let object = |kind, name, table, sql, digest| { 2646 SchemaObject::new(kind, name, table, sql, SchemaDigest::from_bytes(digest)) 2647 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog)) 2648 }; 2649 Ok([ 2650 metadata_table, 2651 metadata_update, 2652 metadata_delete, 2653 request_table, 2654 request_dedup, 2655 request_update, 2656 request_dedup_update, 2657 object( 2658 SchemaObjectKind::Table, 2659 "connections", 2660 "connections", 2661 CREATE_CONNECTIONS_TABLE_SQL, 2662 CONNECTIONS_TABLE_SHA256, 2663 )?, 2664 object( 2665 SchemaObjectKind::Table, 2666 "connection_permissions", 2667 "connection_permissions", 2668 CREATE_CONNECTION_PERMISSIONS_TABLE_SQL, 2669 CONNECTION_PERMISSIONS_TABLE_SHA256, 2670 )?, 2671 object( 2672 SchemaObjectKind::Table, 2673 "nip46_request_decisions", 2674 "nip46_request_decisions", 2675 CREATE_NIP46_REQUEST_DECISIONS_TABLE_SQL, 2676 NIP46_REQUEST_DECISIONS_TABLE_SHA256, 2677 )?, 2678 object( 2679 SchemaObjectKind::Table, 2680 "connection_auth_challenges", 2681 "connection_auth_challenges", 2682 CREATE_CONNECTION_AUTH_CHALLENGES_TABLE_SQL, 2683 CONNECTION_AUTH_CHALLENGES_TABLE_SHA256, 2684 )?, 2685 object( 2686 SchemaObjectKind::Trigger, 2687 "connections_guard_update", 2688 "connections", 2689 CREATE_CONNECTIONS_GUARD_UPDATE_SQL, 2690 CONNECTIONS_GUARD_UPDATE_SHA256, 2691 )?, 2692 object( 2693 SchemaObjectKind::Trigger, 2694 "connections_no_delete", 2695 "connections", 2696 CREATE_CONNECTIONS_NO_DELETE_SQL, 2697 CONNECTIONS_NO_DELETE_SHA256, 2698 )?, 2699 object( 2700 SchemaObjectKind::Trigger, 2701 "connection_permissions_no_update", 2702 "connection_permissions", 2703 CREATE_CONNECTION_PERMISSIONS_NO_UPDATE_SQL, 2704 CONNECTION_PERMISSIONS_NO_UPDATE_SHA256, 2705 )?, 2706 object( 2707 SchemaObjectKind::Trigger, 2708 "connection_permissions_no_delete", 2709 "connection_permissions", 2710 CREATE_CONNECTION_PERMISSIONS_NO_DELETE_SQL, 2711 CONNECTION_PERMISSIONS_NO_DELETE_SHA256, 2712 )?, 2713 object( 2714 SchemaObjectKind::Trigger, 2715 "nip46_request_decisions_guard_update", 2716 "nip46_request_decisions", 2717 CREATE_NIP46_REQUEST_DECISIONS_GUARD_UPDATE_SQL, 2718 NIP46_REQUEST_DECISIONS_GUARD_UPDATE_SHA256, 2719 )?, 2720 object( 2721 SchemaObjectKind::Trigger, 2722 "nip46_request_decisions_no_delete", 2723 "nip46_request_decisions", 2724 CREATE_NIP46_REQUEST_DECISIONS_NO_DELETE_SQL, 2725 NIP46_REQUEST_DECISIONS_NO_DELETE_SHA256, 2726 )?, 2727 object( 2728 SchemaObjectKind::Trigger, 2729 "connection_auth_challenges_guard_update", 2730 "connection_auth_challenges", 2731 CREATE_CONNECTION_AUTH_CHALLENGES_GUARD_UPDATE_SQL, 2732 CONNECTION_AUTH_CHALLENGES_GUARD_UPDATE_SHA256, 2733 )?, 2734 object( 2735 SchemaObjectKind::Trigger, 2736 "connection_auth_challenges_no_delete", 2737 "connection_auth_challenges", 2738 CREATE_CONNECTION_AUTH_CHALLENGES_NO_DELETE_SQL, 2739 CONNECTION_AUTH_CHALLENGES_NO_DELETE_SHA256, 2740 )?, 2741 ]) 2742 } 2743 2744 fn myc_state_governance_objects() -> Result<Vec<SchemaObject>, MycStateCatalogError> { 2745 let mut objects = Vec::from(myc_state_connection_objects()?); 2746 let object = |kind, name, table, sql, digest| { 2747 SchemaObject::new(kind, name, table, sql, SchemaDigest::from_bytes(digest)) 2748 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog)) 2749 }; 2750 objects.extend([ 2751 object( 2752 SchemaObjectKind::Table, 2753 "myc_audit_state", 2754 "myc_audit_state", 2755 CREATE_MYC_AUDIT_STATE_TABLE_SQL, 2756 MYC_AUDIT_STATE_TABLE_SHA256, 2757 )?, 2758 object( 2759 SchemaObjectKind::Table, 2760 "operation_audit", 2761 "operation_audit", 2762 CREATE_OPERATION_AUDIT_TABLE_SQL, 2763 OPERATION_AUDIT_TABLE_SHA256, 2764 )?, 2765 object( 2766 SchemaObjectKind::Table, 2767 "nip46_request_audit", 2768 "nip46_request_audit", 2769 CREATE_NIP46_REQUEST_AUDIT_TABLE_SQL, 2770 NIP46_REQUEST_AUDIT_TABLE_SHA256, 2771 )?, 2772 object( 2773 SchemaObjectKind::Table, 2774 "connection_rate_windows", 2775 "connection_rate_windows", 2776 CREATE_CONNECTION_RATE_WINDOWS_TABLE_SQL, 2777 CONNECTION_RATE_WINDOWS_TABLE_SHA256, 2778 )?, 2779 object( 2780 SchemaObjectKind::Trigger, 2781 "myc_audit_state_guard_update", 2782 "myc_audit_state", 2783 CREATE_MYC_AUDIT_STATE_GUARD_UPDATE_SQL, 2784 MYC_AUDIT_STATE_GUARD_UPDATE_SHA256, 2785 )?, 2786 object( 2787 SchemaObjectKind::Trigger, 2788 "myc_audit_state_no_delete", 2789 "myc_audit_state", 2790 CREATE_MYC_AUDIT_STATE_NO_DELETE_SQL, 2791 MYC_AUDIT_STATE_NO_DELETE_SHA256, 2792 )?, 2793 object( 2794 SchemaObjectKind::Trigger, 2795 "operation_audit_no_update", 2796 "operation_audit", 2797 CREATE_OPERATION_AUDIT_NO_UPDATE_SQL, 2798 OPERATION_AUDIT_NO_UPDATE_SHA256, 2799 )?, 2800 object( 2801 SchemaObjectKind::Trigger, 2802 "nip46_request_audit_no_update", 2803 "nip46_request_audit", 2804 CREATE_NIP46_REQUEST_AUDIT_NO_UPDATE_SQL, 2805 NIP46_REQUEST_AUDIT_NO_UPDATE_SHA256, 2806 )?, 2807 object( 2808 SchemaObjectKind::Trigger, 2809 "connection_rate_windows_guard_update", 2810 "connection_rate_windows", 2811 CREATE_CONNECTION_RATE_WINDOWS_GUARD_UPDATE_SQL, 2812 CONNECTION_RATE_WINDOWS_GUARD_UPDATE_SHA256, 2813 )?, 2814 ]); 2815 Ok(objects) 2816 } 2817 2818 fn myc_state_delivery_objects() -> Result<Vec<SchemaObject>, MycStateCatalogError> { 2819 let mut objects = myc_state_governance_objects()?; 2820 let object = |kind, name, table, sql, digest| { 2821 SchemaObject::new(kind, name, table, sql, SchemaDigest::from_bytes(digest)) 2822 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog)) 2823 }; 2824 objects.extend([ 2825 object( 2826 SchemaObjectKind::Table, 2827 "publication_outbox", 2828 "publication_outbox", 2829 CREATE_PUBLICATION_OUTBOX_TABLE_SQL, 2830 PUBLICATION_OUTBOX_TABLE_SHA256, 2831 )?, 2832 object( 2833 SchemaObjectKind::Table, 2834 "publication_targets", 2835 "publication_targets", 2836 CREATE_PUBLICATION_TARGETS_TABLE_SQL, 2837 PUBLICATION_TARGETS_TABLE_SHA256, 2838 )?, 2839 object( 2840 SchemaObjectKind::Table, 2841 "publication_attempts", 2842 "publication_attempts", 2843 CREATE_PUBLICATION_ATTEMPTS_TABLE_SQL, 2844 PUBLICATION_ATTEMPTS_TABLE_SHA256, 2845 )?, 2846 object( 2847 SchemaObjectKind::Trigger, 2848 "publication_outbox_guard_update", 2849 "publication_outbox", 2850 CREATE_PUBLICATION_OUTBOX_GUARD_UPDATE_SQL, 2851 PUBLICATION_OUTBOX_GUARD_UPDATE_SHA256, 2852 )?, 2853 object( 2854 SchemaObjectKind::Trigger, 2855 "publication_targets_guard_update", 2856 "publication_targets", 2857 CREATE_PUBLICATION_TARGETS_GUARD_UPDATE_SQL, 2858 PUBLICATION_TARGETS_GUARD_UPDATE_SHA256, 2859 )?, 2860 object( 2861 SchemaObjectKind::Trigger, 2862 "publication_attempts_guard_update", 2863 "publication_attempts", 2864 CREATE_PUBLICATION_ATTEMPTS_GUARD_UPDATE_SQL, 2865 PUBLICATION_ATTEMPTS_GUARD_UPDATE_SHA256, 2866 )?, 2867 object( 2868 SchemaObjectKind::Trigger, 2869 "publication_outbox_no_delete", 2870 "publication_outbox", 2871 CREATE_PUBLICATION_OUTBOX_NO_DELETE_SQL, 2872 PUBLICATION_OUTBOX_NO_DELETE_SHA256, 2873 )?, 2874 object( 2875 SchemaObjectKind::Trigger, 2876 "publication_targets_no_delete", 2877 "publication_targets", 2878 CREATE_PUBLICATION_TARGETS_NO_DELETE_SQL, 2879 PUBLICATION_TARGETS_NO_DELETE_SHA256, 2880 )?, 2881 object( 2882 SchemaObjectKind::Trigger, 2883 "publication_attempts_no_delete", 2884 "publication_attempts", 2885 CREATE_PUBLICATION_ATTEMPTS_NO_DELETE_SQL, 2886 PUBLICATION_ATTEMPTS_NO_DELETE_SHA256, 2887 )?, 2888 ]); 2889 Ok(objects) 2890 } 2891 2892 fn myc_state_discovery_objects() -> Result<Vec<SchemaObject>, MycStateCatalogError> { 2893 let mut objects = myc_state_delivery_objects()?; 2894 objects.retain(|object| { 2895 !matches!( 2896 object.name(), 2897 "publication_outbox" 2898 | "publication_targets" 2899 | "publication_attempts" 2900 | "publication_outbox_guard_update" 2901 | "publication_targets_guard_update" 2902 | "publication_attempts_guard_update" 2903 | "publication_outbox_no_delete" 2904 | "publication_targets_no_delete" 2905 | "publication_attempts_no_delete" 2906 ) 2907 }); 2908 let object = |kind, name, table, sql, digest| { 2909 SchemaObject::new(kind, name, table, sql, SchemaDigest::from_bytes(digest)) 2910 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog)) 2911 }; 2912 objects.extend([ 2913 object( 2914 SchemaObjectKind::Table, 2915 "delivery_jobs", 2916 "delivery_jobs", 2917 CREATE_DELIVERY_JOBS_TABLE_SQL, 2918 DELIVERY_JOBS_TABLE_SHA256, 2919 )?, 2920 object( 2921 SchemaObjectKind::Table, 2922 "delivery_targets", 2923 "delivery_targets", 2924 CREATE_DELIVERY_TARGETS_TABLE_SQL, 2925 DELIVERY_TARGETS_TABLE_SHA256, 2926 )?, 2927 object( 2928 SchemaObjectKind::Table, 2929 "delivery_attempts", 2930 "delivery_attempts", 2931 CREATE_DELIVERY_ATTEMPTS_TABLE_SQL, 2932 DELIVERY_ATTEMPTS_TABLE_SHA256, 2933 )?, 2934 object( 2935 SchemaObjectKind::Trigger, 2936 "delivery_jobs_guard_update", 2937 "delivery_jobs", 2938 CREATE_DELIVERY_JOBS_GUARD_UPDATE_SQL, 2939 DELIVERY_JOBS_GUARD_UPDATE_SHA256, 2940 )?, 2941 object( 2942 SchemaObjectKind::Trigger, 2943 "delivery_targets_guard_update", 2944 "delivery_targets", 2945 CREATE_DELIVERY_TARGETS_GUARD_UPDATE_SQL, 2946 DELIVERY_TARGETS_GUARD_UPDATE_SHA256, 2947 )?, 2948 object( 2949 SchemaObjectKind::Trigger, 2950 "delivery_attempts_guard_update", 2951 "delivery_attempts", 2952 CREATE_DELIVERY_ATTEMPTS_GUARD_UPDATE_SQL, 2953 DELIVERY_ATTEMPTS_GUARD_UPDATE_SHA256, 2954 )?, 2955 object( 2956 SchemaObjectKind::Trigger, 2957 "delivery_jobs_no_delete", 2958 "delivery_jobs", 2959 CREATE_DELIVERY_JOBS_NO_DELETE_SQL, 2960 DELIVERY_JOBS_NO_DELETE_SHA256, 2961 )?, 2962 object( 2963 SchemaObjectKind::Trigger, 2964 "delivery_targets_no_delete", 2965 "delivery_targets", 2966 CREATE_DELIVERY_TARGETS_NO_DELETE_SQL, 2967 DELIVERY_TARGETS_NO_DELETE_SHA256, 2968 )?, 2969 object( 2970 SchemaObjectKind::Trigger, 2971 "delivery_attempts_no_delete", 2972 "delivery_attempts", 2973 CREATE_DELIVERY_ATTEMPTS_NO_DELETE_SQL, 2974 DELIVERY_ATTEMPTS_NO_DELETE_SHA256, 2975 )?, 2976 object( 2977 SchemaObjectKind::Table, 2978 "discovery_desired_state", 2979 "discovery_desired_state", 2980 CREATE_DISCOVERY_DESIRED_STATE_TABLE_SQL, 2981 DISCOVERY_DESIRED_STATE_TABLE_SHA256, 2982 )?, 2983 object( 2984 SchemaObjectKind::Table, 2985 "discovery_documents", 2986 "discovery_documents", 2987 CREATE_DISCOVERY_DOCUMENTS_TABLE_SQL, 2988 DISCOVERY_DOCUMENTS_TABLE_SHA256, 2989 )?, 2990 object( 2991 SchemaObjectKind::Table, 2992 "discovery_publication_state", 2993 "discovery_publication_state", 2994 CREATE_DISCOVERY_PUBLICATION_STATE_TABLE_SQL, 2995 DISCOVERY_PUBLICATION_STATE_TABLE_SHA256, 2996 )?, 2997 object( 2998 SchemaObjectKind::Trigger, 2999 "delivery_jobs_guard_insert", 3000 "delivery_jobs", 3001 CREATE_DELIVERY_JOBS_GUARD_INSERT_SQL, 3002 DELIVERY_JOBS_GUARD_INSERT_SHA256, 3003 )?, 3004 object( 3005 SchemaObjectKind::Trigger, 3006 "discovery_desired_state_no_update", 3007 "discovery_desired_state", 3008 CREATE_DISCOVERY_DESIRED_STATE_NO_UPDATE_SQL, 3009 DISCOVERY_DESIRED_STATE_NO_UPDATE_SHA256, 3010 )?, 3011 object( 3012 SchemaObjectKind::Trigger, 3013 "discovery_desired_state_no_delete", 3014 "discovery_desired_state", 3015 CREATE_DISCOVERY_DESIRED_STATE_NO_DELETE_SQL, 3016 DISCOVERY_DESIRED_STATE_NO_DELETE_SHA256, 3017 )?, 3018 object( 3019 SchemaObjectKind::Trigger, 3020 "discovery_documents_no_update", 3021 "discovery_documents", 3022 CREATE_DISCOVERY_DOCUMENTS_NO_UPDATE_SQL, 3023 DISCOVERY_DOCUMENTS_NO_UPDATE_SHA256, 3024 )?, 3025 object( 3026 SchemaObjectKind::Trigger, 3027 "discovery_documents_no_delete", 3028 "discovery_documents", 3029 CREATE_DISCOVERY_DOCUMENTS_NO_DELETE_SQL, 3030 DISCOVERY_DOCUMENTS_NO_DELETE_SHA256, 3031 )?, 3032 object( 3033 SchemaObjectKind::Trigger, 3034 "discovery_publication_state_guard_update", 3035 "discovery_publication_state", 3036 CREATE_DISCOVERY_PUBLICATION_STATE_GUARD_UPDATE_SQL, 3037 DISCOVERY_PUBLICATION_STATE_GUARD_UPDATE_SHA256, 3038 )?, 3039 object( 3040 SchemaObjectKind::Trigger, 3041 "discovery_publication_state_no_delete", 3042 "discovery_publication_state", 3043 CREATE_DISCOVERY_PUBLICATION_STATE_NO_DELETE_SQL, 3044 DISCOVERY_PUBLICATION_STATE_NO_DELETE_SHA256, 3045 )?, 3046 ]); 3047 Ok(objects) 3048 } 3049 3050 fn myc_state_completion_objects() -> Result<Vec<SchemaObject>, MycStateCatalogError> { 3051 let mut objects = myc_state_discovery_objects()?; 3052 let object = |kind, name, table, sql, digest| { 3053 SchemaObject::new(kind, name, table, sql, SchemaDigest::from_bytes(digest)) 3054 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog)) 3055 }; 3056 objects.extend([ 3057 object( 3058 SchemaObjectKind::Table, 3059 "nip46_operation_commits", 3060 "nip46_operation_commits", 3061 CREATE_NIP46_OPERATION_COMMITS_TABLE_SQL, 3062 NIP46_OPERATION_COMMITS_TABLE_SHA256, 3063 )?, 3064 object( 3065 SchemaObjectKind::Trigger, 3066 "nip46_operation_commits_no_update", 3067 "nip46_operation_commits", 3068 CREATE_NIP46_OPERATION_COMMITS_NO_UPDATE_SQL, 3069 NIP46_OPERATION_COMMITS_NO_UPDATE_SHA256, 3070 )?, 3071 object( 3072 SchemaObjectKind::Trigger, 3073 "nip46_operation_commits_no_delete", 3074 "nip46_operation_commits", 3075 CREATE_NIP46_OPERATION_COMMITS_NO_DELETE_SQL, 3076 NIP46_OPERATION_COMMITS_NO_DELETE_SHA256, 3077 )?, 3078 ]); 3079 Ok(objects) 3080 } 3081 3082 fn myc_state_response_objects() -> Result<Vec<SchemaObject>, MycStateCatalogError> { 3083 let mut objects = myc_state_completion_objects()?; 3084 let object = |kind, name, table, sql, digest| { 3085 SchemaObject::new(kind, name, table, sql, SchemaDigest::from_bytes(digest)) 3086 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog)) 3087 }; 3088 objects.extend([ 3089 object( 3090 SchemaObjectKind::Table, 3091 "nip46_signed_responses", 3092 "nip46_signed_responses", 3093 CREATE_NIP46_SIGNED_RESPONSES_TABLE_SQL, 3094 NIP46_SIGNED_RESPONSES_TABLE_SHA256, 3095 )?, 3096 object( 3097 SchemaObjectKind::Trigger, 3098 "nip46_signed_responses_no_update", 3099 "nip46_signed_responses", 3100 CREATE_NIP46_SIGNED_RESPONSES_NO_UPDATE_SQL, 3101 NIP46_SIGNED_RESPONSES_NO_UPDATE_SHA256, 3102 )?, 3103 object( 3104 SchemaObjectKind::Trigger, 3105 "nip46_signed_responses_no_delete", 3106 "nip46_signed_responses", 3107 CREATE_NIP46_SIGNED_RESPONSES_NO_DELETE_SQL, 3108 NIP46_SIGNED_RESPONSES_NO_DELETE_SHA256, 3109 )?, 3110 ]); 3111 Ok(objects) 3112 } 3113 3114 fn myc_state_config_binding_objects() -> Result<Vec<SchemaObject>, MycStateCatalogError> { 3115 let mut objects = myc_state_response_objects()?; 3116 let object = |kind, name, sql, digest| { 3117 SchemaObject::new( 3118 kind, 3119 name, 3120 "myc_config_bindings", 3121 sql, 3122 SchemaDigest::from_bytes(digest), 3123 ) 3124 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog)) 3125 }; 3126 objects.extend([ 3127 object( 3128 SchemaObjectKind::Table, 3129 "myc_config_bindings", 3130 CREATE_MYC_CONFIG_BINDINGS_TABLE_SQL, 3131 MYC_CONFIG_BINDINGS_TABLE_SHA256, 3132 )?, 3133 object( 3134 SchemaObjectKind::Trigger, 3135 "myc_config_bindings_guard_insert", 3136 CREATE_MYC_CONFIG_BINDINGS_GUARD_INSERT_SQL, 3137 MYC_CONFIG_BINDINGS_GUARD_INSERT_SHA256, 3138 )?, 3139 object( 3140 SchemaObjectKind::Trigger, 3141 "myc_config_bindings_no_update", 3142 CREATE_MYC_CONFIG_BINDINGS_NO_UPDATE_SQL, 3143 MYC_CONFIG_BINDINGS_NO_UPDATE_SHA256, 3144 )?, 3145 object( 3146 SchemaObjectKind::Trigger, 3147 "myc_config_bindings_no_delete", 3148 CREATE_MYC_CONFIG_BINDINGS_NO_DELETE_SQL, 3149 MYC_CONFIG_BINDINGS_NO_DELETE_SHA256, 3150 )?, 3151 ]); 3152 Ok(objects) 3153 } 3154 3155 fn myc_state_admin_operation_objects() -> Result<Vec<SchemaObject>, MycStateCatalogError> { 3156 let mut objects = myc_state_config_binding_objects()?; 3157 let object = |kind, name, sql, digest| { 3158 SchemaObject::new( 3159 kind, 3160 name, 3161 "myc_admin_operations", 3162 sql, 3163 SchemaDigest::from_bytes(digest), 3164 ) 3165 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog)) 3166 }; 3167 objects.extend([ 3168 object( 3169 SchemaObjectKind::Table, 3170 "myc_admin_operations", 3171 CREATE_MYC_ADMIN_OPERATIONS_TABLE_SQL, 3172 MYC_ADMIN_OPERATIONS_TABLE_SHA256, 3173 )?, 3174 object( 3175 SchemaObjectKind::Trigger, 3176 "myc_admin_operations_guard_update", 3177 CREATE_MYC_ADMIN_OPERATIONS_GUARD_UPDATE_SQL, 3178 MYC_ADMIN_OPERATIONS_GUARD_UPDATE_SHA256, 3179 )?, 3180 ]); 3181 Ok(objects) 3182 } 3183 3184 fn myc_state_pending_response_objects() -> Result<Vec<SchemaObject>, MycStateCatalogError> { 3185 let mut objects = myc_state_admin_operation_objects()?; 3186 let object = |kind, name, table, sql, digest| { 3187 SchemaObject::new(kind, name, table, sql, SchemaDigest::from_bytes(digest)) 3188 .map_err(|_| MycStateCatalogError::new(MycStateCatalogErrorKind::SchemaCatalog)) 3189 }; 3190 objects.extend([ 3191 object( 3192 SchemaObjectKind::Table, 3193 "nip46_pending_responses", 3194 "nip46_pending_responses", 3195 CREATE_NIP46_PENDING_RESPONSES_TABLE_SQL, 3196 NIP46_PENDING_RESPONSES_TABLE_SHA256, 3197 )?, 3198 object( 3199 SchemaObjectKind::Trigger, 3200 "nip46_pending_responses_guard_insert", 3201 "nip46_pending_responses", 3202 CREATE_NIP46_PENDING_RESPONSES_GUARD_INSERT_SQL, 3203 NIP46_PENDING_RESPONSES_GUARD_INSERT_SHA256, 3204 )?, 3205 object( 3206 SchemaObjectKind::Trigger, 3207 "nip46_pending_responses_no_delete", 3208 "nip46_pending_responses", 3209 CREATE_NIP46_PENDING_RESPONSES_NO_DELETE_SQL, 3210 NIP46_PENDING_RESPONSES_NO_DELETE_SHA256, 3211 )?, 3212 object( 3213 SchemaObjectKind::Trigger, 3214 "nip46_pending_responses_no_update", 3215 "nip46_pending_responses", 3216 CREATE_NIP46_PENDING_RESPONSES_NO_UPDATE_SQL, 3217 NIP46_PENDING_RESPONSES_NO_UPDATE_SHA256, 3218 )?, 3219 object( 3220 SchemaObjectKind::Trigger, 3221 "nip46_signed_responses_guard_pending_insert", 3222 "nip46_signed_responses", 3223 CREATE_NIP46_SIGNED_RESPONSES_GUARD_PENDING_INSERT_SQL, 3224 NIP46_SIGNED_RESPONSES_GUARD_PENDING_INSERT_SHA256, 3225 )?, 3226 ]); 3227 Ok(objects) 3228 } 3229 3230 /// Independently validates exact catalog versions, counts, and digests. 3231 pub fn validate_myc_state_catalogs( 3232 migrations: &MigrationCatalog, 3233 schema: &SchemaCatalog, 3234 ) -> Result<(), MycStateCatalogError> { 3235 let versions = schema.versions(); 3236 let descriptors = migrations.descriptors(); 3237 let valid = migrations.current_version() == MYC_STATE_SCHEMA_VERSION 3238 && descriptors.len() == 11 3239 && descriptors[0].target_version() == 2 3240 && descriptors[0].name().as_str() == "create_myc_state_metadata" 3241 && descriptors[0].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_2_MIGRATION_SHA256 3242 && descriptors[1].target_version() == 3 3243 && descriptors[1].name().as_str() == "create_nip46_request_admission" 3244 && descriptors[1].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_3_MIGRATION_SHA256 3245 && descriptors[2].target_version() == 4 3246 && descriptors[2].name().as_str() == "create_connection_authorization_state" 3247 && descriptors[2].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_4_MIGRATION_SHA256 3248 && descriptors[3].target_version() == 5 3249 && descriptors[3].name().as_str() == "create_bounded_governance_state" 3250 && descriptors[3].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_5_MIGRATION_SHA256 3251 && descriptors[4].target_version() == 6 3252 && descriptors[4].name().as_str() == "create_delivery_evidence_state" 3253 && descriptors[4].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_6_MIGRATION_SHA256 3254 && descriptors[5].target_version() == 7 3255 && descriptors[5].name().as_str() == "create_discovery_desired_state" 3256 && descriptors[5].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_7_MIGRATION_SHA256 3257 && descriptors[6].target_version() == 8 3258 && descriptors[6].name().as_str() == "create_nip46_operation_completion" 3259 && descriptors[6].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_8_MIGRATION_SHA256 3260 && descriptors[7].target_version() == 9 3261 && descriptors[7].name().as_str() == "create_nip46_atomic_response" 3262 && descriptors[7].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_9_MIGRATION_SHA256 3263 && descriptors[8].target_version() == 10 3264 && descriptors[8].name().as_str() == "create_configuration_binding_history" 3265 && descriptors[8].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_10_MIGRATION_SHA256 3266 && descriptors[9].target_version() == 11 3267 && descriptors[9].name().as_str() == "create_admin_operation_journal" 3268 && descriptors[9].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_11_MIGRATION_SHA256 3269 && descriptors[10].target_version() == 12 3270 && descriptors[10].name().as_str() == "create_nip46_pending_response_authority" 3271 && descriptors[10].checksum().as_bytes() == &MYC_STATE_SCHEMA_VERSION_12_MIGRATION_SHA256 3272 && migrations.digest().as_bytes() == &MYC_MIGRATION_CATALOG_SHA256 3273 && schema.migration_catalog_digest() == migrations.digest() 3274 && versions.len() == 12 3275 && versions[0].version() == MYC_STATE_BASE_SCHEMA_VERSION 3276 && versions[0].object_count() == MYC_STATE_SCHEMA_VERSION_1_OBJECT_COUNT 3277 && versions[0].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_1_SHA256 3278 && versions[1].version() == 2 3279 && versions[1].object_count() == MYC_STATE_SCHEMA_VERSION_2_OBJECT_COUNT 3280 && versions[1].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_2_SHA256 3281 && versions[2].version() == 3 3282 && versions[2].object_count() == MYC_STATE_SCHEMA_VERSION_3_OBJECT_COUNT 3283 && versions[2].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_3_SHA256 3284 && versions[3].version() == 4 3285 && versions[3].object_count() == MYC_STATE_SCHEMA_VERSION_4_OBJECT_COUNT 3286 && versions[3].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_4_SHA256 3287 && versions[4].version() == 5 3288 && versions[4].object_count() == MYC_STATE_SCHEMA_VERSION_5_OBJECT_COUNT 3289 && versions[4].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_5_SHA256 3290 && versions[5].version() == 6 3291 && versions[5].object_count() == MYC_STATE_SCHEMA_VERSION_6_OBJECT_COUNT 3292 && versions[5].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_6_SHA256 3293 && versions[6].version() == 7 3294 && versions[6].object_count() == MYC_STATE_SCHEMA_VERSION_7_OBJECT_COUNT 3295 && versions[6].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_7_SHA256 3296 && versions[7].version() == 8 3297 && versions[7].object_count() == MYC_STATE_SCHEMA_VERSION_8_OBJECT_COUNT 3298 && versions[7].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_8_SHA256 3299 && versions[8].version() == 9 3300 && versions[8].object_count() == MYC_STATE_SCHEMA_VERSION_9_OBJECT_COUNT 3301 && versions[8].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_9_SHA256 3302 && versions[9].version() == 10 3303 && versions[9].object_count() == MYC_STATE_SCHEMA_VERSION_10_OBJECT_COUNT 3304 && versions[9].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_10_SHA256 3305 && versions[10].version() == 11 3306 && versions[10].object_count() == MYC_STATE_SCHEMA_VERSION_11_OBJECT_COUNT 3307 && versions[10].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_11_SHA256 3308 && versions[11].version() == 12 3309 && versions[11].object_count() == MYC_STATE_SCHEMA_VERSION_12_OBJECT_COUNT 3310 && versions[11].digest().as_bytes() == &MYC_STATE_SCHEMA_VERSION_12_SHA256 3311 && schema.digest().as_bytes() == &MYC_STATE_SCHEMA_CATALOG_SHA256; 3312 if valid { 3313 Ok(()) 3314 } else { 3315 Err(MycStateCatalogError::new( 3316 MycStateCatalogErrorKind::CatalogMismatch, 3317 )) 3318 } 3319 }