Skip to content

Commit e6d7492

Browse files
fix two way link removal processing. (#829)
* fix two way link removal processing. * fix resolving two way link if target end doesnt exist. Previously it was marked as valid two way link * changelog entry for bug fixes.
1 parent 6386114 commit e6d7492

File tree

3 files changed

+45
-36
lines changed

3 files changed

+45
-36
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
## 1.10.0
22
Release built: _not released yet_
33

4+
### Bug fixes
5+
- Fixed two bugs in two-way links returned from `/state/entity/details`:
6+
- If one end of the link pointed to an entity without a corresponding metadata key, it was incorrectly considered a valid two-way link.
7+
- Fixed invalidation after removing a metadata entry on one end. Previously, the link was still considered valid even after the metadata entry was removed.
8+
49
### API Changes
510
- New filters are supported on the `/stream/transactions` endpoint:
611
- `transaction_status_filter` - Allows filtering by the transaction commit status (`Success`, `Failure`, `All`). Defaults to `All`.
@@ -36,7 +41,6 @@ Release built: _not released yet_
3641
- Added a new configuration parameter, `GatewayApi__Endpoint__EntitiesByRoleRequirementLookupMaxRequestedRequirementsCount`, which sets the limit (default `50`) on the number of requirements that can be queried using the `/extensions/entities-by-role-requirement/lookup` endpoint.
3742
- Added a new configuration parameter, `GatewayApi__Endpoint__ImplicitRequirementsLookupMaxRequestedRequirementsCount`, which sets the limit (default `100`) on the number of implicit requirements that can be queried using the `/extensions/implicit-requirements/lookup` endpoint.
3843

39-
4044
## 1.9.2
4145
Release built: 9.12.2024
4246

src/RadixDlt.NetworkGateway.PostgresIntegration/LedgerExtension/Processors/StandardMetadataProcessor.cs

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -99,35 +99,28 @@ public StandardMetadataProcessor(ProcessorContext context, ReferencedEntityDicti
9999

100100
public void VisitUpsert(CoreModel.IUpsertedSubstate substate, ReferencedEntity referencedEntity, long stateVersion)
101101
{
102-
var substateData = substate.Value.SubstateData;
103-
104-
if (substateData is not CoreModel.MetadataModuleEntrySubstate metadataEntry)
105-
{
106-
return;
107-
}
108-
109-
bool TryParseValue<T>([NotNullWhen(true)] out T? value)
102+
T? ParseMetadataValue<T>(CoreModel.MetadataModuleEntrySubstate metadataSubstate)
110103
where T : GatewayModel.MetadataTypedValue
111104
{
112-
var parsed = metadataEntry.Value == null
105+
var parsed = metadataSubstate.Value == null
113106
? null
114-
: ScryptoSborUtils.DecodeToGatewayMetadataItemValue(metadataEntry.Value.DataStruct.StructData.GetDataBytes(), _context.NetworkConfiguration.Id);
107+
: ScryptoSborUtils.DecodeToGatewayMetadataItemValue(metadataSubstate.Value.DataStruct.StructData.GetDataBytes(), _context.NetworkConfiguration.Id);
115108

116-
if (parsed is T typed)
117-
{
118-
value = typed;
119-
return true;
120-
}
109+
return parsed as T;
110+
}
111+
112+
var substateData = substate.Value.SubstateData;
121113

122-
value = default;
123-
return false;
114+
if (substateData is not CoreModel.MetadataModuleEntrySubstate metadataEntry)
115+
{
116+
return;
124117
}
125118

126119
var key = metadataEntry.Key.Name;
127120

128121
if (referencedEntity.Address.IsAccount)
129122
{
130-
if (key == StandardMetadataConstants.DappAccountType && TryParseValue<GatewayModel.MetadataStringValue>(out var accountType))
123+
if (key == StandardMetadataConstants.DappAccountType)
131124
{
132125
_entriesToAdd.Add(
133126
new DappAccountTypeUnverifiedStandardMetadataEntryHistory
@@ -137,10 +130,10 @@ bool TryParseValue<T>([NotNullWhen(true)] out T? value)
137130
EntityId = referencedEntity.DatabaseId,
138131
IsDeleted = metadataEntry.Value == null,
139132
IsLocked = substateData.IsLocked,
140-
Value = accountType.Value,
133+
Value = ParseMetadataValue<GatewayModel.MetadataStringValue>(metadataEntry)?.Value,
141134
});
142135
}
143-
else if (key == StandardMetadataConstants.DappClaimedWebsites && TryParseValue<GatewayModel.MetadataOriginArrayValue>(out var claimedWebsites))
136+
else if (key == StandardMetadataConstants.DappClaimedWebsites)
144137
{
145138
_entriesToAdd.Add(
146139
new DappClaimedWebsitesUnverifiedStandardMetadataEntryHistory
@@ -150,10 +143,10 @@ bool TryParseValue<T>([NotNullWhen(true)] out T? value)
150143
EntityId = referencedEntity.DatabaseId,
151144
IsDeleted = metadataEntry.Value == null,
152145
IsLocked = substateData.IsLocked,
153-
ClaimedWebsites = claimedWebsites.Values.ToArray(),
146+
ClaimedWebsites = ParseMetadataValue<GatewayModel.MetadataOriginArrayValue>(metadataEntry)?.Values.ToArray(),
154147
});
155148
}
156-
else if (key == StandardMetadataConstants.DappClaimedEntities && TryParseValue<GatewayModel.MetadataGlobalAddressArrayValue>(out var claimedEntities))
149+
else if (key == StandardMetadataConstants.DappClaimedEntities)
157150
{
158151
_entriesToAdd.Add(
159152
new DappClaimedEntitiesUnverifiedStandardMetadataEntryHistory
@@ -163,10 +156,13 @@ bool TryParseValue<T>([NotNullWhen(true)] out T? value)
163156
EntityId = referencedEntity.DatabaseId,
164157
IsDeleted = metadataEntry.Value == null,
165158
IsLocked = substateData.IsLocked,
166-
ClaimedEntityIds = claimedEntities.Values.Select(address => _referencedEntities.Get((EntityAddress)address).DatabaseId).ToArray(),
159+
ClaimedEntityIds = ParseMetadataValue<GatewayModel.MetadataGlobalAddressArrayValue>(metadataEntry)
160+
?.Values
161+
.Select(address => _referencedEntities.Get((EntityAddress)address).DatabaseId)
162+
.ToArray(),
167163
});
168164
}
169-
else if (key == StandardMetadataConstants.DappDefinitions && TryParseValue<GatewayModel.MetadataGlobalAddressArrayValue>(out var dappDefinitions))
165+
else if (key == StandardMetadataConstants.DappDefinitions)
170166
{
171167
_entriesToAdd.Add(
172168
new DappDefinitionsUnverifiedStandardMetadataEntryHistory
@@ -176,11 +172,16 @@ bool TryParseValue<T>([NotNullWhen(true)] out T? value)
176172
EntityId = referencedEntity.DatabaseId,
177173
IsDeleted = metadataEntry.Value == null,
178174
IsLocked = substateData.IsLocked,
179-
DappDefinitionEntityIds = dappDefinitions.Values.Select(address => _referencedEntities.Get((EntityAddress)address).DatabaseId).ToArray(),
175+
DappDefinitionEntityIds = ParseMetadataValue<GatewayModel.MetadataGlobalAddressArrayValue>(metadataEntry)
176+
?.Values
177+
.Select(address => _referencedEntities.Get((EntityAddress)address).DatabaseId)
178+
.ToArray(),
180179
});
181180
}
182-
else if (key == StandardMetadataConstants.DappAccountLocker && TryParseValue<GatewayModel.MetadataGlobalAddressValue>(out var dappAccountLocker))
181+
else if (key == StandardMetadataConstants.DappAccountLocker)
183182
{
183+
var parsedValue = ParseMetadataValue<GatewayModel.MetadataGlobalAddressValue>(metadataEntry);
184+
184185
_entriesToAdd.Add(
185186
new DappAccountLockerUnverifiedStandardMetadataEntryHistory
186187
{
@@ -189,13 +190,13 @@ bool TryParseValue<T>([NotNullWhen(true)] out T? value)
189190
EntityId = referencedEntity.DatabaseId,
190191
IsDeleted = metadataEntry.Value == null,
191192
IsLocked = substateData.IsLocked,
192-
AccountLockerEntityId = _referencedEntities.Get((EntityAddress)dappAccountLocker.Value).DatabaseId,
193+
AccountLockerEntityId = parsedValue != null ? _referencedEntities.Get((EntityAddress)parsedValue.Value).DatabaseId : null,
193194
});
194195
}
195196
}
196197
else if (referencedEntity.Address.IsResource)
197198
{
198-
if (key == StandardMetadataConstants.DappDefinitions && TryParseValue<GatewayModel.MetadataGlobalAddressArrayValue>(out var dappDefinitions))
199+
if (key == StandardMetadataConstants.DappDefinitions)
199200
{
200201
_entriesToAdd.Add(
201202
new DappDefinitionsUnverifiedStandardMetadataEntryHistory
@@ -205,14 +206,18 @@ bool TryParseValue<T>([NotNullWhen(true)] out T? value)
205206
EntityId = referencedEntity.DatabaseId,
206207
IsDeleted = metadataEntry.Value == null,
207208
IsLocked = substateData.IsLocked,
208-
DappDefinitionEntityIds = dappDefinitions.Values.Select(address => _referencedEntities.Get((EntityAddress)address).DatabaseId).ToArray(),
209+
DappDefinitionEntityIds = ParseMetadataValue<GatewayModel.MetadataGlobalAddressArrayValue>(metadataEntry)
210+
?.Values
211+
.Select(address => _referencedEntities.Get((EntityAddress)address).DatabaseId)
212+
.ToArray(),
209213
});
210214
}
211215
}
212216
else if (referencedEntity.Address.IsGlobal)
213217
{
214-
if (key == StandardMetadataConstants.DappDefinition && TryParseValue<GatewayModel.MetadataGlobalAddressValue>(out var dappDefinition))
218+
if (key == StandardMetadataConstants.DappDefinition)
215219
{
220+
var parsedValue = ParseMetadataValue<GatewayModel.MetadataGlobalAddressValue>(metadataEntry);
216221
_entriesToAdd.Add(
217222
new DappDefinitionUnverifiedStandardMetadataEntryHistory
218223
{
@@ -221,7 +226,7 @@ bool TryParseValue<T>([NotNullWhen(true)] out T? value)
221226
EntityId = referencedEntity.DatabaseId,
222227
IsDeleted = metadataEntry.Value == null,
223228
IsLocked = substateData.IsLocked,
224-
DappDefinitionEntityId = _referencedEntities.Get((EntityAddress)dappDefinition.Value).DatabaseId,
229+
DappDefinitionEntityId = parsedValue != null ? _referencedEntities.Get((EntityAddress)parsedValue.Value).DatabaseId : null,
225230
});
226231
}
227232
}

