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

Commit 9c9bee2

Browse files
authored
Merge pull request #276 from zallo-labs/Z-314-impr-account-creation
Z 314 impr account creation
2 parents b29798f + 8363533 commit 9c9bee2

40 files changed

+765
-693
lines changed
Binary file not shown.

api/dbschema/bootstrap.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ configure instance set query_work_mem := <cfg::memory>"8MiB";
1212
configure instance set shared_buffers := <cfg::memory>"2GiB";
1313

1414
# Total memory available to the database for caching - 75%
15-
configure instance set effective_cache_size := <cfg::memory>"3GiB";
15+
configure instance set effective_cache_size := <cfg::memory>"6GiB";

api/dbschema/edgeql-js/__spec__.ts

+71-71
Large diffs are not rendered by default.

api/dbschema/edgeql-js/modules/cfg.ts

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export type $AbstractConfigλShape = $.typeutil.flatten<$ConfigObjectλShape & {
6262
"default_statistics_target": $.PropertyDesc<_std.$int64, $.Cardinality.AtMostOne, false, false, false, false>;
6363
"force_database_error": $.PropertyDesc<_std.$str, $.Cardinality.AtMostOne, false, false, false, true>;
6464
"_pg_prepared_statement_cache_size": $.PropertyDesc<_std.$int16, $.Cardinality.One, false, false, false, true>;
65+
"auto_rebuild_query_cache_timeout": $.PropertyDesc<_std.$duration, $.Cardinality.AtMostOne, false, false, false, true>;
6566
"<cfg[is cfg::ExtensionConfig]": $.LinkDesc<$ExtensionConfig, $.Cardinality.AtMostOne, {}, true, false, false, false>;
6667
"<cfg": $.LinkDesc<$.ObjectType, $.Cardinality.Many, {}, false, false, false, false>;
6768
}>;

api/dbschema/edgeql-js/modules/default.ts

+75-75
Large diffs are not rendered by default.

