Skip to content
This repository was archived by the owner on Feb 8, 2025. It is now read-only.

Commit ddfa927

Browse files
committedJul 30, 2024··
fix(api): actviate correct policy state when multiple of the same key are executed at once
1 parent b10d4d9 commit ddfa927

File tree

3 files changed

+19
-11
lines changed

3 files changed

+19
-11
lines changed
 

‎api/src/feat/policies/activate-policy.edgeql

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
with account := (select Account filter .address = <UAddress>$account),
2-
proposal := (select SystemTx filter .hash = <Bytes32>$systxHash).proposal,
32
key := <uint16>$key,
4-
new := assert_single((select PolicyState filter .account = account and .key = key and (.proposal ?= proposal or .initState))),
3+
new := assert_single((
4+
select PolicyState filter .account = account and .key = key and
5+
([is Policy].hash ?= <optional Bytes32>$hash or PolicyState is RemovedPolicy) and
6+
(not exists .activationBlock or .activationBlock ?= 0)
7+
)),
58
old := assert_single((select PolicyState filter .account = account and key = .key and .isLatest and .id != new.id)),
69
activationBlock := <bigint>$activationBlock,
710
isLater := (activationBlock > (old.activationBlock ?? -1n)),

‎api/src/feat/policies/activate-policy.query.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import type {Executor} from "edgedb";
44

55
export type ActivatePolicyArgs = {
66
readonly "account": string;
7-
readonly "systxHash": string;
87
readonly "key": number;
8+
readonly "hash"?: string | null;
99
readonly "activationBlock": bigint;
1010
};
1111

@@ -18,9 +18,12 @@ export type ActivatePolicyReturns = {
1818
export function activatePolicy(client: Executor, args: ActivatePolicyArgs): Promise<ActivatePolicyReturns> {
1919
return client.queryRequiredSingle(`\
2020
with account := (select Account filter .address = <UAddress>$account),
21-
proposal := (select SystemTx filter .hash = <Bytes32>$systxHash).proposal,
2221
key := <uint16>$key,
23-
new := assert_single((select PolicyState filter .account = account and .key = key and (.proposal ?= proposal or .initState))),
22+
new := assert_single((
23+
select PolicyState filter .account = account and .key = key and
24+
([is Policy].hash ?= <optional Bytes32>$hash or PolicyState is RemovedPolicy) and
25+
(not exists .activationBlock or .activationBlock ?= 0)
26+
)),
2427
old := assert_single((select PolicyState filter .account = account and key = .key and .isLatest and .id != new.id)),
2528
activationBlock := <bigint>$activationBlock,
2629
isLater := (activationBlock > (old.activationBlock ?? -1n)),

‎api/src/feat/policies/policies.events.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable } from '@nestjs/common';
22
import { EventsWorker, EventData, Log } from '../events/events.worker';
3-
import { ACCOUNT_ABI, PolicyKey, asPolicyKey, asUAddress, asUUID } from 'lib';
3+
import { ACCOUNT_ABI, Hex, PolicyKey, asPolicyKey, asUAddress, asUUID } from 'lib';
44
import { Chain } from 'chains';
55
import { DatabaseService } from '~/core/database';
66
import { getAbiItem } from 'viem';
@@ -29,6 +29,7 @@ export class PoliciesEventsProcessor {
2929
chain,
3030
log,
3131
asPolicyKey(log.args.key),
32+
log.args.hash,
3233
);
3334

3435
if (policyId)
@@ -46,20 +47,21 @@ export class PoliciesEventsProcessor {
4647
this.policies.event({ event: PolicyEvent.removed, account, policyId: asUUID(policyId) });
4748
}
4849

49-
private async markStateAsActive(chain: Chain, log: Log, key: PolicyKey) {
50-
// FIXME: when multiple policies are activated in one block, the wrong one may be marked as active
51-
// This *always* occurs when a policy is activated by a policy update transaction
52-
50+
private async markStateAsActive(chain: Chain, log: Log, key: PolicyKey, hash?: Hex) {
5351
const account = asUAddress(log.address, chain);
5452
const r = await this.db.exec(activatePolicy, {
5553
account,
5654
key,
57-
systxHash: log.transactionHash,
55+
hash,
5856
activationBlock: log.blockNumber,
5957
});
6058

6159
await Promise.all(r.pendingTransactions.map((id) => this.transactions.tryExecute(asUUID(id))));
6260

61+
if (!r.new) {
62+
// TODO: this shouldn't happen
63+
}
64+
6365
return { account, old: r.old, new: r.new };
6466
}
6567
}

0 commit comments

Comments
 (0)
This repository has been archived.