src/RadixDlt.NetworkGateway.PostgresIntegration/Services/StandardMetadataResolver.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,9 @@ candidates AS (
164164
target_entity.id AS target_entity_id,
165165
target_entity.address AS target_entity_address,
166166
target_entity.discriminator AS target_entity_discriminator,
167-
dapp_marker_check.valid AS dapp_marker_check_valid,
168-
target_dapp_marker_check.valid AS target_dapp_marker_check_valid,
169-
target_entity_check.valid AS target_entity_check_valid
167+
COALESCE(dapp_marker_check.valid, FALSE) AS dapp_marker_check_valid,
168+
COALESCE(target_dapp_marker_check.valid, FALSE) AS target_dapp_marker_check_valid,
169+
COALESCE(target_entity_check.valid, FALSE) AS target_entity_check_valid
170170
FROM entry_history_expanded entry
171171
INNER JOIN entities source_entity ON source_entity.id = entry.entity_id
172172
LEFT JOIN entities target_entity ON target_entity.id = entry.target_entity_id
@@ -229,7 +229,7 @@ resolved AS (
229229
-- 'on-app-check' - on-ledger, partially validated,
230230
-- 'off-app-check' - off-ledger, partially validated,
231231
-- <non-null string value> - validation failure
232-
coalesce(CASE c.discriminator
232+
COALESCE(CASE c.discriminator
233233
WHEN 'dapp_account_type' THEN
234234
CASE FALSE
235235
WHEN source_discriminator = 'global_account_component' THEN 'account expected'

0 commit comments

Comments
 (0)