api/dbschema/interfaces.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export namespace cfg {
3838
"default_statistics_target"?: number | null;
3939
"force_database_error"?: string | null;
4040
"_pg_prepared_statement_cache_size": number;
41+
"auto_rebuild_query_cache_timeout"?: edgedb.Duration | null;
4142
}
4243
export type AllowBareDDL = "AlwaysAllow" | "NeverAllow";
4344
export interface Auth extends ConfigObject {
@@ -215,9 +216,9 @@ export namespace $default {
215216
"proposal"?: Transaction | null;
216217
"initState": boolean;
217218
"isActive": boolean;
218-
"isDraft": boolean;
219219
"latest"?: PolicyState | null;
220220
"isLatest": boolean;
221+
"isDraft": boolean;
221222
}
222223
export interface Policy extends PolicyState {
223224
"approvers": Approver[];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CREATE MIGRATION m1ob6arfwyamzcpgk2hgzhby3iwv3moewthqacorsw2mtyjkopdoaq
2+
ONTO m13qxppnkqofigih7dxkipm2lh6k3ahrqerachqhdzihw76nb6i3aa
3+
{
4+
ALTER TYPE default::PolicyState {
5+
ALTER PROPERTY isDraft {
6+
USING ((__source__ ?= .draft));
7+
};
8+
};
9+
};

api/dbschema/policy.esdl

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module default {
1919
required initState := .activationBlock ?= 0;
2020
required hasBeenActive := exists .activationBlock;
2121
required isActive := .isLatest and .hasBeenActive;
22-
required isDraft := exists .draft;
22+
required isDraft := (__source__ ?= .draft);
2323
latest := (__source__ if .isLatest else latestPolicy(.account, .key));
2424
draft := assert_single((
2525
with account := __source__.account, key := __source__.key
@@ -94,9 +94,9 @@ module default {
9494
}
9595

9696
type TransfersConfig {
97-
multi limits: TransferLimit { constraint exclusive; }
9897
required defaultAllow: bool { default := true; };
9998
required budget: uint32;
99+
multi limits: TransferLimit { constraint exclusive; }
100100
}
101101

102102
type TransferLimit {

api/edgedb.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[edgedb]
2-
server-version = "5.4"
2+
server-version = "5.6"

api/schema.graphql

+11-36
Original file line numberDiff line numberDiff line change
@@ -207,22 +207,6 @@ input CreateAccountInput {
207207
salt: Bytes32
208208
}
209209

210-
input CreatePolicyInput {
211-
account: UAddress!
212-
actions: [ActionInput!]
213-
allowMessages: Boolean
214-
approvers: [Address!]
215-
216-
"""seconds"""
217-
delay: Float
218-
key: PolicyKey
219-
name: String
220-
threshold: Float
221-
transfers: TransfersConfigInput
222-
}
223-
224-
union CreatePolicyResponse = NameTaken | Policy
225-
226210
interface CustomNode {
227211
id: ID!
228212
}
@@ -342,12 +326,12 @@ type Mutation {
342326
approveMessage(input: ApproveInput!): Message!
343327
approveTransaction(input: ApproveInput!): Transaction!
344328
createAccount(input: CreateAccountInput!): Account!
345-
createPolicy(input: CreatePolicyInput!): CreatePolicyResponse!
346329
deleteContact(address: UAddress!): ID
347330
execute(input: ExecuteTransactionInput!): Transaction
348331
link(input: LinkInput!): User!
349332
proposeCancelScheduledTransaction(input: ProposeCancelScheduledTransactionInput!): Transaction!
350333
proposeMessage(input: ProposeMessageInput!): Message!
334+
proposePolicies(input: ProposePoliciesInput!): [Policy!]!
351335
proposeTransaction(input: ProposeTransactionInput!): Transaction!
352336
rejectProposal(input: UniqueProposalInput!): Proposal!
353337
removeMessage(input: UniqueProposalInput!): ID!
@@ -357,8 +341,7 @@ type Mutation {
357341
requestTokens(input: RequestTokensInput!): [Address!]!
358342
updateAccount(input: UpdateAccountInput!): Account!
359343
updateApprover(input: UpdateApproverInput!): Approver!
360-
updatePolicies(input: UpdatePoliciesInput!): [Policy!]!
361-
updatePolicy(input: UpdatePolicyInput!): UpdatePolicyResponse!
344+
updatePolicyDetails(input: UpdatePolicyDetailsInput!): UpdatePolicyDetailsResponse
362345
updateProposal(input: UpdateProposalInput!): Proposal!
363346
updateTransaction(input: UpdateTransactionInput!): Transaction!
364347
updateUser(input: UpdateUserInput!): User!
@@ -575,6 +558,11 @@ input ProposeMessageInput {
575558
typedData: TypedData
576559
}
577560

561+
input ProposePoliciesInput {
562+
account: UAddress!
563+
policies: [PolicyInput!]!
564+
}
565+
578566
input ProposeTransactionInput {
579567
account: UAddress!
580568
dapp: DappMetadataInput
@@ -1053,24 +1041,13 @@ input UpdateApproverInput {
10531041
pushToken: String
10541042
}
10551043

1056-
input UpdatePoliciesInput {
1044+
input UpdatePolicyDetailsInput {
10571045
account: UAddress!
1058-
policies: [UpdatePolicyInput!]!
1046+
key: PolicyKey!
1047+
name: String!
10591048
}
10601049

1061-
input UpdatePolicyInput {
1062-
account: UAddress!
1063-
actions: [ActionInput!]
1064-
allowMessages: Boolean
1065-
approvers: [Address!]
1066-
1067-
"""seconds"""
1068-
delay: Float
1069-
key: PolicyKey
1070-
name: String
1071-
threshold: Float
1072-
transfers: TransfersConfigInput
1073-
}
1050+
union UpdatePolicyDetailsResponse = NameTaken | Policy
10741051

10751052
type UpdatePolicyOp {
10761053
_args: [JSON!]!
@@ -1081,8 +1058,6 @@ type UpdatePolicyOp {
10811058
threshold: Float!
10821059
}
10831060

1084-
union UpdatePolicyResponse = NameTaken | Policy
1085-
10861061
input UpdateProposalInput {
10871062
id: ID!
10881063
policy: PolicyKey

api/src/core/database/database.service.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ export class DatabaseService implements OnModuleInit {
5151
return reqCtx.db;
5252
}
5353

54-
private async run<R>(p: Promise<R>, name = 'inline'): Promise<R> {
54+
private async run<R>(f: () => Promise<R>, name = 'inline'): Promise<R> {
5555
return Sentry.startSpan({ op: 'db.query', name }, async () => {
5656
try {
57-
return await p;
57+
return await f();
5858
} catch (e) {
5959
if (e instanceof EdgeDBError && e['_query']) Sentry.setExtra('EdgeQL', e['_query']);
6060
throw e;
@@ -63,7 +63,7 @@ export class DatabaseService implements OnModuleInit {
6363
}
6464

6565
async query<Expr extends Expression>(expression: Expr): Promise<$infer<Expr>> {
66-
return this.run(expression.run(this.client));
66+
return this.run(() => expression.run(this.client));
6767
}
6868

6969
async queryWith<
@@ -75,7 +75,7 @@ export class DatabaseService implements OnModuleInit {
7575
params: paramsToParamArgs<Params>,
7676
) {
7777
const expression = e.params(paramsDef, getExpr as any);
78-
return this.run(expression.run(this.client, params as any)) as Promise<$infer<Expr>>;
78+
return this.run(() => expression.run(this.client, params as any)) as Promise<$infer<Expr>>;
7979
}
8080

8181
async queryWith2<
@@ -87,14 +87,14 @@ export class DatabaseService implements OnModuleInit {
8787
getExpr: (params: paramsToParamExprs<Params>) => Expr,
8888
) {
8989
const expression = e.params(paramsDef, getExpr as any);
90-
return this.run(expression.run(this.client, params as any)) as Promise<$infer<Expr>>;
90+
return this.run(() => expression.run(this.client, params as any)) as Promise<$infer<Expr>>;
9191
}
9292

9393
async exec<F extends (client: Executor, args: any) => Promise<any>>(
9494
f: F,
9595
args: Parameters<F>[1],
9696
): Promise<Awaited<ReturnType<F>>> {
97-
return this.run(f(this.client, args), f.name);
97+
return this.run(() => f(this.client, args), f.name);
9898
}
9999

100100
async transaction<T>(action: (transaction: Transaction) => Promise<T>): Promise<T> {

api/src/core/networks/networks.worker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class NetworkWorker extends Worker<NetworkQueue> {
3939
if (runningJobs.find((j) => j.data.chain === network.chain.key)) continue;
4040

4141
const chain = network.chain.key;
42-
this.queue.add(chain, { chain }, { repeat: { every: 30_000 /* ms */ }, ...NON_RETRYING_JOB });
42+
this.queue.add(chain, { chain }, { repeat: { every: 2_000 /* ms */ }, ...NON_RETRYING_JOB });
4343
}
4444
}
4545
}

api/src/feat/accounts/accounts.service.ts

+32-14
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
ACCOUNT_IMPLEMENTATION,
1212
DEPLOYER,
1313
asUAddress,
14+
PLACEHOLDER_ACCOUNT_ADDRESS,
1415
} from 'lib';
1516
import { ShapeFunc } from '~/core/database';
1617
import {
@@ -30,6 +31,7 @@ import { AccountsCacheService } from '../auth/accounts.cache.service';
3031
import { v4 as uuid } from 'uuid';
3132
import { selectAccount2 } from './accounts.util';
3233
import { AccountEvent } from './accounts.model';
34+
import { PolicyInput } from '../policies/policies.input';
3335

3436
const accountTrigger = (account: UAddress) => `account.updated:${account}`;
3537
const accountApproverTrigger = (approver: Address) => `account.updated:approver:${approver}`;
@@ -105,7 +107,7 @@ export class AccountsService {
105107
throw new UserInputError('Duplicate policy keys');
106108

107109
const implementation = ACCOUNT_IMPLEMENTATION.address[chain];
108-
const account = asUAddress(
110+
const address = asUAddress(
109111
getProxyAddress({
110112
deployer: DEPLOYER.address[chain],
111113
implementation,
@@ -119,35 +121,51 @@ export class AccountsService {
119121
const id = uuid();
120122
await this.accountsCache.addCachedAccount({
121123
approver: getApprover(),
122-
account: { id, address: account },
124+
account: { id, address },
123125
});
124126

127+
// Replace self address with account address
128+
const selfRefPolicies = policies.map(
129+
(p) =>
130+
({
131+
...p,
132+
actions: p.actions?.map((a) => ({
133+
...a,
134+
functions: a.functions.map((f) => ({
135+
...f,
136+
contract:
137+
f.contract === PLACEHOLDER_ACCOUNT_ADDRESS ? asAddress(address) : f.contract,
138+
})),
139+
})),
140+
}) satisfies PolicyInput,
141+
);
142+
125143
await this.db.transaction(async () => {
126144
await this.db.query(
127145
e.insert(e.Account, {
128146
id,
129-
address: account,
147+
address,
130148
name,
131149
implementation,
132150
salt,
133151
}),
134152
);
135153

136-
for (const policy of policyInputs) {
137-
await this.policies.create({
138-
account,
139-
initState: true,
140-
...policy,
141-
});
142-
}
154+
await this.policies.propose(
155+
{
156+
account: address,
157+
isInitialization: true,
158+
},
159+
...selfRefPolicies,
160+
);
143161
});
144162

145-
this.contracts.addAccountAsVerified(asAddress(account));
146-
this.faucet.requestTokens(account);
147-
this.event({ account, event: AccountEvent.created });
163+
this.contracts.addAccountAsVerified(asAddress(address));
164+
this.faucet.requestTokens(address);
165+
this.event({ account: address, event: AccountEvent.created });
148166
this.setAsPrimaryAccountIfNotConfigured(id);
149167

150-
return { id, address: account };
168+
return { id, address: address };
151169
}
152170

153171
async updateAccount({ account, name, photo }: UpdateAccountInput) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
with account := (select Account filter .address = <UAddress>$account),
2+
keys := array_unpack(<array<uint16>>$policyKeys)
3+
select Policy {
4+
key,
5+
approvers: { address },
6+
threshold,
7+
actions: {
8+
label,
9+
functions: {
10+
contract,
11+
selector,
12+
abi,
13+
},
14+
allow,
15+
description,
16+
},
17+
transfers: {
18+
limits: {
19+
token,
20+
amount,
21+
duration
22+
},
23+
defaultAllow,
24+
budget
25+
},
26+
allowMessages,
27+
delay,
28+
} filter .account = account and .key in keys and
29+
(.isDraft if exists .draft else .isLatest)

0 commit comments

Comments
 (0)