Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 9 additions & 44 deletions packages/agent/src/curator-meta-refresh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
import { randomUUID } from 'node:crypto';
import { multiaddr } from '@multiformats/multiaddr';
import {
assertSafeIri,
contextGraphDataGraphUri,
contextGraphMetaGraphUri,
createOperationContext,
DKG_ONTOLOGY,
type OperationContext,
} from '@origintrail-official/dkg-core';
import {
tryUpdateWithTouchedGraphs,
tryReplaceProjectionFromGraphAtomically,
type Quad,
type TripleStore,
} from '@origintrail-official/dkg-storage';
Expand Down Expand Up @@ -415,45 +414,6 @@ async function fetchAuthoritativeMetaSnapshot(
return { checkpointKey: result.checkpointKey, quads: controlMetaQuads };
}

/**
* Replace only the curator-replicated portion of a CG's root `_meta` graph.
* `dkg:revokedAgent` is deliberately retained as a node-local tombstone.
*/
function replaceCuratorMetaProjectionSparql(
contextGraphId: string,
metaGraph: string,
stagingGraph: string,
): string {
const contextGraphUri = assertSafeIri(contextGraphDataGraphUri(contextGraphId));
const delegationPrefix = `did:dkg:agent-delegation:${contextGraphId}:`;
assertSafeIri(metaGraph);
assertSafeIri(stagingGraph);
return `DELETE {
GRAPH <${metaGraph}> { ?staleSubject ?stalePredicate ?staleObject . }
}
INSERT {
GRAPH <${metaGraph}> { ?freshSubject ?freshPredicate ?freshObject . }
}
WHERE {
{
GRAPH <${metaGraph}> {
?staleSubject ?stalePredicate ?staleObject .
FILTER (
(
?staleSubject = <${contextGraphUri}> &&
?stalePredicate != <${DKG_ONTOLOGY.DKG_REVOKED_AGENT}>
) ||
STRSTARTS(STR(?staleSubject), ${JSON.stringify(delegationPrefix)})
)
}
}
UNION
{
GRAPH <${stagingGraph}> { ?freshSubject ?freshPredicate ?freshObject . }
}
}`;
}

async function atomicallyReplaceCuratorMetaSnapshot(
agent: CuratorMetaRefreshAgent,
contextGraphId: string,
Expand Down Expand Up @@ -488,10 +448,15 @@ async function atomicallyReplaceCuratorMetaSnapshot(
invalidateTargetProjections();
let replaced = false;
try {
replaced = await tryUpdateWithTouchedGraphs(
replaced = await tryReplaceProjectionFromGraphAtomically(
agent.store,
replaceCuratorMetaProjectionSparql(contextGraphId, metaGraph, stagingGraph),
[metaGraph],
{
targetGraphUri: metaGraph,
stagingGraphUri: stagingGraph,
targetSubject: contextGraphDataGraphUri(contextGraphId),
preservedTargetPredicates: [DKG_ONTOLOGY.DKG_REVOKED_AGENT],
targetSubjectPrefixes: [`did:dkg:agent-delegation:${contextGraphId}:`],
},
{ source: 'agent.metaRefresh.replace' },
);
} finally {
Expand Down
15 changes: 14 additions & 1 deletion packages/agent/src/dkg-agent-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ import {
pickNetworkTunables,
isSparqlUpdateOperation,
} from '@origintrail-official/dkg-core';
import { GraphManager, PrivateContentStore, SystemRecordLaneForwarderV1, createTripleStore, isExternalBackend, type TripleStore, type TripleStoreConfig, type Quad, type LargeLiteralStorageConfig, type QueryOptions } from '@origintrail-official/dkg-storage';
import { GraphManager, PrivateContentStore, SystemRecordLaneForwarderV1, createTripleStore, isExternalBackend, structuredMutationMightMutate, structuredMutationTouchedGraphs, type TripleStore, type TripleStoreConfig, type Quad, type LargeLiteralStorageConfig, type QueryOptions } from '@origintrail-official/dkg-storage';
import { emptyRpcUsageWindow, EVMChainAdapter, NoChainAdapter, enrichEvmError, buildKnowledgeAssetUal, type EVMAdapterConfig, type ChainAdapter, type CreateContextGraphParams, type CreateOnChainContextGraphParams, type CreateOnChainContextGraphResult, type TxResult, type V10PublishingConvictionAccountInfo, type RpcUsageWindow } from '@origintrail-official/dkg-chain';
import {
DKGPublisher, PublishHandler, SharedMemoryHandler, UpdateHandler, ChainEventPoller, AccessHandler, AccessClient,
Expand Down Expand Up @@ -576,6 +576,19 @@ export function createListContextGraphsCacheInvalidatingStore(
() => markProjectionDirty?.(undefined, graphUri),
)
: undefined,
structuredMutation: innerStore.structuredMutation
? (mutation, options) => {
// Capture scope before the first await so caller-side mutation cannot
// redirect cache invalidation after the backend has committed.
const targetGraphs = [...structuredMutationTouchedGraphs(mutation)];
Comment thread
Jurij89 marked this conversation as resolved.
const mightMutate = structuredMutationMightMutate(mutation);
return invalidateAfterMutation(
() => innerStore.structuredMutation!(mutation, options),
() => mightMutate,
() => targetGraphs.forEach((graph) => markProjectionDirty?.(undefined, graph)),
);
}
: undefined,
listGraphs(options) {
return innerStore.listGraphs(options);
},
Expand Down
28 changes: 6 additions & 22 deletions packages/agent/src/dkg-agent-cg-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ import {
pickNetworkTunables,
assertRdfLiteralMutf8Safe,
} from '@origintrail-official/dkg-core';
import { GraphManager, PrivateContentStore, createTripleStore, tryUpdateWithTouchedGraphs, type TripleStore, type TripleStoreConfig, type Quad, type LargeLiteralStorageConfig } from '@origintrail-official/dkg-storage';
import { GraphManager, PrivateContentStore, createTripleStore, type TripleStore, type TripleStoreConfig, type Quad, type LargeLiteralStorageConfig } from '@origintrail-official/dkg-storage';
import { EVMChainAdapter, NoChainAdapter, enrichEvmError, buildKnowledgeAssetUal, type EVMAdapterConfig, type ChainAdapter, type CreateContextGraphParams, type CreateOnChainContextGraphParams, type CreateOnChainContextGraphResult, type TxResult, type V10PublishingConvictionAccountInfo } from '@origintrail-official/dkg-chain';
import {
DKGPublisher, PublishHandler, SharedMemoryHandler, UpdateHandler, ChainEventPoller, AccessHandler, AccessClient,
Expand Down Expand Up @@ -955,28 +955,12 @@ export class ContextGraphRegistryMethods extends DKGAgentBase {

const gm = new GraphManager(this.store);

const { subGraphDeregistrationSparql } = await import('@origintrail-official/dkg-publisher');
const metaGraph = `did:dkg:context-graph:${contextGraphId}/_meta`;
try {
const sparql = subGraphDeregistrationSparql(contextGraphId, subGraphName);
const updated = await tryUpdateWithTouchedGraphs(
this.store,
sparql,
[metaGraph],
{
source: 'agent.cg.removeSubGraph.registration',
},
);
if (!updated) {
await this.store.query(sparql, {
source: 'agent.cg.removeSubGraph.registrationFallback',
});
}
} catch {
// SPARQL DELETE WHERE may not be supported — delete quads manually
const subGraphUri = `did:dkg:context-graph:${contextGraphId}/${subGraphName}`;
await this.store.deleteByPattern({ graph: metaGraph, subject: subGraphUri });
}
const subGraphUri = `did:dkg:context-graph:${contextGraphId}/${subGraphName}`;
await this.store.deleteByPattern(
{ graph: metaGraph, subject: subGraphUri },
{ source: 'agent.cg.removeSubGraph.registration' },
);

const dataUri = gm.subGraphUri(contextGraphId, subGraphName);
const metaUri = gm.subGraphMetaUri(contextGraphId, subGraphName);
Expand Down
Loading
Loading